Add an Interface for Pitchtrackers and set VolTresholds
This commit is contained in:
1 parent
5f79406cf2
commit
d04cbe7ceb
16 files changed
+344
-173
No files matched your search
@@ -39,17 +39,17 @@ void Analyzer_Process(Analyzer* analyzer){
|
||||
analyzer->process();
|
||||
}
|
||||
|
||||
double Analyzer_GetPeak(Analyzer* analyzer){
|
||||
float Analyzer_GetPeak(Analyzer* analyzer){
|
||||
if(!analyzer)
|
||||
return -999;
|
||||
return analyzer->getPeak();
|
||||
return static_cast<float>(analyzer->getPeakRaw());
|
||||
}
|
||||
|
||||
double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq){
|
||||
if(!analyzer)
|
||||
return -1;
|
||||
const Tone* tone = analyzer->findTone(minFreq, maxFreq);
|
||||
return (tone == NULL) ? -1 : FreqToNote(tone->freq);
|
||||
return (tone == NULL) ? -1 : FreqToNote(tone->freq);
|
||||
}
|
||||
|
||||
bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate){
|
||||
@@ -71,6 +71,18 @@ int PtAKF_GetNumHalfTones(){
|
||||
return PtAKF::GetNumHalfTones();
|
||||
}
|
||||
|
||||
void PtAKF_SetVolumeTreshold(PtAKF* analyzer, float threshold){
|
||||
if(!analyzer)
|
||||
return;
|
||||
analyzer->SetVolumeThreshold(threshold);
|
||||
}
|
||||
|
||||
float PtAKF_GetVolumeThreshold(PtAKF* analyzer){
|
||||
if(!analyzer)
|
||||
return 0.f;
|
||||
return analyzer->GetVolumeThreshold();
|
||||
}
|
||||
|
||||
void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){
|
||||
if(sampleCt <= 0 || !analyzer)
|
||||
return;
|
||||
@@ -82,7 +94,7 @@ void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){
|
||||
//analyzer->input(dataShort, dataShort + sampleCt);
|
||||
}
|
||||
|
||||
int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights){
|
||||
int PtAKF_GetNote(PtAKF* analyzer, float* maxVolume, float* weights){
|
||||
if(!analyzer)
|
||||
return -1;
|
||||
return analyzer->GetNote(maxVolume, weights);
|
||||
@@ -97,6 +109,18 @@ void PtDyWa_Free(PtDyWa* analyzer){
|
||||
delete analyzer;
|
||||
}
|
||||
|
||||
void PtDyWa_SetVolumeTreshold(PtDyWa* analyzer, float threshold){
|
||||
if(!analyzer)
|
||||
return;
|
||||
analyzer->SetVolumeThreshold(threshold);
|
||||
}
|
||||
|
||||
float PtDyWa_GetVolumeThreshold(PtDyWa* analyzer){
|
||||
if(!analyzer)
|
||||
return 0.f;
|
||||
return analyzer->GetVolumeThreshold();
|
||||
}
|
||||
|
||||
void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt){
|
||||
if(sampleCt <= 0 || !analyzer)
|
||||
return;
|
||||
@@ -105,16 +129,10 @@ void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt){
|
||||
freeFloatArray(dataFloat);
|
||||
}
|
||||
|
||||
void PtDyWa_Process(PtDyWa* analyzer){
|
||||
if(!analyzer)
|
||||
return;
|
||||
analyzer->Process();
|
||||
}
|
||||
|
||||
double PtDyWa_GetNote(PtDyWa* analyzer){
|
||||
double PtDyWa_FindNote(PtDyWa* analyzer, float* maxVolume){
|
||||
if(!analyzer)
|
||||
return -1;
|
||||
return analyzer->GetNote();
|
||||
return analyzer->FindNote(maxVolume);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -12,21 +12,24 @@ DllExport void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt
|
||||
DllExport void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt);
|
||||
DllExport void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt);
|
||||
DllExport void Analyzer_Process(Analyzer* analyzer);
|
||||
DllExport double Analyzer_GetPeak(Analyzer* analyzer);
|
||||
DllExport float Analyzer_GetPeak(Analyzer* analyzer);
|
||||
DllExport double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq);
|
||||
DllExport bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate);
|
||||
|
||||
DllExport PtAKF* PtAKF_Create(unsigned step);
|
||||
DllExport void PtAKF_Free(PtAKF* analyzer);
|
||||
DllExport int PtAKF_GetNumHalfTones();
|
||||
DllExport void PtAKF_SetVolumeThreshold(PtAKF* analyzer, float threshold);
|
||||
DllExport float PtAKF_GetVolumeThreshold(PtAKF* analyzer);
|
||||
DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt);
|
||||
DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights);
|
||||
DllExport int PtAKF_GetNote(PtAKF* analyzer, float* maxVolume, float* weights);
|
||||
|
||||
DllExport PtDyWa* PtDyWa_Create(unsigned step);
|
||||
DllExport void PtDyWa_Free(PtDyWa* analyzer);
|
||||
DllExport void PtDyWa_SetVolumeTreshold(PtDyWa* analyzer,float threshold);
|
||||
DllExport float PtDyWa_GetVolumeThreshold(PtDyWa* analyzer);
|
||||
DllExport void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt);
|
||||
DllExport void PtDyWa_Process(PtDyWa* analyzer);
|
||||
DllExport double PtDyWa_GetNote(PtDyWa* analyzer);
|
||||
DllExport double PtDyWa_FindNote(PtDyWa* analyzer);
|
||||
|
||||
/*
|
||||
public ref class CTone {
|
||||
|
||||
@@ -102,7 +102,7 @@ typedef struct _minmax {
|
||||
struct _minmax *next;
|
||||
} minmax;
|
||||
|
||||
double _dywapitch_computeWaveletPitch(double * samples, int startsample, int samplecount) {
|
||||
double _dywapitch_computeWaveletPitch(double * samples, int startsample, int samplecount, float* maxVolume, double volThreshold) {
|
||||
double pitchF = 0.0;
|
||||
|
||||
int i, j;
|
||||
@@ -143,6 +143,9 @@ double _dywapitch_computeWaveletPitch(double * samples, int startsample, int sam
|
||||
maxValue = maxValue - theDC;
|
||||
minValue = minValue - theDC;
|
||||
double amplitudeMax = (maxValue > -minValue ? maxValue : -minValue);
|
||||
*maxVolume = static_cast<float>(amplitudeMax + theDC);
|
||||
if(*maxVolume < volThreshold)
|
||||
return 0.0;
|
||||
|
||||
ampltitudeThreshold = amplitudeMax*maximaThresholdRatio;
|
||||
//asLog("dywapitch theDC=%f ampltitudeThreshold=%f\n", theDC, ampltitudeThreshold);
|
||||
@@ -439,8 +442,8 @@ void dywapitch_inittracking(dywapitchtracker *pitchtracker) {
|
||||
pitchtracker->_pitchConfidence = -1;
|
||||
}
|
||||
|
||||
double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount) {
|
||||
double raw_pitch = _dywapitch_computeWaveletPitch(samples, startsample, samplecount);
|
||||
double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount, float* maxVolume, double volThreshold) {
|
||||
double raw_pitch = _dywapitch_computeWaveletPitch(samples, startsample, samplecount, maxVolume, volThreshold);
|
||||
return _dywapitch_dynamicprocess(pitchtracker, raw_pitch);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ void dywapitch_inittracking(dywapitchtracker *pitchtracker);
|
||||
// startsample : the index of the first sample to use in the sample buffer
|
||||
// samplecount : the number of samples to use to compte the pitch
|
||||
// return 0.0 if no pitch was found (sound too low, noise, etc..)
|
||||
double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount);
|
||||
double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount, float* maxVolume, double volThreshold);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -5,23 +5,27 @@
|
||||
PtDyWa::PtDyWa(unsigned step){
|
||||
_Step = step;
|
||||
dywapitch_inittracking(&_State);
|
||||
_VolTreshold = 0.01f;
|
||||
_LastMaxVol = 0.f;
|
||||
}
|
||||
|
||||
void PtDyWa::Process(){
|
||||
void PtDyWa::SetVolumeThreshold(float threshold){
|
||||
_VolTreshold = threshold;
|
||||
}
|
||||
|
||||
double PtDyWa::FindNote(float* maxVolume){
|
||||
double AnaylsisBuf[_SampleCt];
|
||||
size_t size = _AnalysisBuf.size();
|
||||
if(size > _SampleCt)
|
||||
_AnalysisBuf.pop(size - _SampleCt);
|
||||
if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt))
|
||||
return;
|
||||
if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)){
|
||||
*maxVolume = _LastMaxVol * 0.85f;
|
||||
return -1;
|
||||
}
|
||||
_AnalysisBuf.pop(_Step);
|
||||
double pitch = dywapitch_computepitch(&_State, AnaylsisBuf,0,_SampleCt);
|
||||
double pitch = dywapitch_computepitch(&_State, AnaylsisBuf, 0, _SampleCt, maxVolume, _VolTreshold);
|
||||
if(pitch == 0.0)
|
||||
_LastNote = -1;
|
||||
return -1;
|
||||
else
|
||||
_LastNote = FreqToNote(pitch);
|
||||
}
|
||||
|
||||
double PtDyWa::GetNote(){
|
||||
return _LastNote;
|
||||
return FreqToNote(pitch);
|
||||
}
|
||||
@@ -11,12 +11,14 @@ public:
|
||||
_AnalysisBuf.insert(begin, end);
|
||||
}
|
||||
|
||||
void Process();
|
||||
double GetNote();
|
||||
double FindNote(float* maxVolume);
|
||||
void SetVolumeThreshold(float threshold);
|
||||
float GetVolumeThreshold(){return _VolTreshold;}
|
||||
private:
|
||||
dywapitchtracker _State;
|
||||
constexpr static size_t _SampleCt = 2048;
|
||||
RingBuffer<_SampleCt * 2> _AnalysisBuf;
|
||||
unsigned _Step;
|
||||
double _LastNote;
|
||||
float _VolTreshold;
|
||||
float _LastMaxVol;
|
||||
};
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
fft_t const& getFFT() const { return m_fft; }
|
||||
/** Get the peak level in dB (negative value, 0.0 = clipping). **/
|
||||
double getPeak() const { return 10.0 * log10(m_peak); }
|
||||
double getPeakRaw() const { return m_peak; }
|
||||
/** Get a list of all tones detected. **/
|
||||
tones_t const& getTones() const { return m_tones; }
|
||||
/** Find a tone within the singing range; prefers strong tones around 200-400 Hz. **/
|
||||
|
||||
+15
-4
@@ -47,6 +47,8 @@ PtAKF::PtAKF(unsigned step){
|
||||
}
|
||||
}
|
||||
_Step = step;
|
||||
_VolTreshold = 0.01f;
|
||||
_LastMaxVol = 0.f;
|
||||
}
|
||||
|
||||
PtAKF::~PtAKF(){
|
||||
@@ -59,13 +61,19 @@ PtAKF::~PtAKF(){
|
||||
}
|
||||
}
|
||||
|
||||
int PtAKF::GetNote(double* restrict maxVolume, float* restrict weights){
|
||||
void PtAKF::SetVolumeThreshold(float threshold){
|
||||
_VolTreshold = threshold;
|
||||
}
|
||||
|
||||
int PtAKF::GetNote(float* restrict maxVolume, float* restrict weights){
|
||||
float AnaylsisBuf[_SampleCt];
|
||||
size_t size = _AnalysisBuf.size();
|
||||
if(size > _SampleCt)
|
||||
_AnalysisBuf.pop(size - _SampleCt);
|
||||
if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt))
|
||||
if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)){
|
||||
*maxVolume = _LastMaxVol * 0.85f;
|
||||
return -1;
|
||||
}
|
||||
_AnalysisBuf.pop(_Step);
|
||||
return _GetNote(AnaylsisBuf, maxVolume, weights);
|
||||
}
|
||||
@@ -96,7 +104,7 @@ void PtAKF::AddPeak(SPeak peaks[], float curWeight, int toneIndex){
|
||||
}
|
||||
}
|
||||
|
||||
int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights){
|
||||
int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* restrict weights){
|
||||
// Calculate maximum volume
|
||||
|
||||
float maxVolumeL = 0;
|
||||
@@ -105,9 +113,12 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float*
|
||||
if(vol > maxVolumeL)
|
||||
maxVolumeL = vol;
|
||||
}
|
||||
//maxVolumeL /= 32767.;
|
||||
//maxVolumeL /= 32767.f;
|
||||
*maxVolume = maxVolumeL;
|
||||
|
||||
if(maxVolumeL < _VolTreshold)
|
||||
return -1;
|
||||
|
||||
float samplesWindowed[_SampleCt];
|
||||
|
||||
for(int i = 0; i < _SampleCt; i++){
|
||||
|
||||
@@ -29,7 +29,9 @@ public:
|
||||
_AnalysisBuf.insert(begin, end);
|
||||
}
|
||||
|
||||
int GetNote(double* restrict maxVolume, float* restrict weights);
|
||||
int GetNote(float* restrict maxVolume, float* restrict weights);
|
||||
void SetVolumeThreshold(float threshold);
|
||||
float GetVolumeThreshold(){return _VolTreshold;}
|
||||
static int GetNumHalfTones(){ return _MaxHalfTone - _MinHalfTone + 1;}
|
||||
|
||||
private:
|
||||
@@ -48,8 +50,11 @@ private:
|
||||
constexpr static size_t _SampleCt = 2048;
|
||||
RingBuffer<_SampleCt * 2> _AnalysisBuf;
|
||||
unsigned _Step;
|
||||
float _VolTreshold;
|
||||
float _LastMaxVol;
|
||||
|
||||
int _GetNote(float* restrict samples, float* restrict maxVolume, float* restrict weights);
|
||||
|
||||
static int _GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights);
|
||||
static float _AnalyzeBySampleCt(float* restrict samples, float* restrict samplesWindowed, float samplesPerPeriodD);
|
||||
static inline float _AnalyzeByTone(float* restrict samples, float* restrict samplesWindowed, int toneIndex);
|
||||
static float _AKFBySampleCt(float* restrict samples, float samplesPerPeriodD);
|
||||
|
||||
Reference in new issue
Block a user