/// <summary> /// Evaluate harmonic and percussive mag-phase spectrograms from given signal. /// Both spectrogram objects share the same phase array. /// </summary> /// <param name="signal"></param> /// <returns></returns> public (MagnitudePhaseList, MagnitudePhaseList) EvaluateSpectrograms(DiscreteSignal signal) { // spectrogram memory will be reused for harmonic magnitudes var harmonicSpectrogram = _stft.MagnitudePhaseSpectrogram(signal); var harmonicMagnitudes = harmonicSpectrogram.Magnitudes; // median filtering along frequency axis: var percussiveMagnitudes = new List <float[]>(harmonicMagnitudes.Count); for (var i = 0; i < harmonicMagnitudes.Count; i++) { var mag = new DiscreteSignal(1, harmonicMagnitudes[i]); percussiveMagnitudes.Add(_medianPercussive.ApplyTo(mag).Samples); _medianPercussive.Reset(); } // median filtering along time axis: for (var j = 0; j <= _stft.Size / 2; j++) { int i = 0, k = 0; for (; k < _medianHarmonic.Size / 2; k++) // feed first Size/2 samples { _medianHarmonic.Process(harmonicMagnitudes[k][j]); } for (; i < harmonicMagnitudes.Count - _medianHarmonic.Size / 2; i++, k++) { var h = _medianHarmonic.Process(harmonicMagnitudes[k][j]); harmonicMagnitudes[i][j] *= _mask(h, percussiveMagnitudes[k][j]); percussiveMagnitudes[i][j] *= _mask(percussiveMagnitudes[k][j], h); } for (k = 0; k < _medianHarmonic.Size / 2; i++, k++) // don't forget last samples { var h = _medianHarmonic.Process(0); harmonicMagnitudes[i][j] *= _mask(h, percussiveMagnitudes[i][j]); percussiveMagnitudes[i][j] *= _mask(percussiveMagnitudes[i][j], h); } _medianHarmonic.Reset(); } var percussiveSpectrogram = new MagnitudePhaseList { Magnitudes = percussiveMagnitudes, Phases = harmonicSpectrogram.Phases }; return(harmonicSpectrogram, percussiveSpectrogram); }
public void TestMedianFiltering() { var filter = new MedianFilter2(5); var input = new[] { 2, 6, 5, 4, 0, 3, 5, 7, 9, 2, 0, 1f }; var expected = new[] { 2, 4, 4, 4, 4, 4, 5, 5, 5, 2, 1, 0f }; var filtered = filter.ApplyTo(new DiscreteSignal(1, input)); Assert.That(filtered.Samples, Is.EqualTo(expected).Within(1e-10)); }
public void TestMedianFilteringDefault() { var filter1 = new MedianFilter(); // 9-point median filter (faster implementation for sizes > 10) var filter2 = new MedianFilter2(); // 9-point median filter var input = new[] { 1, 6, 5, 2, 8, 1, 9, 5, 4, 2, 3, 4, 6, 7, 4f }; var expected = new[] { 1, 1, 2, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3f }; var filtered1 = filter1.ApplyTo(new DiscreteSignal(1, input)); var filtered2 = filter2.ApplyTo(new DiscreteSignal(1, input)); Assert.Multiple(() => { Assert.That(filtered1.Samples, Is.EqualTo(expected).Within(1e-10)); Assert.That(filtered2.Samples, Is.EqualTo(expected).Within(1e-10)); }); }
public void MedianFilter2() { var output = _filter2.ApplyTo(_signal); }
public void Run() { var output2 = new float[_signal.Length]; var output4 = new float[_signal.Length]; var output5 = new float[_signal.Length]; var outputZi = new float[_signal.Length]; var samples = _signal.Samples; for (var i = 0; i < samples.Length; i++) { output4[i] = _filterV4BiQuad.Process(samples[i]); output5[i] = _filterV5BiQuad.Process(samples[i]); outputZi[i] = _filterZiBiQuad.Process(samples[i]); } var diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average(); var diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average(); Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}"); Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}"); for (var i = 0; i < samples.Length; i++) { output4[i] = _filterV4Butterworth6.Process(samples[i]); output5[i] = _filterV5Butterworth6.Process(samples[i]); outputZi[i] = _filterZiButterworth6.Process(samples[i]); } diffAverageV4 = output5.Zip(output4, (o5, o4) => Math.Abs(o5 - o4)).Average(); diffAverageZi = output5.Zip(outputZi, (o5, zi) => Math.Abs(o5 - zi)).Average(); Console.WriteLine($"Average difference Ver.0.9.5 vs. Ver.0.9.4 : {diffAverageV4}"); Console.WriteLine($"Average difference IirFilter vs. ZiFilter : {diffAverageZi}"); // === MISC ==== var med = new MedianFilter(); var med2 = new MedianFilter2(); var medOut = med.ApplyTo(_signal).Samples; var medOut2 = med2.ApplyTo(_signal).Samples; var diffAverageMed = medOut.Zip(medOut, (m1, m2) => Math.Abs(m1 - m2)).Average(); Console.WriteLine($"Average difference MedianFilter vs. MedianFilter2 : {diffAverageMed}"); var ma = new MovingAverageFilter(); var maRec = new MovingAverageRecursiveFilter(); var maOut = ma.ApplyTo(_signal).Samples; var maRecOut = maRec.ApplyTo(_signal).Samples; var diffAverageMa = maOut.Zip(maRecOut, (m1, m2) => Math.Abs(m1 - m2)).Average(); Console.WriteLine($"Average difference MovingAverageFilter vs. MovingAverageRecursiveFilter : {diffAverageMa}"); // 32bit vs. 64bit var fir32 = new FirFilter(DesignFilter.FirWinLp(7, 0.1)); var fir64 = new FirFilter64(DesignFilter.FirWinLp(7, 0.1)); var fir32Out = fir32.ApplyTo(_signal).Samples; var fir64Out = fir64.ApplyTo(_signal.Samples.ToDoubles()); var diffAverageFir = fir64Out.Zip(fir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average(); Console.WriteLine($"Average difference FirFilter vs. FirFilter64 : {diffAverageFir}"); var iir32 = new IirFilter(_filterV5Butterworth6.Tf); var iir64 = new IirFilter64(_filterV5Butterworth6.Tf); var iir32Out = iir32.ApplyTo(_signal).Samples; var iir64Out = iir64.ApplyTo(_signal.Samples.ToDoubles()); var diffAverageIir = iir64Out.Zip(iir32Out, (m1, m2) => Math.Abs(m1 - m2)).Average(); Console.WriteLine($"Average difference IirFilter vs. IirFilter64 : {diffAverageIir}"); var zi32 = new ZiFilter(_filterV5Butterworth6.Tf); var zi64 = new ZiFilter64(_filterV5Butterworth6.Tf); var zi32Out = zi32.ApplyTo(_signal).Samples; var zi64Out = zi64.ApplyTo(_signal.Samples.ToDoubles()); var diffAverageZis = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average(); Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 : {diffAverageZis}"); zi32Out = zi32.ZeroPhase(_signal).Samples; zi64Out = zi64.ZeroPhase(_signal.Samples.ToDoubles()); var diffAverageZiZeroPhase = zi64Out.Zip(zi32Out, (m1, m2) => Math.Abs(m1 - m2)).Average(); Console.WriteLine($"Average difference ZiFilter vs. ZiFilter64 (zero-phase): {diffAverageZiZeroPhase}"); }