Add FastAnalyzer to the class (split it later)

Fix some bugs
Use FastAnalyzer as Analyzer seems not to be reliable by now (need further tests)
This commit is contained in:
Flamefire committed 2014-03-28 22:13:52 +01:00
1 parent c781f5427f
commit 980644108e
8 files changed
+39 -32

No files matched your search

+8 -7
View File
@@ -10,12 +10,13 @@ AnalyzerExt::~AnalyzerExt(){
PitchTracker::DeInit();
}
int AnalyzerExt::GetNoteFast(float* weights){
int AnalyzerExt::GetNoteFast(double* maxVolume, float* weights){
size_t size = m_fastAnalysisBuf.size();
if(size > m_SampleCt)
m_fastAnalysisBuf.pop(size - m_SampleCt);
m_fastAnalysisBuf.read(m_AnalysisBuf, m_AnalysisBuf + m_SampleCt);
return PitchTracker::GetTone(m_AnalysisBuf, m_SampleCt, weights);
if(!m_fastAnalysisBuf.read(m_AnalysisBuf, m_AnalysisBuf + m_SampleCt))
return -1;
return PitchTracker::GetTone(m_AnalysisBuf, m_SampleCt, maxVolume, weights);
}
void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){
@@ -26,11 +27,11 @@ void PtFast_DeInit(){
PitchTracker::DeInit();
}
int PtFast_GetTone(short* samples, int sampleCt, float* weights){
int PtFast_GetTone(short* samples, int sampleCt, double* maxVolume, float* weights){
if(sampleCt <= 0)
return -1;
double* dataDouble = short2DoubleArray(samples, sampleCt, false);
int result = PitchTracker::GetTone(dataDouble, sampleCt, weights, true);
int result = PitchTracker::GetTone(dataDouble, sampleCt, maxVolume, weights, true);
freeDoubleArray(dataDouble);
return result;
}
@@ -85,10 +86,10 @@ double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq){
return (tone == NULL) ? -1 : ToneToNote(tone);
}
int Analyzer_GetNoteFast(AnalyzerExt* analyzer, float* weights){
int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights){
if(!analyzer)
return -1;
return analyzer->GetNoteFast(weights);
return analyzer->GetNoteFast(maxVolume, weights);
}
bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate){
+2 -2
View File
@@ -12,7 +12,7 @@ public:
m_fastAnalysisBuf.insert(begin, end);
Analyzer::input(begin, end);
}
int GetNoteFast(float* weights);
int GetNoteFast(double* maxVolume, float* weights);
private:
constexpr static size_t m_SampleCt = 4096;
RingBuffer<m_SampleCt * 2> m_fastAnalysisBuf; // Buffer used for fast analysis instead of FFT
@@ -30,7 +30,7 @@ DllExport void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampl
DllExport void Analyzer_InputByte(AnalyzerExt* analyzer, char* data, int sampleCt);
DllExport void Analyzer_Process(AnalyzerExt* analyzer);
DllExport double Analyzer_GetPeak(AnalyzerExt* analyzer);
DllExport int Analyzer_GetNoteFast(AnalyzerExt* analyzer, float* weights);
DllExport int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights);
DllExport double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq);
DllExport bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate);
+1 -1
View File
@@ -137,7 +137,7 @@ void Analyzer::calcTones() {
double phase = std::arg(m_fft[k]);
// process phase difference
double delta = phase - m_fftLastPhase[k];
m_fftLastPhase[k] = phase;
m_fftLastPhase[k] = static_cast<float>(phase);
delta -= k * phaseStep; // subtract expected phase difference
delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval
delta /= phaseStep; // calculate diff from bin center frequency
+1 -1
View File
@@ -52,7 +52,7 @@ public:
/// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer.
template <typename OutIt> bool read(OutIt begin, OutIt end) {
size_t r = m_read;
if (size() <= static_cast<size_t>(end - begin)) return false; // Not enough audio available
if (size() < static_cast<size_t>(end - begin)) return false; // Not enough audio available
while (begin != end) *begin++ = m_buf[r++ % SIZE]; // Copy audio to output iterator
return true;
}
+8 -7
View File
@@ -89,21 +89,22 @@ namespace PitchTracker{
}
template<typename T>
int GetTone(T *samples, int sampleCt, float *weights, bool scale){
int GetTone(T *samples, int sampleCt, double* maxVolume, float *weights, bool scale){
if(!SamplesPerPeriodPerTone)
return -1;
T maxVolume = 0;
T maxVolumeL = 0;
for(int i = 0; i < sampleCt; i++){
T vol = abs(samples[i]);
if(vol > maxVolume)
maxVolume = vol;
if(vol > maxVolumeL)
maxVolumeL = vol;
}
*maxVolume = maxVolumeL;
T maxWeight = -1;
T minWeight = 1;
int maxTone = -1;
for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++)
{
T curWeight = _AnalyzeToneFunc<T>(samples, sampleCt, toneIndex) / maxVolume;
T curWeight = _AnalyzeToneFunc<T>(samples, sampleCt, toneIndex) / maxVolumeL;
if(scale)
curWeight /= 32768.0; //maximum abs value of a short, would actually need to scale by MaxValue^2 but we already scaled by maxVolume
@@ -124,7 +125,7 @@ namespace PitchTracker{
}else return -1;
}
template int GetTone(float *samples, int sampleCt, float *weights, bool scale);
template int GetTone(double *samples, int sampleCt, float *weights, bool scale);
template int GetTone(float *samples, int sampleCt, double* maxVolume, float *weights, bool scale);
template int GetTone(double *samples, int sampleCt, double* maxVolume, float *weights, bool scale);
}
+1 -1
View File
@@ -3,7 +3,7 @@
namespace PitchTracker{
void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone);
void DeInit();
template<typename T> int GetTone(T *samples, int sampleCt, float *weights, bool scale = false);
template<typename T> int GetTone(T *samples, int sampleCt, double* maxVolume, float *weights, bool scale = false);
typedef void (__stdcall * LogCallback)(const char* text);
static LogCallback Log;
+6 -6
View File
@@ -28,7 +28,7 @@ namespace Vocaluxe.Lib.Sound.Record
private static extern double Analyzer_GetPeak(IntPtr analyzer);
[DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double Analyzer_GetNoteFast(IntPtr analyzer, [Out] float[] weights);
private static extern int Analyzer_GetNoteFast(IntPtr analyzer, [Out] out double maxVolume, [Out] float[] weights);
[DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double Analyzer_FindNote(IntPtr analyzer, double minFreq, double maxFreq);
@@ -79,9 +79,9 @@ namespace Vocaluxe.Lib.Sound.Record
return Analyzer_FindNote(_Instance, minFreq, maxFreq);
}
public double GetNoteFast(float[] weights)
public int GetNoteFast(out double maxVolume, float[] weights)
{
return Analyzer_GetNoteFast(_Instance, weights);
return Analyzer_GetNoteFast(_Instance, out maxVolume, weights);
}
public bool Output(float[] data, float rate)
@@ -114,12 +114,12 @@ namespace Vocaluxe.Lib.Sound.Record
public static extern void DeInit();
[DllImport("PitchTracker.dll", EntryPoint = "PtFast_GetTone", CallingConvention = CallingConvention.Cdecl)]
private static extern int PtFast_GetTone([In] short[] samples, int sampleCt, [Out] float[] weights);
private static extern int PtFast_GetTone([In] short[] samples, int sampleCt, [Out] out double maxVolume, [Out] float[] weights);
#endregion
public static int GetTone(short[] samples, float[] weights)
public static int GetTone(short[] samples, out double maxVolume, float[] weights)
{
return PtFast_GetTone(samples, samples.Length, weights);
return PtFast_GetTone(samples, samples.Length, out maxVolume, weights);
}
}
}
+12 -7
View File
@@ -96,10 +96,10 @@ namespace Vocaluxe.Lib.Sound.Record
public void AnalyzeBuffer()
{
_Analyzer.Process();
_MaxVolume = _Analyzer.GetPeak() / 43 + 1;
int tone = (int)Math.Round(_Analyzer.FindNote());
if (tone >= 0)
//_Analyzer.Process();
//_MaxVolume = _Analyzer.GetPeak() / 43 + 1;
int tone = _Analyzer.GetNoteFast(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); //
if (tone >= 0 && _MaxVolume >= MinVolume)
{
ToneAbs = tone;
Tone = ToneAbs % 12;
@@ -146,6 +146,7 @@ namespace Vocaluxe.Lib.Sound.Record
const int toneTo = 47; //B5
Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo));
byte[] data;
byte[] data2 = new byte[2048];
int ok = 0;
double angle = 0;
for (int distort = 0; distort < 10; distort++)
@@ -155,8 +156,12 @@ namespace Vocaluxe.Lib.Sound.Record
_GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, ref angle, out data);
_Distort(data, tone, distort);
ProcessNewBuffer(data);
AnalyzeBuffer();
for (int i = 0; i < 4; i++)
{
Buffer.BlockCopy(data, i * 2048, data2, 0, 2048);
ProcessNewBuffer(data2);
AnalyzeBuffer();
}
if (!ToneValid)
CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected (Distortion: " + distort + ")");
else if (Tone != tone % 12)
@@ -168,7 +173,7 @@ namespace Vocaluxe.Lib.Sound.Record
_GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data);
Stopwatch sw = new Stopwatch();
sw.Start();
const int repeats = 1000;
const int repeats = 100;
for (int i = 0; i < repeats; i++)
{
ProcessNewBuffer(data);