/// <summary> /// Perform adaptive whitening on the magnitude spectrogram /// </summary> /// <param name="floor">floor value</param> /// <param name="relaxation">relaxation time in seconds</param> /// "Adaptive Whitening For Improved Real-time Audio Onset Detection" /// Dan Stowell and Mark Plumbley /// Proceedings of the International Computer Music Conference(ICMC), 2007 public void AW(float floor = 5, float relaxation = 10) { var memCoeff = (float)Math.Pow(10.0, (-6 * relaxation / _fps)); var P = _allocator.GetFloatMatrix(Spec.RowCount, Spec.ColumnCount); //var P = Matrix<float>.Build.SameAs(Spec); //iterate over all frames Vector <float> spec_floor = _allocator.GetFloatVector(Spec.ColumnCount); //var spec_floor = Vector<float>.Build.Dense(Spec.ColumnCount); foreach (var f in Enumerable.Range(0, _frames)) { spec_floor.Clear(); for (int i = 0; i < Spec.ColumnCount; i++) { spec_floor[i] = Math.Max(Spec[f, i], floor); } //var spec_floor = Math.Max(Spec.ToRowArrays()[f].ToList().Max(), floor); if (f > 0) { for (int i = 0; i < P.ColumnCount; i++) { P[f, i] = Math.Max(spec_floor[i], memCoeff * P[f - 1, i]); } } else { P.SetRow(f, spec_floor); } } //adjust spec Spec = Spec.PointwiseDivide(P); //cleanup _allocator.ReturnFloatMatrixStorage((MathNet.Numerics.LinearAlgebra.Storage.DenseColumnMajorMatrixStorage <float>)P.Storage); _allocator.ReturnFloatVectorStorage((MathNet.Numerics.LinearAlgebra.Storage.DenseVectorStorage <float>)spec_floor.Storage); }
public void Cleanup() { _allocator.ReturnFloatMatrixStorage((MathNet.Numerics.LinearAlgebra.Storage.DenseColumnMajorMatrixStorage <float>)Filterbank.Storage); }