[DataRow(1174.66F, 106, DisplayName = "D6")] // Top octave public void OutputBinTestSingleValueWithPureSine(float testFreq, int expectedPeak) { const float BASE_FREQ = 55F; // A2 ShinNoteFinderDFT NF = new ShinNoteFinderDFT(); NF.CalculateFrequencies(BASE_FREQ); NF.FillReferenceTables(); NF.PrepareSampleStorage(); // Fill input. float Omega1 = testFreq * MathF.PI * 2 / NF.SampleRate; float[] TestWaveform = new float[NF.WindowSize / 2]; for (uint i = 0; i < TestWaveform.Length; i++) { TestWaveform[i] = MathF.Sin(i * Omega1); } NF.AddSamples(TestWaveform); //NF.SaveData(); // Get output float[] Output = NF.Magnitudes; // Find peak float PeakVal = -1F; int PeakInd = -1; for (int i = 0; i < Output.Length; i++) { if (Output[i] > PeakVal) { PeakVal = Output[i]; PeakInd = i; } } // Make sure peak is correct and large enough Assert.IsTrue(PeakVal > 1500F, "Peak was not large enough"); Assert.IsTrue(PeakInd == expectedPeak, "Peak was in the wrong place"); // Make sure all far-away bins are small enough for (int i = 0; i < Output.Length; i++) { if (Math.Abs(i - PeakInd) > 3) { Assert.IsTrue(Output[i] < (PeakVal / 2), "Other frequencies had content too strong compared to peak"); } } }
public void OutputBinTestCompondSineProprotional(float testFreq1, float testFreq2, int expectedPeak1, int expectedPeak2, float ratio) { const float BASE_FREQ = 55F; // A2 ShinNoteFinderDFT NF = new ShinNoteFinderDFT(); NF.CalculateFrequencies(BASE_FREQ); NF.FillReferenceTables(); NF.PrepareSampleStorage(); // Fill input. float Omega1 = testFreq1 * MathF.PI * 2 / NF.SampleRate; float Omega2 = testFreq2 * MathF.PI * 2 / NF.SampleRate; float[] TestWaveform = new float[NF.WindowSize / 2]; for (uint i = 0; i < TestWaveform.Length; i++) { float Wave1 = ratio * MathF.Sin(i * Omega1); float Wave2 = (1 - ratio) * MathF.Sin(i * Omega2); TestWaveform[i] = Wave1 + Wave2; } NF.AddSamples(TestWaveform); // Get output float[] Output = NF.Magnitudes; // Find peaks float PeakVal1 = -1F; float PeakVal2 = -1F; int PeakInd1 = -1; int PeakInd2 = -1; for (int i = 0; i < Output.Length; i++) { if (Output[i] > PeakVal1) { PeakVal2 = PeakVal1; PeakVal1 = Output[i]; PeakInd2 = PeakInd1; PeakInd1 = i; } else if (Output[i] > PeakVal2) { PeakVal2 = Output[i]; PeakInd2 = i; } } // Sort the peaks if (PeakInd1 > PeakInd2) { float ValTemp = PeakVal1; PeakVal1 = PeakVal2; PeakVal2 = ValTemp; int IndTemp = PeakInd1; PeakInd1 = PeakInd2; PeakInd2 = IndTemp; } // Make sure peaks are correct and large enough Assert.IsTrue(PeakVal1 > (1500F * ratio), "Peak 1 was not large enough"); Assert.IsTrue(PeakVal2 > (1500F * (1 - ratio)), "Peak 2 was not large enough"); Assert.IsTrue(PeakInd1 == expectedPeak1, "Peak 1 was in the wrong place"); Assert.IsTrue(PeakInd2 == expectedPeak2, "Peak 2 was in the wrong place"); // Make sure the ratio is about right float Total = PeakVal1 + PeakVal2; Assert.IsTrue(Math.Abs((PeakVal1 / Total) - ratio) < 0.05F, "Peak 1 was not balanced to ratio"); Assert.IsTrue(Math.Abs((PeakVal2 / Total) - (1 - ratio)) < 0.05F, "Peak 2 was not balanced to ratio"); // Make sure all far-away bins are small enough for (int i = 0; i < Output.Length; i++) { if (Math.Abs(i - PeakInd1) > 3 && Math.Abs(i - PeakInd2) > 3) { Assert.IsTrue(Output[i] < (Math.Max(PeakVal1, PeakVal2) / 1.5F), "Too much noise far away from peaks"); } } }