Add an Interface for Pitchtrackers and set VolTresholds

This commit is contained in:
Flamefire committed 2014-04-16 21:05:57 +02:00
1 parent 5f79406cf2
commit d04cbe7ceb
16 files changed
+344 -173

No files matched your search

+30 -12
View File
@@ -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);
}
/*
+7 -4
View File
@@ -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);
}
+1 -1
View File
@@ -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"
+14 -10
View File
@@ -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);
}
+5 -3
View File
@@ -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;
};
+1
View File
@@ -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
View File
@@ -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++){
+7 -2
View File
@@ -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);