/// <summary> /// Constructor /// </summary> /// <param name="noise"></param> /// <param name="fftSize"></param> /// <param name="hopSize"></param> public SpectralSubtractor(DiscreteSignal noise, int fftSize = 1024, int hopSize = 128) { Guard.AgainstInvalidRange(hopSize, fftSize, "Hop size", "FFT size"); _fftSize = fftSize; _hopSize = hopSize; _overlapSize = _fftSize - _hopSize; _fft = new RealFft(_fftSize); _window = Window.OfType(WindowTypes.Hann, _fftSize); _gain = 2 / (_fftSize * _window.Select(w => w * w).Sum() / _hopSize); _noiseEstimate = new float[_fftSize / 2 + 1]; _dl = new float[_fftSize]; _re = new float[_fftSize]; _im = new float[_fftSize]; _filteredRe = new float[_fftSize]; _filteredIm = new float[_fftSize]; _lastSaved = new float[_overlapSize]; EstimateNoise(noise); Reset(); }
/// <summary> /// Constructs extractor from configuration <paramref name="options"/>. /// </summary> public SpnccExtractor(PnccOptions options) : base(options) { FeatureCount = options.FeatureCount; var filterbankSize = options.FilterBankSize; if (options.FilterBank is null) { _blockSize = options.FftSize > FrameSize ? options.FftSize : MathUtils.NextPowerOfTwo(FrameSize); FilterBank = FilterBanks.Erb(filterbankSize, _blockSize, SamplingRate, options.LowFrequency, options.HighFrequency); } else { FilterBank = options.FilterBank; filterbankSize = FilterBank.Length; _blockSize = 2 * (FilterBank[0].Length - 1); Guard.AgainstExceedance(FrameSize, _blockSize, "frame size", "FFT size"); } _power = options.Power; _includeEnergy = options.IncludeEnergy; _logEnergyFloor = options.LogEnergyFloor; _fft = new RealFft(_blockSize); _dct = new Dct2(filterbankSize); _spectrum = new float[_blockSize / 2 + 1]; _filteredSpectrum = new float[filterbankSize]; }
/// <summary> /// Constructor /// </summary> /// <param name="samplingRate"></param> /// <param name="shift"></param> /// <param name="fftSize"></param> /// <param name="hopSize"></param> public PitchShiftVocoderEffect(int samplingRate, double shift, int fftSize = 1024, int hopSize = 64) { _shift = (float)shift; _fftSize = fftSize; _hopSize = hopSize; _overlapSize = _fftSize - _hopSize; Guard.AgainstInvalidRange(_hopSize, _fftSize, "Hop size", "FFT size"); _fft = new RealFft(_fftSize); _window = Window.OfType(WindowTypes.Hann, _fftSize); _gain = (float)(2 * Math.PI / (_fftSize * _window.Select(w => w * w).Sum() / _hopSize)); _freqResolution = samplingRate / _fftSize; _dl = new float[_fftSize]; _re = new float[_fftSize]; _im = new float[_fftSize]; _filteredRe = new float[_fftSize]; _filteredIm = new float[_fftSize]; _lastSaved = new float[_overlapSize]; _mag = new float[_fftSize / 2 + 1]; _phase = new float[_fftSize / 2 + 1]; _prevPhase = new float[_fftSize / 2 + 1]; _phaseTotal = new float[_fftSize / 2 + 1]; }
/// <summary> /// Constructor /// </summary> /// <param name="stretch"></param> /// <param name="hopAnalysis"></param> /// <param name="fftSize"></param> /// <param name="phaseLocking"></param> public PhaseLockingVocoder(double stretch, int hopAnalysis, int fftSize = 0, bool phaseLocking = true) { _stretch = stretch; _hopAnalysis = hopAnalysis; _hopSynthesis = (int)(hopAnalysis * stretch); _fftSize = (fftSize > 0) ? fftSize : 8 * Math.Max(_hopAnalysis, _hopSynthesis); _phaseLocking = phaseLocking; _fft = new RealFft(_fftSize); _window = Window.OfType(WindowTypes.Hann, _fftSize); _gain = 2 / (_fftSize * _window.Select(w => w * w).Sum() / _hopSynthesis); _omega = Enumerable.Range(0, _fftSize / 2 + 1) .Select(f => 2 * Math.PI * f / _fftSize) .ToArray(); _mag = new double[_fftSize / 2 + 1]; _phase = new double[_fftSize / 2 + 1]; _prevPhase = new double[_fftSize / 2 + 1]; _phaseTotal = new double[_fftSize / 2 + 1]; _delta = new double[_fftSize / 2 + 1]; _peaks = new int[_fftSize / 4]; _re = new float[_fftSize]; _im = new float[_fftSize]; }
/// <summary> /// Pitch estimation: from spectral peaks /// </summary> /// <param name="signal"></param> /// <param name="startPos"></param> /// <param name="endPos"></param> /// <returns></returns> public static float FromSpectralPeaks(DiscreteSignal signal, int startPos = 0, int endPos = -1, float low = 80, float high = 400, int fftSize = 0) { if (endPos == -1) { endPos = signal.Length; } if (startPos != 0 || endPos != signal.Length) { signal = signal[startPos, endPos]; } signal.ApplyWindow(WindowTypes.Hann); var size = fftSize > 0 ? fftSize : MathUtils.NextPowerOfTwo(signal.Length); var fft = new RealFft(size); var spectrum = fft.PowerSpectrum(signal, false).Samples; return(FromSpectralPeaks(spectrum, signal.SamplingRate, low, high)); }
private void UpdateSpectrumAndCepstrum() { var fftSize = int.Parse(fftSizeTextBox.Text); var cepstrumSize = int.Parse(cepstrumSizeTextBox.Text); _hopSize = int.Parse(hopSizeTextBox.Text); if (fftSize != _fftSize) { _fftSize = fftSize; _fft = new RealFft(fftSize); _cepstralTransform = new CepstralTransform(cepstrumSize, _fftSize); } if (cepstrumSize != _cepstrumSize) { _cepstrumSize = cepstrumSize; _cepstralTransform = new CepstralTransform(_cepstrumSize, _fftSize); } var pos = _hopSize * _specNo; var block = _signal[pos, pos + _fftSize]; //block.ApplyWindow(WindowTypes.Hamming); var cepstrum = new float[_fftSize]; _cepstralTransform.RealCepstrum(block.Samples, cepstrum); // ************************************************************************ // just visualize spectrum estimated from cepstral coefficients: // ************************************************************************ var real = new float[_fftSize]; var imag = new float[_fftSize]; for (var i = 0; i < 32; i++) { real[i] = cepstrum[i]; } _fft.Direct(real, real, imag); var spectrum = _fft.PowerSpectrum(block, normalize: false).Samples; var avg = spectrum.Average(s => LevelScale.ToDecibel(s)); var spectrumEstimate = real.Take(_fftSize / 2 + 1) .Select(s => (float)LevelScale.FromDecibel(s * 40 - avg)) .ToArray(); spectrumPanel.Line = spectrum; spectrumPanel.Markline = spectrumEstimate; spectrumPanel.ToDecibel(); var pitch = Pitch.FromCepstrum(block); cepstrumPanel.Line = cepstrum; cepstrumPanel.Mark = (int)(_signal.SamplingRate / pitch); }
public FftArrayVsSpan() { _fft = new RealFft(FrameSize); _fft64 = new RealFft64(FrameSize); _complexFft = new Fft(FrameSize); _samples = new WhiteNoiseBuilder().OfLength(N).Build().Samples; _samples64 = _samples.ToDoubles(); }
/// <summary> /// Constructor /// </summary> /// <param name="samplingRate"></param> /// <param name="featureCount"></param> /// <param name="frameDuration">Length of analysis window (in seconds)</param> /// <param name="hopDuration">Length of overlap (in seconds)</param> /// <param name="power"></param> /// <param name="lowFreq"></param> /// <param name="highFreq"></param> /// <param name="filterbankSize"></param> /// <param name="filterbank"></param> /// <param name="fftSize">Size of FFT (in samples)</param> /// <param name="preEmphasis"></param> /// <param name="window"></param> public PnccExtractor(int samplingRate, int featureCount, double frameDuration = 0.0256 /*sec*/, double hopDuration = 0.010 /*sec*/, int power = 15, double lowFreq = 100, double highFreq = 6800, int filterbankSize = 40, float[][] filterbank = null, int fftSize = 0, double preEmphasis = 0, WindowTypes window = WindowTypes.Hamming) : base(samplingRate, frameDuration, hopDuration, preEmphasis) { FeatureCount = featureCount; _lowFreq = lowFreq; _highFreq = highFreq; if (filterbank == null) { _blockSize = fftSize > FrameSize ? fftSize : MathUtils.NextPowerOfTwo(FrameSize); FilterBank = FilterBanks.Erb(filterbankSize, _blockSize, samplingRate, _lowFreq, _highFreq); } else { FilterBank = filterbank; filterbankSize = filterbank.Length; _blockSize = 2 * (filterbank[0].Length - 1); Guard.AgainstExceedance(FrameSize, _blockSize, "frame size", "FFT size"); } _fft = new RealFft(_blockSize); _dct = new Dct2(filterbankSize); _power = power; _window = window; _windowSamples = Window.OfType(_window, FrameSize); _spectrum = new float[_blockSize / 2 + 1]; _spectrumQOut = new float[filterbankSize]; _gammatoneSpectrum = new float[filterbankSize]; _filteredSpectrumQ = new float[filterbankSize]; _spectrumS = new float[filterbankSize]; _smoothedSpectrumS = new float[filterbankSize]; _avgSpectrumQ1 = new float[filterbankSize]; _avgSpectrumQ2 = new float[filterbankSize]; _smoothedSpectrum = new float[filterbankSize]; _ringBuffer = new SpectraRingBuffer(2 * M + 1, filterbankSize); _step = M - 1; }
/// <summary> /// Main constructor /// </summary> /// <param name="samplingRate"></param> /// <param name="featureCount"></param> /// <param name="frameDuration">Length of analysis window (in seconds)</param> /// <param name="hopDuration">Length of overlap (in seconds)</param> /// <param name="power"></param> /// <param name="lowFreq"></param> /// <param name="highFreq"></param> /// <param name="filterbankSize"></param> /// <param name="filterbank"></param> /// <param name="fftSize">Size of FFT (in samples)</param> /// <param name="preEmphasis"></param> /// <param name="window"></param> public SpnccExtractor(int samplingRate, int featureCount, double frameDuration = 0.0256 /*sec*/, double hopDuration = 0.010 /*sec*/, int power = 15, double lowFreq = 100, double highFreq = 6800, int filterbankSize = 40, float[][] filterbank = null, int fftSize = 0, double preEmphasis = 0, WindowTypes window = WindowTypes.Hamming) : base(samplingRate, frameDuration, hopDuration, preEmphasis) { FeatureCount = featureCount; _power = power; if (filterbank == null) { _blockSize = fftSize > FrameSize ? fftSize : MathUtils.NextPowerOfTwo(FrameSize); _lowFreq = lowFreq; _highFreq = highFreq; FilterBank = FilterBanks.Erb(filterbankSize, _blockSize, samplingRate, _lowFreq, _highFreq); // use power spectrum: foreach (var filter in FilterBank) { for (var j = 0; j < filter.Length; j++) { var ps = filter[j] * filter[j]; filter[j] = ps; } } } else { FilterBank = filterbank; filterbankSize = filterbank.Length; _blockSize = 2 * (filterbank[0].Length - 1); Guard.AgainstExceedance(FrameSize, _blockSize, "frame size", "FFT size"); } _fft = new RealFft(_blockSize); _dct = new Dct2(filterbankSize); _window = window; _windowSamples = Window.OfType(_window, FrameSize); _spectrum = new float[_blockSize / 2 + 1]; _filteredSpectrum = new float[filterbankSize]; }
/// <summary> /// Prepare all necessary arrays for calculations /// </summary> /// <param name="fftSize"></param> private void PrepareMemory(int fftSize) { _fftSize = fftSize; _fft = new RealFft(_fftSize); _real1 = new float[_fftSize]; _imag1 = new float[_fftSize]; _real2 = new float[_fftSize]; _imag2 = new float[_fftSize]; }
public void setLength(int length) { int size = twoPower(length); if (rfft == null || rfft.Size != size) { rfft = new RealFft(size); real = new float[size]; imag = new float[size]; stretcher = new SpectrumStretcher(size, 1.5f); } }
public void TestRealFft() { float[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; // Enumerable.Range(0, 16); float[] re = new float[9]; float[] im = new float[9]; var realFft = new RealFft(16); realFft.Direct(array, re, im); Assert.That(re, Is.EqualTo(new float[] { 120, -8, -8, -8, -8, -8, -8, -8, -8 }).Within(1e-5)); Assert.That(im, Is.EqualTo(new float[] { 0, 40.21872f, 19.31371f, 11.97285f, 8, 5.34543f, 3.31371f, 1.591299f, 0 }).Within(1e-5)); }
public void Initialize(double[] data) { int length = Size = data.Length; fft = new RealFft(length); this.re = new float[length]; this.im = new float[length]; this.data = new float[length]; for (int i = 0; i < length; i++) { this.data[i] = (float)data[i]; } }
public void TestInverseRealFft() { float[] array = { 1, 5, 3, 7, 2, 3, 0, 7 }; float[] output = new float[array.Length]; float[] re = new float[5]; float[] im = new float[5]; var realFft = new RealFft(8); realFft.Direct(array, re, im); realFft.Inverse(re, im, output); Assert.That(output, Is.EqualTo(array.Select(a => a * 4)).Within(1e-5)); }
protected void SetFftSize(int fftSize) { _fftSize = fftSize; if (_fft == null || _fft.Size != _fftSize) { _fft = new RealFft(_fftSize); _re = new float[_fftSize]; _im = new float[_fftSize]; _samples = new float[_fftSize]; } GenerateWavetable(); }
/// <summary> /// Constructor /// </summary> /// <param name="stretch"></param> /// <param name="hopAnalysis"></param> /// <param name="fftSize"></param> public PaulStretch(double stretch, int hopAnalysis, int fftSize = 0) { _stretch = stretch; _hopAnalysis = hopAnalysis; _hopSynthesis = (int)(hopAnalysis * stretch); _fftSize = (fftSize > 0) ? fftSize : 8 * Math.Max(_hopAnalysis, _hopSynthesis); _fft = new RealFft(_fftSize); _window = Window.OfType(WindowTypes.Hann, _fftSize); _gain = 2 / (_fftSize * _window.Select(w => w * w).Sum() / _hopSynthesis); _re = new float[_fftSize]; _im = new float[_fftSize]; }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { var ofd = new OpenFileDialog(); if (ofd.ShowDialog() != DialogResult.OK) { return; } using (var stream = new FileStream(ofd.FileName, FileMode.Open)) { var waveFile = new WaveFile(stream); _signal = waveFile[Channels.Left]; } _fft = new RealFft(512); var options = new LpcOptions { SamplingRate = _signal.SamplingRate, LpcOrder = 16, FrameDuration = FrameDuration, HopDuration = HopDuration }; var lpcExtractor = new LpcExtractor(options); //var lpcExtractor = new LpccExtractor(options); //var lpcExtractor = new PlpExtractor(_signal.SamplingRate, 10, // lpcOrder: 8, // rasta: 0.94, // filterbankSize: 20, // //lifterSize: 22, // window: WindowTypes.Hann); _lpcVectors = lpcExtractor.ParallelComputeFrom(_signal); FillFeaturesList(_lpcVectors, lpcExtractor.FeatureDescriptions, lpcExtractor.TimeMarkers(_lpcVectors.Count)); lpcListView.Items[0].Selected = true; spectrumPanel.Line = ComputeSpectrum(0); spectrumPanel.Markline = EstimateSpectrum(0); spectrumPanel.ToDecibel(); lpcPanel.Line = _lpcVectors[0].Skip(1).ToArray(); }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { var ofd = new OpenFileDialog(); if (ofd.ShowDialog() != DialogResult.OK) { return; } using (var stream = new FileStream(ofd.FileName, FileMode.Open)) { var waveFile = new WaveFile(stream); _signal = waveFile[Channels.Left]; } _fftSize = int.Parse(fftSizeTextBox.Text); _cepstrumSize = int.Parse(cepstrumSizeTextBox.Text); _hopSize = int.Parse(hopSizeTextBox.Text); _fft = new RealFft(_fftSize); _cepstralTransform = new CepstralTransform(_cepstrumSize, _fftSize); var options = new PitchOptions { SamplingRate = _signal.SamplingRate, FrameDuration = (double)_fftSize / _signal.SamplingRate, HopDuration = (double)_hopSize / _signal.SamplingRate }; var pitchExtractor = new PitchExtractor(options); _pitches = pitchExtractor.ParallelComputeFrom(_signal); _specNo = 0; specNoComboBox.DataSource = Enumerable.Range(1, _pitches.Count).ToArray(); // obtain spectrogram _stft = new Stft(_fftSize, _hopSize, WindowTypes.Rectangular); var spectrogram = _stft.Spectrogram(_signal); spectrogramPanel.ColorMapName = "viridis"; spectrogramPanel.MarklineThickness = 6; spectrogramPanel.Spectrogram = spectrogram.Select(s => s.Take(224).ToArray()).ToList(); spectrogramPanel.Markline = _pitches.Select(p => p[0] * _fftSize / _signal.SamplingRate).ToArray(); }
/// <summary> /// Calculate filtering gain so that frequency response is normalized onto [0, 1] range. /// </summary> /// <param name="filter"></param> /// <param name="fftSize"></param> /// <returns>Gain for filtering operations</returns> public static float EstimateGain(this IOnlineFilter filter, int fftSize = 512) { var unit = DiscreteSignal.Unit(fftSize); // get impulse response var response = unit.Samples.Select(s => filter.Process(s)).ToArray(); // get frequency response var spectrum = new float[fftSize / 2 + 1]; var fft = new RealFft(fftSize); fft.MagnitudeSpectrum(response, spectrum); return(1 / spectrum.Max(s => Math.Abs(s))); }
public double[] Spectrum(double[] input, bool scale) { int length = input.Length; var data = Helper.ConvertToFloat(input); var re = new float[length]; var im = new float[length]; var fft = new RealFft(length); fft.Direct(data, re, im); var spectrum = Helper.ComputeSpectrum(length / 2, re, im); fft.Inverse(re, im, data); return(spectrum); }
/// <summary> /// Constructs extractor from configuration <paramref name="options"/>. /// </summary> public ChromaExtractor(ChromaOptions options) : base(options) { _options = options; _blockSize = options.FftSize > FrameSize ? options.FftSize : MathUtils.NextPowerOfTwo(FrameSize); FeatureCount = options.FeatureCount; _filterBank = FilterBanks.Chroma(_blockSize, SamplingRate, FeatureCount, options.Tuning, options.CenterOctave, options.OctaveWidth, options.Norm, options.BaseC); _fft = new RealFft(_blockSize); _spectrum = new float[_blockSize / 2 + 1]; }
/// <summary> /// Constructs <see cref="MorphEffect"/>. /// </summary> /// <param name="hopSize">Hop size (hop length, number of samples)</param> /// <param name="fftSize">FFT size</param> public MorphEffect(int hopSize, int fftSize = 0) { _hopSize = hopSize; _fftSize = (fftSize > 0) ? fftSize : 8 * hopSize; _overlapSize = _fftSize - _hopSize; Guard.AgainstInvalidRange(_hopSize, _fftSize, "Hop size", "FFT size"); _fft = new RealFft(_fftSize); _window = Window.OfType(WindowType.Hann, _fftSize); _dl1 = new float[_fftSize]; _re1 = new float[_fftSize]; _im1 = new float[_fftSize]; _dl2 = new float[_fftSize]; _re2 = new float[_fftSize]; _im2 = new float[_fftSize]; _filteredRe = new float[_fftSize]; _filteredIm = new float[_fftSize]; _lastSaved = new float[_overlapSize]; }
/// <summary> /// Constuctor /// </summary> /// <param name="hopSize"></param> /// <param name="fftSize"></param> public RobotEffect(int hopSize, int fftSize = 0) { _hopSize = hopSize; _fftSize = (fftSize > 0) ? fftSize : 8 * hopSize; _overlapSize = _fftSize - _hopSize; Guard.AgainstInvalidRange(_hopSize, _fftSize, "Hop size", "FFT size"); _fft = new RealFft(_fftSize); _window = Window.OfType(WindowTypes.Hann, _fftSize); _gain = (float)(Math.PI * Math.PI / (_fftSize * _window.Select(w => w * w).Sum() / _hopSize)); _dl = new float[_fftSize]; _re = new float[_fftSize]; _im = new float[_fftSize]; _filteredRe = new float[_fftSize]; _filteredIm = new float[_fftSize]; _lastSaved = new float[_overlapSize]; }
/// <summary> /// Constructor /// </summary> /// <param name="kernel"></param> /// <param name="fftSize"></param> public OlsBlockConvolver(IEnumerable <float> kernel, int fftSize) { _kernel = kernel.ToArray(); _fftSize = MathUtils.NextPowerOfTwo(fftSize); Guard.AgainstExceedance(_kernel.Length, _fftSize, "Kernel length", "the size of FFT"); _fft = new RealFft(_fftSize); _kernelSpectrumRe = _kernel.PadZeros(_fftSize); _kernelSpectrumIm = new float[_fftSize]; _convRe = new float[_fftSize]; _convIm = new float[_fftSize]; _blockRe = new float[_fftSize]; _blockIm = new float[_fftSize]; _lastSaved = new float[_kernel.Length - 1]; _fft.Direct(_kernelSpectrumRe, _kernelSpectrumRe, _kernelSpectrumIm); Reset(); }
/// <summary> /// Constructs <see cref="OverlapAddFilter"/>. /// </summary> /// <param name="hopSize">Hop size (hop length, number of samples)</param> /// <param name="fftSize">FFT size</param> public OverlapAddFilter(int hopSize, int fftSize = 0) { _hopSize = hopSize; _fftSize = (fftSize > 0) ? fftSize : 8 * hopSize; _overlapSize = _fftSize - _hopSize; Guard.AgainstInvalidRange(_hopSize, _fftSize, "Hop size", "FFT size"); _fft = new RealFft(_fftSize); _window = Window.OfType(WindowType.Hann, _fftSize); _gain = 1 / (_fftSize * _window.Select(w => w * w).Sum() / _hopSize); _dl = new float[_fftSize]; _re = new float[_fftSize]; _im = new float[_fftSize]; _filteredRe = new float[_fftSize]; _filteredIm = new float[_fftSize]; _lastSaved = new float[_overlapSize]; _inOffset = _overlapSize; }
/// <summary> /// Constructor /// </summary> /// <param name="kernel"></param> /// <param name="fftSize"></param> public OlsBlockConvolver(IEnumerable <float> kernel, int fftSize) { _fftSize = MathUtils.NextPowerOfTwo(fftSize); if (kernel.Count() > _fftSize) { throw new ArgumentException("Kernel length must not exceed the size of FFT!"); } _fft = new RealFft(_fftSize); _kernel = kernel.ToArray(); _kernelSpectrumRe = _kernel.PadZeros(_fftSize); _kernelSpectrumIm = new float[_fftSize]; _convRe = new float[_fftSize]; _convIm = new float[_fftSize]; _blockRe = new float[_fftSize]; _blockIm = new float[_fftSize]; _lastSaved = new float[_kernel.Length - 1]; _fft.Direct(_kernelSpectrumRe, _kernelSpectrumRe, _kernelSpectrumIm); Reset(); }
/// <summary> /// Constructor /// </summary> /// <param name="options">Options</param> public SpectralFeaturesExtractor(MultiFeatureOptions options) : base(options) { var featureList = options.FeatureList; if (featureList == "all" || featureList == "full") { featureList = FeatureSet; } var features = featureList.Split(',', '+', '-', ';', ':') .Select(f => f.Trim().ToLower()) .ToList(); _parameters = options.Parameters; _extractors = features.Select <string, Func <float[], float[], float> >(feature => { switch (feature) { case "sc": case "centroid": return(Spectral.Centroid); case "ss": case "spread": return(Spectral.Spread); case "sfm": case "flatness": if (_parameters?.ContainsKey("minLevel") ?? false) { var minLevel = (float)_parameters["minLevel"]; return((spectrum, freqs) => Spectral.Flatness(spectrum, minLevel)); } else { return((spectrum, freqs) => Spectral.Flatness(spectrum)); } case "sn": case "noiseness": if (_parameters?.ContainsKey("noiseFrequency") ?? false) { var noiseFrequency = (float)_parameters["noiseFrequency"]; return((spectrum, freqs) => Spectral.Noiseness(spectrum, freqs, noiseFrequency)); } else { return((spectrum, freqs) => Spectral.Noiseness(spectrum, freqs)); } case "rolloff": if (_parameters?.ContainsKey("rolloffPercent") ?? false) { var rolloffPercent = (float)_parameters["rolloffPercent"]; return((spectrum, freqs) => Spectral.Rolloff(spectrum, freqs, rolloffPercent)); } else { return((spectrum, freqs) => Spectral.Rolloff(spectrum, freqs)); } case "crest": return((spectrum, freqs) => Spectral.Crest(spectrum)); case "entropy": case "ent": return((spectrum, freqs) => Spectral.Entropy(spectrum)); case "sd": case "decrease": return((spectrum, freqs) => Spectral.Decrease(spectrum)); case "c1": case "c2": case "c3": case "c4": case "c5": case "c6": return((spectrum, freqs) => Spectral.Contrast(spectrum, freqs, int.Parse(feature.Substring(1)))); default: return((spectrum, freqs) => 0); } }).ToList(); FeatureCount = features.Count; FeatureDescriptions = features; _blockSize = options.FftSize > FrameSize ? options.FftSize : MathUtils.NextPowerOfTwo(FrameSize); _fft = new RealFft(_blockSize); var frequencies = options.Frequencies; var resolution = (float)SamplingRate / _blockSize; if (frequencies == null) { _frequencies = Enumerable.Range(0, _blockSize / 2 + 1) .Select(f => f * resolution) .ToArray(); } else if (frequencies.Length == _blockSize / 2 + 1) { _frequencies = frequencies; } else { _frequencies = new float[frequencies.Length + 1]; frequencies.FastCopyTo(_frequencies, frequencies.Length, 0, 1); _mappedSpectrum = new float[_frequencies.Length]; _frequencyPositions = new int[_frequencies.Length]; for (var i = 1; i < _frequencies.Length; i++) { _frequencyPositions[i] = (int)(_frequencies[i] / resolution) + 1; } } _spectrum = new float[_blockSize / 2 + 1]; // buffer for magnitude spectrum }
/// <summary> /// Constructor /// </summary> /// <param name="samplingRate"></param> /// <param name="featureList"></param> /// <param name="frameDuration"></param> /// <param name="hopDuration"></param> /// <param name="fftSize"></param> /// <param name="parameters"></param> public SpectralFeaturesExtractor(int samplingRate, string featureList, double frameDuration = 0.0256 /*sec*/, double hopDuration = 0.010 /*sec*/, int fftSize = 0, float[] frequencies = null, double preEmphasis = 0, WindowTypes window = WindowTypes.Hamming, IReadOnlyDictionary <string, object> parameters = null) : base(samplingRate, frameDuration, hopDuration, preEmphasis) { if (featureList == "all" || featureList == "full") { featureList = FeatureSet; } var features = featureList.Split(',', '+', '-', ';', ':') .Select(f => f.Trim().ToLower()); _extractors = features.Select <string, Func <float[], float[], float> >(feature => { switch (feature) { case "sc": case "centroid": return(Spectral.Centroid); case "ss": case "spread": return(Spectral.Spread); case "sfm": case "flatness": if (parameters?.ContainsKey("minLevel") ?? false) { var minLevel = (float)parameters["minLevel"]; return((spectrum, freqs) => Spectral.Flatness(spectrum, minLevel)); } else { return((spectrum, freqs) => Spectral.Flatness(spectrum)); } case "sn": case "noiseness": if (parameters?.ContainsKey("noiseFrequency") ?? false) { var noiseFrequency = (float)parameters["noiseFrequency"]; return((spectrum, freqs) => Spectral.Noiseness(spectrum, freqs, noiseFrequency)); } else { return((spectrum, freqs) => Spectral.Noiseness(spectrum, freqs)); } case "rolloff": if (parameters?.ContainsKey("rolloffPercent") ?? false) { var rolloffPercent = (float)parameters["rolloffPercent"]; return((spectrum, freqs) => Spectral.Rolloff(spectrum, freqs, rolloffPercent)); } else { return((spectrum, freqs) => Spectral.Rolloff(spectrum, freqs)); } case "crest": return((spectrum, freqs) => Spectral.Crest(spectrum)); case "entropy": case "ent": return((spectrum, freqs) => Spectral.Entropy(spectrum)); case "sd": case "decrease": return((spectrum, freqs) => Spectral.Decrease(spectrum)); case "c1": case "c2": case "c3": case "c4": case "c5": case "c6": return((spectrum, freqs) => Spectral.Contrast(spectrum, freqs, int.Parse(feature.Substring(1)))); default: return((spectrum, freqs) => 0); } }).ToList(); FeatureDescriptions = features.ToList(); _blockSize = fftSize > FrameSize ? fftSize : MathUtils.NextPowerOfTwo(FrameSize); _fft = new RealFft(_blockSize); _window = window; _windowSamples = Window.OfType(_window, FrameSize); var resolution = (float)samplingRate / _blockSize; if (frequencies == null) { _frequencies = Enumerable.Range(0, _blockSize / 2 + 1) .Select(f => f * resolution) .ToArray(); } else if (frequencies.Length == _blockSize / 2 + 1) { _frequencies = frequencies; } else { _frequencies = new float[frequencies.Length + 1]; frequencies.FastCopyTo(_frequencies, frequencies.Length, 0, 1); _mappedSpectrum = new float[_frequencies.Length]; _frequencyPositions = new int[_frequencies.Length]; for (var i = 1; i < _frequencies.Length; i++) { _frequencyPositions[i] = (int)(_frequencies[i] / resolution) + 1; } } _parameters = parameters; _spectrum = new float[_blockSize / 2 + 1]; // buffer for magnitude spectrum }
/// <summary> /// Constructs extractor from configuration <paramref name="options"/>. /// </summary> public PlpExtractor(PlpOptions options) : base(options) { FeatureCount = options.FeatureCount; // ================================ Prepare filter bank and center frequencies: =========================================== var filterbankSize = options.FilterBankSize; if (options.FilterBank is null) { _blockSize = options.FftSize > FrameSize ? options.FftSize : MathUtils.NextPowerOfTwo(FrameSize); var low = options.LowFrequency; var high = options.HighFrequency; FilterBank = FilterBanks.BarkBankSlaney(filterbankSize, _blockSize, SamplingRate, low, high); var barkBands = FilterBanks.BarkBandsSlaney(filterbankSize, SamplingRate, low, high); _centerFrequencies = barkBands.Select(b => b.Item2).ToArray(); } else { FilterBank = options.FilterBank; filterbankSize = FilterBank.Length; _blockSize = 2 * (FilterBank[0].Length - 1); Guard.AgainstExceedance(FrameSize, _blockSize, "frame size", "FFT size"); if (options.CenterFrequencies != null) { _centerFrequencies = options.CenterFrequencies; } else { var herzResolution = (double)SamplingRate / _blockSize; // try to determine center frequencies automatically from filterbank weights: _centerFrequencies = new double[filterbankSize]; for (var i = 0; i < FilterBank.Length; i++) { var minPos = 0; var maxPos = _blockSize / 2; for (var j = 0; j < FilterBank[i].Length; j++) { if (FilterBank[i][j] > 0) { minPos = j; break; } } for (var j = minPos; j < FilterBank[i].Length; j++) { if (FilterBank[i][j] == 0) { maxPos = j; break; } } _centerFrequencies[i] = herzResolution * (maxPos + minPos) / 2; } } } // ==================================== Compute equal loudness curve: ========================================= _equalLoudnessCurve = new double[filterbankSize]; for (var i = 0; i < _centerFrequencies.Length; i++) { var level2 = _centerFrequencies[i] * _centerFrequencies[i]; _equalLoudnessCurve[i] = Math.Pow(level2 / (level2 + 1.6e5), 2) * ((level2 + 1.44e6) / (level2 + 9.61e6)); } // ============================== Prepare RASTA filters (if necessary): ======================================= _rasta = options.Rasta; if (_rasta > 0) { _rastaFilters = Enumerable.Range(0, filterbankSize) .Select(f => new RastaFilter(_rasta)) .ToArray(); } // ============== Precompute IDFT table for obtaining autocorrelation coeffs from power spectrum: ============= _lpcOrder = options.LpcOrder > 0 ? options.LpcOrder : FeatureCount - 1; _idftTable = new float[_lpcOrder + 1][]; var bandCount = filterbankSize + 2; // +2 duplicated edges var freq = Math.PI / (bandCount - 1); for (var i = 0; i < _idftTable.Length; i++) { _idftTable[i] = new float[bandCount]; _idftTable[i][0] = 1.0f; for (var j = 1; j < bandCount - 1; j++) { _idftTable[i][j] = 2 * (float)Math.Cos(freq * i * j); } _idftTable[i][bandCount - 1] = (float)Math.Cos(freq * i * (bandCount - 1)); } _lpc = new float[_lpcOrder + 1]; _cc = new float[bandCount]; // =================================== Prepare everything else: ============================== _fft = new RealFft(_blockSize); _lifterSize = options.LifterSize; _lifterCoeffs = _lifterSize > 0 ? Window.Liftering(FeatureCount, _lifterSize) : null; _includeEnergy = options.IncludeEnergy; _logEnergyFloor = options.LogEnergyFloor; _spectrum = new float[_blockSize / 2 + 1]; _bandSpectrum = new float[filterbankSize]; }
/// <summary> /// Constructor /// </summary> /// <param name="options">AMS options</param> public AmsExtractor(AmsOptions options) : base(options) { _modulationFftSize = options.ModulationFftSize; _modulationHopSize = options.ModulationHopSize; _modulationFft = new RealFft(_modulationFftSize); _featuregram = options.Featuregram?.ToArray(); if (_featuregram != null) { FeatureCount = _featuregram[0].Length * (_modulationFftSize / 2 + 1); } else { if (options.FilterBank == null) { _fftSize = options.FftSize > FrameSize ? options.FftSize : MathUtils.NextPowerOfTwo(FrameSize); _filterbank = FilterBanks.Triangular(_fftSize, SamplingRate, FilterBanks.MelBands(12, SamplingRate, 100, 3200)); } else { _filterbank = options.FilterBank; _fftSize = 2 * (_filterbank[0].Length - 1); Guard.AgainstExceedance(FrameSize, _fftSize, "frame size", "FFT size"); } _fft = new RealFft(_fftSize); FeatureCount = _filterbank.Length * (_modulationFftSize / 2 + 1); _spectrum = new float[_fftSize / 2 + 1]; _filteredSpectrum = new float[_filterbank.Length]; _block = new float[_fftSize]; } _modBlock = new float[_modulationFftSize]; _modSpectrum = new float[_modulationFftSize / 2 + 1]; // feature descriptions int length; if (_featuregram != null) { length = _featuregram[0].Length; } else { length = _filterbank.Length; } FeatureDescriptions = new List <string>(); var modulationSamplingRate = (float)SamplingRate / HopSize; var resolution = modulationSamplingRate / _modulationFftSize; for (var fi = 0; fi < length; fi++) { for (var fj = 0; fj <= _modulationFftSize / 2; fj++) { FeatureDescriptions.Add(string.Format("band_{0}_mf_{1:F2}_Hz", fi + 1, fj * resolution)); } } }