diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 6314b64c..612882c0 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -71,7 +71,7 @@ int PtAKF_GetNumHalfTones(){ return PtAKF::GetNumHalfTones(); } -void PtAKF_SetVolumeTreshold(PtAKF* analyzer, float threshold){ +void PtAKF_SetVolumeThreshold(PtAKF* analyzer, float threshold){ if(!analyzer) return; analyzer->SetVolumeThreshold(threshold); diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 6425f862..11b32b84 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -29,7 +29,7 @@ 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 double PtDyWa_FindNote(PtDyWa* analyzer); +DllExport double PtDyWa_FindNote(PtDyWa* analyzer, float* maxVolume); /* public ref class CTone { diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 9a4a7b4d..43950e7d 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -18,28 +18,12 @@ #define TEST_PITCH using System; -#if TEST_PITCH -using System.Collections.Generic; -using System.IO; -using System.Windows.Forms; -using System.Diagnostics; -using Pitch; -using Vocaluxe.Lib.Sound.Record.Pitch; using Vocaluxe.Lib.Sound.Record.PitchTracker; -using VocaluxeLib; -using VocaluxeLib.Utils; - -#endif namespace Vocaluxe.Lib.Sound.Record { class CBuffer : IDisposable { -#if TEST_PITCH - //Half tones: C C# D D# E F F# G G# A A# B - private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) - private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) -#endif private CPitchTracker _PitchTracker = new CPtAKF(); private float _MaxVolume; @@ -50,8 +34,12 @@ namespace Vocaluxe.Lib.Sound.Record ToneWeigths = new float[GetNumHalfTones()]; Reset(); #if TEST_PITCH - _TestPitchDetection(); - Reset(); + CPitchTrackerTest tester = new CPitchTrackerTest(); + tester.AddAnalyzer(new CAnalyzer()); + tester.AddAnalyzer(new CPtAKF()); + tester.AddAnalyzer(new CPtDyWa()); + tester.AddAnalyzer(new CPtSharp()); + tester.RunTest(); #endif } @@ -109,8 +97,7 @@ namespace Vocaluxe.Lib.Sound.Record public void AnalyzeBuffer() { - //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; - int tone = _PitchTracker.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // + int tone = _PitchTracker.GetNote(out _MaxVolume, ToneWeigths); if (tone >= 0) { ToneAbs = tone; @@ -135,316 +122,5 @@ namespace Vocaluxe.Lib.Sound.Record _PitchTracker = null; } } - -#if TEST_PITCH - private static bool _PitchTestRun; - - private static string _ToneToNote(int tone, bool withOctave = true) - { - if (tone < 0) - return "inv."; - tone += 24; - string[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; - string result = notes[tone % 12]; - if (withOctave) - result += (tone / 12); - return result; - } - - private void _TestPitchDetection() - { - if (_PitchTestRun) - return; - _PitchTestRun = true; - const int toneFrom = 0; - const int toneTo = -1; // 47; //B5 - Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); - byte[] data; - byte[] data2 = new byte[2048]; - int ok = 0; - int tests = 0; - double angle = 0; - for (int distort = 0; distort < 10; distort++) - { - for (int tone = toneFrom; tone <= toneTo; tone++) - { - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, ref angle, out data); - _Distort(data, tone, distort); - - 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) - { - CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " wrongly detected as " + _ToneToNote(Tone, false) + " (Distortion: " + distort + ")"); - CWavFile file = new CWavFile(); - file.Create(tone + "-" + distort + ".wav", 1, 44100, 16); - file.Write16BitSamples(data, 1); - file.Close(); - } - else - ok++; - tests++; - } - } - /*if (_TestFile("toneG3.wav", 19)) - ok++; - tests++; - if (_TestFile("toneG3Miss.wav", 19)) - ok++; - tests++; - if (_TestFile("toneG4.wav", 31)) - ok++; - tests++;*/ - _TestFile("whistling3.wav", "whistling3.txt", ref tests, ref ok); - _TestFile("sClausVoc.wav", "sClausVoc.txt", ref tests, ref ok); - - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); - Stopwatch sw = new Stopwatch(); - sw.Start(); - const int repeats = 100; - for (int i = 0; i < repeats; i++) - { - ProcessNewBuffer(data); - AnalyzeBuffer(); - } - sw.Stop(); - string msg = "Analyser: Errors: " + (tests - ok) + "/" + tests + "; Speed: " + - (int)(repeats / (sw.ElapsedMilliseconds / 1000.0)) + " buffers/s"; - Console.WriteLine(msg); - MessageBox.Show(msg); - Reset(); - } - - private struct STimedNote - { - public int Time, Note; - } - - private void _TestFile(string fileName, string testFileName, ref int ct, ref int ok) - { - if (!File.Exists(testFileName)) - { - ok = ct = 0; - return; - } - List tones = new List(); - using (StreamReader reader = new StreamReader(testFileName)) - { - String line; - while ((line = reader.ReadLine()) != null) - { - int p = line.IndexOf(' '); - if (p < 0) - continue; - STimedNote note; - note.Time = int.Parse(line.Substring(0, p)); - note.Note = int.Parse(line.Substring(p + 1)); - tones.Add(note); - } - } - _TestFile(fileName, tones, ref ct, ref ok); - } - - private bool _TestFile(string fileName, int tone) - { - STimedNote note; - note.Note = tone; - note.Time = 46; - List tones = new List {note}; - int ct = 0; - int ok = 0; - _TestFile(fileName, tones, ref ct, ref ok); - return ok >= ct - 4; - } - - private bool _IsNoteValid(int note, int time, IList tones) - { - const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples - for (int i = 0; i < tones.Count; i++) - { - if (tones[i].Time > time) - break; - if (i + 1 == tones.Count || time <= tones[i + 1].Time + lastNoteMaxTimeDiff) - { - if (tones[i].Note == note) - return true; - } - } - return false; - } - - private void _TestFile(string fileName, IList tones, ref int ct, ref int ok) - { - CWavFile wavFile = new CWavFile(); - try - { - if (!wavFile.Open(fileName)) - return; - if (wavFile.BitsPerSample != 16) - { - wavFile.Close(); - return; - } - int samplesRead = 0; - int curTimeIndex = -1; - int curNote = -1; - const int maxSamplesPerBatch = 512; - CPitchTracker analyzer2 = new CAnalyzer(); - CPitchTracker analyzer3 = new CPtDyWa(); - CPitchTracker analyzer4 = new CPtSharp(); - int[] detectedTones = new int[4]; - int[] oks = new int[4]; - float dummyMaxVol; - float[] dummyWeights = new float[ToneWeigths.Length]; - int lCt = 0; - while (wavFile.NumSamplesLeft > maxSamplesPerBatch) - { - byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); - samplesRead += samples.Length / 2; - int time = samplesRead * 1000 / wavFile.SampleRate; - ProcessNewBuffer(samples); - AnalyzeBuffer(); - analyzer2.Input(samples); - analyzer3.Input(samples); - analyzer4.Input(samples); - while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) - { - curTimeIndex++; - curNote = tones[curTimeIndex].Note; - } - if (curNote < 0) - continue; - detectedTones[0] = ToneValid ? ToneAbs : -1; - detectedTones[1] = analyzer2.GetNote(out dummyMaxVol, dummyWeights); - detectedTones[2] = analyzer3.GetNote(out dummyMaxVol, dummyWeights); - detectedTones[3] = analyzer4.GetNote(out dummyMaxVol, dummyWeights); - lCt++; - /*if (!ToneValid) - CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms not detected"); - else if (ToneAbs % 12 != curNote % 12) - CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(ToneAbs)); - else - ok++;*/ - bool[] valids = new bool[4]; - bool error = false; - for (int i = 0; i < 4; i++) - { - valids[i] = _IsNoteValid(detectedTones[i], time, tones); - if (valids[i]) - oks[i]++; - else - error = true; - } - if (error) - { - string msg = "Note " + _ToneToNote(curNote) + " at " + time + "ms detected as "; - for (int i = 0; i < 4; i++) - msg += _ToneToNote(detectedTones[i]) + (valids[i] ? "" : "(!)") + "; "; - CBase.Log.LogDebug(msg); - } - } - string msg2 = "Detected "; - for (int i = 0; i < 4; i++) - msg2 += oks[i] + "|" + (lCt - oks[i]) + " "; - CBase.Log.LogDebug(msg2); - } - catch (Exception e) - { - Console.WriteLine("Error on file " + fileName + ": " + e); - } - wavFile.Close(); - } - - private static short[] _GetDistort(int len, int tone, int type) - { - short[] sdata = new short[len]; - if (type < 9) - { - int newTone = 1; - switch (type) - { - case 0: - newTone = 2; - break; - case 1: - newTone = 3; - break; - case 2: - newTone = 6; - break; - case 3: - newTone = 8; - break; - case 4: - newTone = 10; - break; - case 5: - newTone = 15; - break; - case 6: - newTone = 25; - break; - case 7: - newTone = 26; - break; - case 8: - newTone = 29; - break; - } - byte[] data2; - double angle = 0; - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, ref angle, out data2); - Buffer.BlockCopy(data2, 0, sdata, 0, len * 2); - } - else - { - Random r = new Random(0xBEEF); - for (int i = 0; i < sdata.Length; i++) - sdata[i] = (short)(r.Next() - Int16.MinValue); - } - return sdata; - } - - private static void _Distort(byte[] data, int tone, int distortCt) - { - if (distortCt < 1) - return; - short[] sdata = new short[data.Length / 2]; - Buffer.BlockCopy(data, 0, sdata, 0, data.Length); - - short[][] distortions = new short[distortCt][]; - for (int i = 0; i < distortCt; i++) - distortions[i] = _GetDistort(data.Length / 2, tone, i); - - for (int i = 0; i < sdata.Length; i++) - { - double distortion = 0; - for (int j = 0; j < distortCt; j++) - distortion += distortions[j][i]; - distortion /= distortCt; - sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + distortion / 5.0); - } - Buffer.BlockCopy(sdata, 0, data, 0, data.Length); - } - - private static void _GetSineWave(double freq, int sampleRate, ref double angle, out byte[] data) - { - const short max = short.MaxValue; - const int len = 4096; //sampleRate * durationMs / 1000; - short[] data16Bit = new short[len]; - for (int i = 0; i < len; i++) - data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq + angle) * max); - angle = 2 * Math.PI * len / sampleRate * freq + angle; - angle = angle % (2 * Math.PI); - data = new byte[data16Bit.Length * 2]; - Buffer.BlockCopy(data16Bit, 0, data, 0, data.Length); - } -#endif } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs new file mode 100644 index 00000000..00670ad1 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs @@ -0,0 +1,388 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using VocaluxeLib; +using VocaluxeLib.Utils; + +namespace Vocaluxe.Lib.Sound.Record.PitchTracker +{ + class CPitchTrackerTest + { + //Half tones: C C# D D# E F F# G G# A A# B + private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) + private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) + + private readonly List _Analyzers = new List(); + private int[] _Tones; + private float[][] _Weights; + private float _MaxVolume; + private int _CurTestCount; + private int[] _CurPassedCount; + private int _TestCount; + private int[] _PassedCount; + private int[] _SamplesPerSec; + + private static bool _IsRun; + + public void AddAnalyzer(CPitchTracker analyzer) + { + _Analyzers.Add(analyzer); + } + + #region Init + private void _InitTests() + { + _Tones = new int[_Analyzers.Count]; + _TestCount = 0; + _PassedCount = new int[_Analyzers.Count]; + _CurTestCount = 0; + _CurPassedCount = new int[_Analyzers.Count]; + _Weights = new float[_Analyzers.Count][]; + for (int i = 0; i < _Analyzers.Count; i++) + _Weights[i] = new float[_Analyzers[i].GetNumHalfTones()]; + _SamplesPerSec = new int[_Analyzers.Count]; + } + + private void _InitNext(string lastTest) + { + string msg = "Errors " + lastTest + ": "; + for (int i = 0; i < _CurPassedCount.Length; i++) + { + msg += _CurTestCount - _CurPassedCount[i] + " "; + _PassedCount[i] += _CurPassedCount[i]; + _CurPassedCount[i] = 0; + } + msg += "of " + _CurTestCount; + CBase.Log.LogDebug(msg); + _TestCount += _CurTestCount; + _CurTestCount = 0; + } + #endregion + + public void RunTest(bool reRun = false) + { + if (_IsRun && !reRun) + return; + _IsRun = true; + + _InitTests(); + + _TestSines(); + _InitNext("Sines"); + + _TestFile("toneG3.wav", 19); + _InitNext("Real G3"); + + _TestFile("toneG3Miss.wav", 19); + _InitNext("Real G3 with miss. fundamental"); + + _TestFile("toneG4.wav", 31); + _InitNext("Real G4"); + + _TestFile("whistling3.wav", "whistling3.txt"); + _InitNext("High whistling"); + + _TestFile("sClausVoc.wav", "sClausVoc.txt"); + _InitNext("Real song"); + + _TestSpeed(); + CBase.Log.LogDebug("Finished: "); + for (int i = 0; i < _Analyzers.Count; i++) + { + string msg = _Analyzers[i].GetType().Name + ":"; + msg += " Errors=" + (_TestCount - _PassedCount[i]); + msg += " Passed=" + _PassedCount[i]; + msg += " Total=" + _TestCount; + msg += " Speed=" + _SamplesPerSec[i] + "samples/s (=" + (_SamplesPerSec[i] / 44100) + "rec.s/s)"; + CBase.Log.LogDebug(msg); + } + } + + private void _TestSpeed() + { + const int samplesPerBuffer = 512; + byte[] data; + byte[] data2 = new byte[samplesPerBuffer * 2]; + double angle = 0; + const int repeats = 100; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, samplesPerBuffer * repeats, ref angle, out data); + for (int i = 0; i < _Analyzers.Count; i++) + { + CPitchTracker analyzer = _Analyzers[i]; + Stopwatch sw = new Stopwatch(); + sw.Start(); + for (int j = 0; j < repeats; j++) + { + Buffer.BlockCopy(data, 0, data2, 0, samplesPerBuffer * 2); + analyzer.Input(data2); + analyzer.GetNote(out _MaxVolume, _Weights[j]); + } + sw.Stop(); + _SamplesPerSec[i] = (int)Math.Round(samplesPerBuffer * repeats / (sw.ElapsedMilliseconds / 1000.0)); + } + } + + private void _Process(byte[] data) + { + for (int j = 0; j < _Analyzers.Count; j++) + { + _Analyzers[j].Input(data); + _Tones[j] = _Analyzers[j].GetNote(out _MaxVolume, _Weights[j]); + } + } + + private static string _ToneToNote(int tone, bool withOctave = true) + { + if (tone < 0) + return "inv."; + tone += 24; + string[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; + string result = notes[tone % 12]; + if (withOctave) + result += (tone / 12); + return result; + } + + #region Sines + private void _TestSines() + { + const int toneFrom = 0; + const int toneTo = 47; //B5 + const int sampleCt = 4096; + const int batchCt = 512; + byte[] data2 = new byte[batchCt * 2]; + Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); + double angle = 0; + bool[] valids = new bool[_Analyzers.Count]; + for (int distort = 0; distort < 10; distort++) + { + for (int tone = toneFrom; tone <= toneTo; tone++) + { + byte[] data; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, sampleCt, ref angle, out data); + _Distort(data, tone, distort); + + for (int i = 0; i < sampleCt / batchCt; i++) + { + Buffer.BlockCopy(data, i * batchCt * 2, data2, 0, batchCt * 2); + _Process(data2); + if (i * batchCt < 2048) + continue; + _CurTestCount++; + bool ok = true; + for (int j = 0; j < valids.Length; j++) + { + valids[j] = _Tones[j] == tone; + if (!valids[j]) + ok = false; + else + _CurPassedCount[j]++; + } + if (ok) + continue; + string msg = "Note " + _ToneToNote(tone) + " detected as "; + for (int j = 0; j < valids.Length; j++) + msg += _ToneToNote(_Tones[j]) + (valids[j] ? "" : "(!)") + "; "; + CBase.Log.LogDebug(msg); + } + } + } + } + + private static short[] _GetDistort(int sampleCt, int tone, int type) + { + short[] sdata = new short[sampleCt]; + if (type < 9) + { + int newTone = 1; + switch (type) + { + case 0: + newTone = 2; + break; + case 1: + newTone = 3; + break; + case 2: + newTone = 6; + break; + case 3: + newTone = 8; + break; + case 4: + newTone = 10; + break; + case 5: + newTone = 15; + break; + case 6: + newTone = 25; + break; + case 7: + newTone = 26; + break; + case 8: + newTone = 29; + break; + } + byte[] data2; + double angle = 0; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, sampleCt, ref angle, out data2); + Buffer.BlockCopy(data2, 0, sdata, 0, sampleCt * 2); + } + else + { + Random r = new Random(0xBEEF); + for (int i = 0; i < sdata.Length; i++) + sdata[i] = (short)(r.Next() - Int16.MinValue); + } + return sdata; + } + + private static void _Distort(byte[] data, int tone, int distortCt) + { + if (distortCt < 1) + return; + short[] sdata = new short[data.Length / 2]; + Buffer.BlockCopy(data, 0, sdata, 0, data.Length); + + short[][] distortions = new short[distortCt][]; + for (int i = 0; i < distortCt; i++) + distortions[i] = _GetDistort(data.Length / 2, tone, i); + + for (int i = 0; i < sdata.Length; i++) + { + double distortion = 0; + for (int j = 0; j < distortCt; j++) + distortion += distortions[j][i]; + distortion /= distortCt; + sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + distortion / 5.0); + } + Buffer.BlockCopy(sdata, 0, data, 0, data.Length); + } + + private static void _GetSineWave(double freq, int sampleRate, int sampleCt, ref double angle, out byte[] data) + { + const short max = short.MaxValue; + short[] data16Bit = new short[sampleCt]; + for (int i = 0; i < sampleCt; i++) + data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq + angle) * max); + angle = 2 * Math.PI * sampleCt / sampleRate * freq + angle; + angle = angle % (2 * Math.PI); + data = new byte[data16Bit.Length * 2]; + Buffer.BlockCopy(data16Bit, 0, data, 0, data.Length); + } + #endregion + + #region File + private struct STimedNote + { + public int Time, Note; + } + + private void _TestFile(string fileName, string testFileName) + { + if (!File.Exists(testFileName)) + return; + List tones = new List(); + using (StreamReader reader = new StreamReader(testFileName)) + { + String line; + while ((line = reader.ReadLine()) != null) + { + int p = line.IndexOf(' '); + if (p < 0) + continue; + STimedNote note; + note.Time = int.Parse(line.Substring(0, p)); + note.Note = int.Parse(line.Substring(p + 1)); + tones.Add(note); + } + } + _TestFile(fileName, tones); + } + + private void _TestFile(string fileName, int tone) + { + STimedNote note; + note.Note = tone; + note.Time = 46; + List tones = new List {note}; + _TestFile(fileName, tones); + } + + private static bool _IsNoteValid(int note, int time, IList tones) + { + const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples + for (int i = 0; i < tones.Count; i++) + { + if (tones[i].Time > time) + break; + if (i + 1 == tones.Count || time <= tones[i + 1].Time + lastNoteMaxTimeDiff) + { + if (tones[i].Note == note) + return true; + } + } + return false; + } + + private void _TestFile(string fileName, IList tones) + { + CWavFile wavFile = new CWavFile(); + try + { + if (!wavFile.Open(fileName)) + return; + if (wavFile.BitsPerSample != 16) + { + wavFile.Close(); + return; + } + int samplesRead = 0; + int curTimeIndex = -1; + int curNote = -1; + const int maxSamplesPerBatch = 512; + bool[] valids = new bool[_Tones.Length]; + while (wavFile.NumSamplesLeft > maxSamplesPerBatch) + { + byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); + samplesRead += samples.Length / 2; + int time = samplesRead * 1000 / wavFile.SampleRate; + _Process(samples); + while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) + { + curTimeIndex++; + curNote = tones[curTimeIndex].Note; + } + if (curNote < 0) + continue; + _CurTestCount++; + bool error = false; + for (int i = 0; i < _Tones.Length; i++) + { + valids[i] = _IsNoteValid(_Tones[i], time, tones); + if (valids[i]) + _CurPassedCount[i]++; + else + error = true; + } + if (error) + { + string msg = "Note " + _ToneToNote(curNote) + " at " + time + "ms detected as "; + for (int i = 0; i < 4; i++) + msg += _ToneToNote(_Tones[i]) + (valids[i] ? "" : "(!)") + "; "; + CBase.Log.LogDebug(msg); + } + } + } + catch (Exception e) + { + Console.WriteLine("Error on file " + fileName + ": " + e); + } + wavFile.Close(); + } + #endregion + } +} \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 1f6afd01..df259176 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -268,6 +268,7 @@ +