- Massively update/cleanup XML comments and docs
- Include XML documentation in nuget package
- Various refactorings
- Minor enhancements / bugfixes:
- Correct naming of methods
NormalizePeak()
/ ChangePeak()
- Add
signal.Crossfade()
, signal.FadeIn/Out()
methods
- Better implementation of
DesignFilter.Fir()
method
- Better implementation of
OnlineFeatureExtractor.VectorCount()
method
- Add implementation of
FastDct3.DirectNorm()
/ FastDct2.InverseNorm()
- 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
- 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)
- 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;
- 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);
- 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)