Player: fix low notes and smooth note change

This commit is contained in:
Louis-Joseph Fournier 2016-01-13 11:41:06 +01:00
parent 91403124b2
commit 8926bbf8ea
5 changed files with 38 additions and 6 deletions

View file

@ -273,6 +273,7 @@ void TunerWorker::Entry()
); );
// update frequency to update from previous tuner results // update frequency to update from previous tuner results
player->Reset();
player->SetFreq(pitchDetection->GetNoteFreq(result.note, result.octave)); player->SetFreq(pitchDetection->GetNoteFreq(result.note, result.octave));
} }

View file

@ -17,6 +17,7 @@
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
//#include <iostream>
#include "FreqPlayer.hpp" #include "FreqPlayer.hpp"
@ -27,16 +28,28 @@ template<typename sample_t> FreqPlayer<sample_t>::FreqPlayer(int _rate):
n_frame(0), n_frame(0),
waveform(W_SINUS) waveform(W_SINUS)
{ {
k = K();
k_update = -1; // invalid: don't update
} }
template<typename sample_t> void FreqPlayer<sample_t>::Reset() template<typename sample_t> void FreqPlayer<sample_t>::Reset()
{ {
n_frame = 0; n_frame = 0;
if (k_update != -1) {
k = k_update;
k_update = -1;
}
}
template<typename sample_t> double FreqPlayer<sample_t>::K() const
{
return freq / rate * M_PI * 2;
} }
template<typename sample_t> void FreqPlayer<sample_t>::SetFreq(double freq) template<typename sample_t> void FreqPlayer<sample_t>::SetFreq(double freq)
{ {
this->freq = freq; this->freq = freq;
k_update = K();
} }
template<typename sample_t> void FreqPlayer<sample_t>::SetVolume(double volume) template<typename sample_t> void FreqPlayer<sample_t>::SetVolume(double volume)
@ -49,7 +62,21 @@ template<> double FreqPlayer<double>::max() { return 1; }
template<typename sample_t> double FreqPlayer<sample_t>::radius() template<typename sample_t> double FreqPlayer<sample_t>::radius()
{ {
return (double) (n_frame++) * freq / rate * M_PI * 2; double ret = (n_frame++) * k;
/* to update frequency factor, wait current radius to go to beginning
* in interval [0, 2PI]
*/
if (k_update != -1) {
double a = fmod(ret, M_PI * 1);
double b = fmod(n_frame * k, M_PI * 2);
if (b < a) { // next frame go back to beginning of circle
n_frame = 0;
k = k_update;
k_update = -1;
}
}
return ret;
} }
template<typename sample_t> sample_t FreqPlayer<sample_t>::AudioFrame() template<typename sample_t> sample_t FreqPlayer<sample_t>::AudioFrame()

View file

@ -40,7 +40,11 @@ template<typename sample_t> class FreqPlayer {
int n_frame; int n_frame;
/// wave form /// wave form
WAVEFORM waveform; WAVEFORM waveform;
/// pre computed factor
double k, k_update;
/// return k computed
double K() const;
/// return the max sample_t /// return the max sample_t
sample_t max(); sample_t max();
/// return the current radius /// return the current radius

View file

@ -120,7 +120,7 @@ void Scale::ConstructEqualTemperament()
updateScale(); updateScale();
} }
double Scale::GetLa() double Scale::GetLa() const
{ {
return actualLa; return actualLa;
} }
@ -140,12 +140,12 @@ void Scale::SetLa(double la)
if (freq_setted) updateScale(); if (freq_setted) updateScale();
} }
double Scale::GetNoteFreq(int note, int octave) double Scale::GetNoteFreq(int note, int octave) const
{ {
assert(note >= 0 && note < nbNote); assert(note >= 0 && note < nbNote);
double f = actualNoteFreq[note]; double f = actualNoteFreq[note];
octave -= 4; octave -= 4;
if (octave < 0) f /= 1 << octave; if (octave < 0) f /= 1 << (-octave);
else if (octave > 0) f *= 1 << octave; else if (octave > 0) f *= 1 << octave;
return f; return f;

View file

@ -57,13 +57,13 @@ class Scale {
void SetNotesFrequencies(const double freq[nbNote]); void SetNotesFrequencies(const double freq[nbNote]);
/// Get ref freq for la4 /// Get ref freq for la4
double GetLa(); double GetLa() const;
/// Set ref freq for la4 /// Set ref freq for la4
void SetLa(double la); void SetLa(double la);
/// get note frequency /// get note frequency
double GetNoteFreq(int note, int octave); double GetNoteFreq(int note, int octave) const;
/** /**
* Find nearest note, octave, and deviation * Find nearest note, octave, and deviation