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:
1 parent
c781f5427f
commit
980644108e
8 files changed
+39
-32
No files matched your search
@@ -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){
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user