Skip to content

Known bugs and changelog

Tim Sharii edited this page Aug 19, 2021 · 35 revisions

Version 0.9.5

  • Multi-target package to .NET Standard 2.0 and .NET 5
  • Add Fft / RealFft methods taking Span as input
  • Add 3D/Stereo audio functionality (stereo panning, stereo and ping-pong delay, ITD-ILD, binaural panning)
  • Add benchmarks
  • Accelerate IirFilter, Butterworth, Elliptic, Chebyshev filters
  • Add OnlineFeatureExtractor class
  • Add methods for fractional delay FIR filter design
  • Add code for designing even-sized FIR filters
  • Add FadeInOutBuilder class
  • Add IIR filter design methods IirNotch / IirPeak / IirCombNotch / IirCombPeak
  • Add FractionalDelayLine class with more interpolation options (cubic, Thiran)
  • Add WetDryMixer class
  • Implement more distortion modes
  • Add WaveShaper class
  • Add BitCrusherEffect class
  • Add DynamicsProcessor class (limiter/compressor/expander/noise gate)
  • Add Filterbanks.Chroma() method and ChromaFeatureExtractor class
  • Add Welch() and LombScargle() methods for evaluating periodograms
  • Various minor enhancements / bugfixes:
    • implement 'perfect reconstruction' mode in inverse STFT
    • add normalization flag in Stft.Spectrogram() method
    • add DiscreteSignal.Unit() and DiscreteSignal.Reverse() methods
    • add EstimateGain() method and methods for filter processing with user-specified gain
    • WaveFile constructor doesn't close underlying stream
    • change type of TF zeros and poles to Complex[]. Methods accepting ComplexDiscreteSignal objects are not removed.
    • add overloaded constructor: var zsignal = new ComplexDiscreteSignal(1, tf.Zeros);
    • add faster implementation of median filter
    • add FilterChain64 and StereoFilter64 classes
    • fix bug with magnitude doubling in OlaBlockConvolver64/OlsBlockConvolver64
    • fix bug in EnvelopeFollower.Process() method
    • add Wavelet constructor with user-defined wavelet coefficients
    • rename WindowTypes enum to WindowType

Version 0.9.4

  • Add ZiFilter class / TransferFunction.Zi property
  • Add methods for TransferFunction <-> StateSpace conversion
  • Modify DesignFilter.IirBsTf() function to produce MATLAB/sciPy-like results
  • Add FastDct family (DCT implementations via FFT for large sizes)
  • Add Mdct and FastMdct classes (Modified DCT)
  • Add KarplusStrongBuilder / KarplusStrongDrumBuilder classes
  • Add PadSynthBuilder class
  • Add StereoFilter class for convenient filtering of data in interleaved buffers
  • Add Scale.NoteToFreq() / Scale.FreqToNote() methods
  • Add Fft.InverseNorm() and RealFft.InverseNorm() methods
  • Bugfix: correct gain in TfToSos() method
  • Bugfix: correct results of RealFft.Inverse() (results of previous implementation should be multiplied by 2)

Version 0.9.3

  • Accelerate FIR/IIR online filtering (up to ~2x in .NET Framework, up to ~1.3x in .NET Core)
  • Add 64-bit FIR/IIR filters and block convolvers (OLA/OLS)
  • Fix incorrect implementation of adaptive filtering
  • Add OverlapAddFilter base class for PV-based filters/effects
  • Add ByteConverter class
  • Bugfix: allow STFT have window size different from power-of-two
  • Introduce LogEnergyFloor parameter in MFCC/PNCC/PLP extractors
  • Add chorus effect; enhance flanger, vibrato effects
  • Nicer design of feature extractors:
var mfccOptions = new MfccOptions
{
    SamplingRate = 22050,
    FeatureCount = 13,
    FrameDuration = 0.032/*sec*/,
    HopDuration = 0.015/*sec*/,
    FilterBankSize = 26,
    HighFrequency = 6000,
    PreEmphasis = 0.97,
    //...unspecified parameters will have default values 
};

var mfccExtractor = new MfccExtractor(mfccOptions);
List<float[]> mfccVectors = mfccExtractor.ComputeFrom(signal);

// { 0, 0.015, 0.030, 0.045, 0.060, 0.075, ... }
List<double> timeMarkers = mfccExtractor.TimeMarkers(mfccVectors.Count);

// serialize current config to JSON file:
using (var config = new FileStream("file.json", FileMode.Create))
{
    config.SaveOptions(mfccOptions);
}

// open config from JSON file:
PlpOptions options;
using (var config = new FileStream("file.json", FileMode.Open))
{
    // identical fields will be copied, other fields will be ignored
    options = config.LoadOptions<PlpOptions>();
}

// cast (identical fields will be copied, other fields will be ignored)
options = mfccOptions.Cast<MfccOptions, PlpOptions>();

// get all errors after validation:
List<string> errors = options.Errors;

Version 0.9.2

  • Add more IIR filters: Bessel, Chebyshev-I & II, Elliptic, Thiran
  • Add TfToSos / SosToTf methods to DesignFilter class for working with second-order sections
  • Add SavitzkyGolayFilter class (window size up to 31; derivatives 0, 1, 2)
  • Add Fwt class for Fast Wavelet Transform and wavelets ("haar", "db1-20", "sym2-20", "coif1-5")
  • Add PolyphaseSystem class
  • Add PlpExtractor class
  • Add Lpc class with new methods ToLsf / FromLsf, move LPC-related functions to Lpc
  • Add more customizations in MfccExtractor class
  • Add more customizations in FilterBanks class
  • Add VtlnWarper class
  • Add Stft methods: MagnitudePhaseSpectrogram()/ReconstructMagnitudePhase()
  • Add HarmonicPercussiveSeparator class
  • Add GriffinLimReconstructor class
  • Add Remez class for equiripple FIR filter design
  • Add methods FirWin(Lp|Hp|Bp|Bs) and FirEquiripple(Lp|Hp|Bp|Bs) to DesignFilter class
  • Fix bug with pre-emphasis in PnccExtractor that led to less accurate results
  • Add lpcOrder parameter to LpccExtractor
  • Add RealFft class and use it instead of Fft where possible (25-35% performance gain)
  • Important change in interface and implementation of LTI filter classes:
// code in versions before 0.9.2
var filter = DesignFilter.FirLp(145, 0.15f);
var impulseResponse = filter.ImpulseResponse();
var magnitudeResponse = filter.FrequencyResponse().Magnitude;
var tf = filter.Tf;

// became:
var filter = new FirFilter(DesignFilter.FirWinLp(145, 0.15));
var impulseResponse = filter.Tf.ImpulseResponse();
var magnitudeResponse = filter.Tf.FrequencyResponse().Magnitude;
var tf = filter.Tf;  // looks the same, but now it's more optimized

// in short:
// FirFilter / IirFilter classes are now used only for filtering.
// Everything related to filter design & analysis as of ver.0.9.2
// is concentrated in TransferFunction class. It was here before,
// but FDA responsibilities were somewhat mixed between filters and Tf.

// Filter objects contained arrays of both 32-bit and 64-bit coefficients
// although filtering was (and still is) done with 32-bit floats
// and FDA was (and still is) done with 64-bit doubles.

// As of ver.0.9.2 filters contain only 32-bit coefficients for filtering
// and the reference to TransferFunction object (not null - only if needed).
// TF objects contain 64-bit numerator / denominator coefficients.

var filter = new IirFilter(new[] { 1, 0.2, -0.3 }, new[] { 1, 0.9 });
var tf = filter.Tf;
// in this case TransferFunction will be generated on the fly
// from 32-bit floats (so we'll lose precision).
// Internal Tf object of the filter is still null.
// Memory efficient, but this filter maybe lacks precision for filter analysis.
// If we need just to filter data, this is the best solution.

var filter = new IirFilter(new TransferFunction(new[]{ 1, 0.2, -0.3 }, new[]{ 1, 0.9 }));
var tf = filter.Tf;
// here the filter stores the reference to TF with 64-bit precision
// and Tf property returns this reference.
// If we use this filter only for filtering, then this constructor is redundant
// and memory inefficient.


// Surely, we can work just with TF object, without any filter objects:

var tf = new TransferFunction(new[] { 1, 0.2, -0.3 }, new[] { 1, 0.9 });
var zeros = tf.Zeros;
var freqResponse = tf.FrequencyResponse(1024);
// etc.

// 64-bit precision:
var tf1 = new TransferFunction(b, a);
var tf2 = new TransferFunction(d, c);
var tf = tf1 * tf2;

// 32-bit precision:
var filter1 = new IirFilter(b, a);
var filter2 = new IirFilter(d, c);
var filter = filter1 * filter2;


// also:
var hpFilter = DesignFilter.LpToHp(filter);
var lpFilter = DesignFilter.HpToLp(hpFilter);
var bpFilter = DesignFilter.FirBp(123, 0.05f, 0.15f);
var brFilter = DesignFilter.FirBr(201, 0.08f, 0.23f, WindowTypes.Kaiser);

// became:
var hpFilter = DesignFilter.FirLpToHp(filter);
var lpFilter = DesignFilter.FirHpToLp(hpFilter);
var bpFilter = DesignFilter.FirWinBp(123, 0.05, 0.15);
var brFilter = DesignFilter.FirWinBr(201, 0.08, 0.23, WindowTypes.Kaiser);

Version 0.9.1

  • Add adaptive filters (LMS variations, LMF, RLS)
  • Add Hartley transform
  • Add Mellin transform
  • Add wavetable and ADSR signal builders
  • Add PitchShiftVocoderEffect class
  • Add parameter int parallelThreads in ParallelComputeFrom method of feature extractors
  • Add overloaded versions of ParallelComputeFrom methods with startSample and endSample parameters
  • Implement online processing methods in SpectralSubtractor, WhisperEffect, RobotEffect, MorphEffect
  • Phase Vocoder with Identity Phase Locking is used by default for TSM (instead of WSOLA)
  • Trim feature names in FeatureDescriptions list of multi-feature extractors
  • Move PitchExtractor to FeatureExtractors namespace
  • Fix bug with incorrectly working pre-emphasis filter in Lpc/LpccExtractor
  • Size of FFT in Pncc/SpnccExtractor is 0 by default (it'll be auto-derived)
Clone this wiki locally