/// <summary> /// Method for computing LPCC features. /// It essentially duplicates LPC extractor code /// (for efficient memory usage it doesn't just delegate its work to LpcExtractor) /// and then post-processes LPC vectors to obtain LPCC coefficients. /// </summary> /// <param name="block">Samples for analysis</param> /// <param name="features">LPCC vector</param> public override void ProcessFrame(float[] block, float[] features) { block.FastCopyTo(_reversed, FrameSize); // 1) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 2) Levinson-Durbin for (int k = 0; k < _lpc.Length; _lpc[k] = 0, k++) { ; } var err = Lpc.LevinsonDurbin(_cc, _lpc, _order, FrameSize - 1); // 3) compute LPCC coefficients from LPC Lpc.ToCepstrum(_lpc, err, features); // 4) (optional) liftering if (_lifterCoeffs != null) { features.ApplyWindow(_lifterCoeffs); } }
/// <summary> /// Computes pitch in one frame. /// </summary> /// <param name="block">Block of data</param> /// <param name="features">Pitch (feature vector containing only pitch) computed in the block</param> public override void ProcessFrame(float[] block, float[] features) { block.FastCopyTo(_reversed, FrameSize); // 1) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 2) argmax of autocorrelation var pitch1 = (int)(SamplingRate / _high); // 2,5 ms = 400Hz var pitch2 = (int)(SamplingRate / _low); // 12,5 ms = 80Hz var start = pitch1 + FrameSize - 1; var end = Math.Min(start + pitch2, _cc.Length); var max = start < _cc.Length ? _cc[start] : 0; var peakIndex = start; for (var k = start; k < end; k++) { if (_cc[k] > max) { max = _cc[k]; peakIndex = k - FrameSize + 1; } } features[0] = max > 1.0f ? (float)SamplingRate / peakIndex : 0; }
/// <summary> /// Computes LPCC vector in one frame. /// </summary> /// <param name="block">Block of data</param> /// <param name="features">Features (one LPCC feature vector) computed in the block</param> public override void ProcessFrame(float[] block, float[] features) { // The code here essentially duplicates LPC extractor code // (for efficient memory usage it doesn't just delegate its work to LpcExtractor) // and then post-processes LPC vectors to obtain LPCC coefficients. block.FastCopyTo(_reversed, FrameSize); // 1) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 2) Levinson-Durbin for (int k = 0; k < _lpc.Length; _lpc[k] = 0, k++) { ; } var err = Lpc.LevinsonDurbin(_cc, _lpc, _order, FrameSize - 1); // 3) compute LPCC coefficients from LPC Lpc.ToCepstrum(_lpc, err, features); // 4) (optional) liftering if (_lifterCoeffs != null) { features.ApplyWindow(_lifterCoeffs); } }
/// <summary> /// Standard method for computing LPC vector. /// /// Note: /// The first LP coefficient is always equal to 1.0. /// This method replaces it with the value of prediction error. /// /// </summary> /// <param name="block">Samples for analysis</param> /// <param name="features">LPC vector</param> public override void ProcessFrame(float[] block, float[] features) { block.FastCopyTo(_reversed, FrameSize); // 1) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 2) levinson-durbin var err = Lpc.LevinsonDurbin(_cc, features, _order, FrameSize - 1); features[0] = err; }
/// <summary> /// Pitch tracking /// </summary> /// <param name="samples"></param> /// <returns></returns> public override List <FeatureVector> ComputeFrom(float[] samples, int startSample, int endSample) { Guard.AgainstInvalidRange(startSample, endSample, "starting pos", "ending pos"); var samplingRate = SamplingRate; var frameSize = FrameSize; var pitches = new List <FeatureVector>(); var pitch1 = (int)(samplingRate / _high); // 2,5 ms = 400Hz var pitch2 = (int)(samplingRate / _low); // 12,5 ms = 80Hz var i = startSample; while (i + frameSize < endSample) { samples.FastCopyTo(_block, frameSize, i); samples.FastCopyTo(_reversed, frameSize, i); _convolver.CrossCorrelate(_block, _reversed, _cc); var start = pitch1 + FrameSize - 1; var end = Math.Min(start + pitch2, _cc.Length); var max = start < _cc.Length ? _cc[start] : 0; var peakIndex = start; for (var k = start; k < end; k++) { if (_cc[k] > max) { max = _cc[k]; peakIndex = k - FrameSize + 1; } } var f0 = max > 1.0f ? (float)samplingRate / peakIndex : 0; pitches.Add(new FeatureVector { Features = new float[] { f0 }, TimePosition = (double)i / SamplingRate }); i += HopSize; } return(pitches); }
/// <summary> /// Position of the best found waveform similarity /// </summary> /// <param name="current"></param> /// <param name="prev"></param> /// <param name="maxDelta"></param> /// <returns></returns> public int WaveformSimilarityPos(float[] current, float[] prev, int maxDelta) { var optimalShift = 0; var maxCorrelation = 0.0f; // for small window sizes cross-correlate directly: if (_convolver == null) { for (var i = 0; i < maxDelta; i++) { var xcorr = 0.0f; for (var j = 0; j < prev.Length; j++) { xcorr += current[i + j] * prev[j]; } if (xcorr > maxCorrelation) { maxCorrelation = xcorr; optimalShift = i; } } } // for very large window sizes better use FFT convolution: else { _convolver.CrossCorrelate(current, prev, _cc); for (int i = prev.Length - 1, j = 0; i < prev.Length + _maxDelta - 1; i++, j++) { if (_cc[i] > maxCorrelation) { maxCorrelation = _cc[i]; optimalShift = j; } } } return(optimalShift); }
/// <summary> /// Pitch tracking /// </summary> /// <param name="block">Samples</param> /// <returns>Array of one element: pitch</returns> public override float[] ProcessFrame(float[] block) { // 1) apply window if (_window != WindowTypes.Rectangular) { block.ApplyWindow(_windowSamples); } block.FastCopyTo(_reversed, FrameSize); // 2) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 3) argmax of autocorrelation var pitch1 = (int)(SamplingRate / _high); // 2,5 ms = 400Hz var pitch2 = (int)(SamplingRate / _low); // 12,5 ms = 80Hz var start = pitch1 + FrameSize - 1; var end = Math.Min(start + pitch2, _cc.Length); var max = start < _cc.Length ? _cc[start] : 0; var peakIndex = start; for (var k = start; k < end; k++) { if (_cc[k] > max) { max = _cc[k]; peakIndex = k - FrameSize + 1; } } var f0 = max > 1.0f ? (float)SamplingRate / peakIndex : 0; return(new float[] { f0 }); }
/// <summary> /// Method for computing LPCC features. /// It essentially duplicates LPC extractor code /// (for efficient memory usage it doesn't just delegate its work to LpcExtractor) /// and then post-processes LPC vectors to obtain LPCC coefficients. /// </summary> /// <param name="block">Samples for analysis</param> /// <returns>LPCC vector</returns> public override float[] ProcessFrame(float[] block) { // 1) apply window (usually signal isn't windowed for LPC, so we check first) if (_window != WindowTypes.Rectangular) { block.ApplyWindow(_windowSamples); } block.FastCopyTo(_reversed, FrameSize); // 2) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 3) Levinson-Durbin for (int k = 0; k < _lpc.Length; _lpc[k] = 0, k++) { ; } var err = Lpc.LevinsonDurbin(_cc, _lpc, _order, FrameSize - 1); // 4) compute LPCC coefficients from LPC var lpcc = new float[FeatureCount]; Lpc.ToCepstrum(_lpc, err, lpcc); // 5) (optional) liftering if (_lifterCoeffs != null) { lpcc.ApplyWindow(_lifterCoeffs); } return(lpcc); }
/// <summary> /// Standard method for computing LPC vector. /// /// Note: /// The first LP coefficient is always equal to 1.0. /// This method replaces it with the value of prediction error. /// /// </summary> /// <param name="block">Samples for analysis</param> /// <returns>LPC vector</returns> public override float[] ProcessFrame(float[] block) { // 1) apply window (usually signal isn't windowed for LPC, so we check first) if (_window != WindowTypes.Rectangular) { block.ApplyWindow(_windowSamples); } block.FastCopyTo(_reversed, FrameSize); // 2) autocorrelation _convolver.CrossCorrelate(block, _reversed, _cc); // 3) levinson-durbin var lpc = new float[_order + 1]; var err = Lpc.LevinsonDurbin(_cc, lpc, _order, FrameSize - 1); lpc[0] = err; return(lpc); }
/// <summary> /// Standard method for computing LPC features. /// /// Note: /// The first LP coefficient is always equal to 1.0. /// This method replaces it with the value of prediction error. /// /// </summary> /// <param name="samples">Samples for analysis</param> /// <param name="startSample">The number (position) of the first sample for processing</param> /// <param name="endSample">The number (position) of last sample for processing</param> /// <returns>List of LPC vectors</returns> public override List <FeatureVector> ComputeFrom(float[] samples, int startSample, int endSample) { Guard.AgainstInvalidRange(startSample, endSample, "starting pos", "ending pos"); var frameSize = FrameSize; var hopSize = HopSize; var featureVectors = new List <FeatureVector>(); var prevSample = startSample > 0 ? samples[startSample - 1] : 0.0f; var lastSample = endSample - Math.Max(frameSize, hopSize); for (var i = startSample; i < lastSample; i += hopSize) { // prepare all blocks in memory for the current step: samples.FastCopyTo(_block, frameSize, i); // 0) pre-emphasis (if needed) if (_preEmphasis > 1e-10) { for (var k = 0; k < frameSize; k++) { var y = _block[k] - prevSample * _preEmphasis; prevSample = _block[k]; _block[k] = y; } prevSample = samples[i + hopSize - 1]; } // 1) apply window if (_window != WindowTypes.Rectangular) { _block.ApplyWindow(_windowSamples); } _block.FastCopyTo(_reversed, frameSize); // 2) autocorrelation _convolver.CrossCorrelate(_block, _reversed, _cc); // 3) levinson-durbin var a = new float[_order + 1]; var err = MathUtils.LevinsonDurbin(_cc, a, _order, frameSize - 1); a[0] = err; // add LPC vector to output sequence featureVectors.Add(new FeatureVector { Features = a, TimePosition = (double)i / SamplingRate }); } return(featureVectors); }
/// <summary> /// Method for computing LPCC features. /// It essentially duplicates LPC extractor code /// (for efficient memory usage it doesn't just delegate its work to LpcExtractor) /// and then post-processes LPC vectors to obtain LPCC coefficients. /// </summary> /// <param name="samples">Samples for analysis</param> /// <param name="startSample">The number (position) of the first sample for processing</param> /// <param name="endSample">The number (position) of last sample for processing</param> /// <returns></returns> public override List <FeatureVector> ComputeFrom(float[] samples, int startSample, int endSample) { Guard.AgainstInvalidRange(startSample, endSample, "starting pos", "ending pos"); var hopSize = HopSize; var frameSize = FrameSize; var featureVectors = new List <FeatureVector>(); var prevSample = startSample > 0 ? samples[startSample - 1] : 0.0f; var lastSample = endSample - Math.Max(frameSize, hopSize); for (var i = startSample; i < lastSample; i += hopSize) { // prepare all blocks in memory for the current step: samples.FastCopyTo(_block, frameSize, i); // 0) pre-emphasis (if needed) if (_preEmphasis > 1e-10) { for (var k = 0; k < frameSize; k++) { var y = _block[k] - prevSample * _preEmphasis; prevSample = _block[k]; _block[k] = y; } prevSample = samples[i + hopSize - 1]; } // 1) apply window if (_window != WindowTypes.Rectangular) { _block.ApplyWindow(_windowSamples); } _block.FastCopyTo(_reversed, frameSize); // 2) autocorrelation _convolver.CrossCorrelate(_block, _reversed, _cc); // 3) Levinson-Durbin for (int k = 0; k < _lpc.Length; k++) { _lpc[k] = 0; } var err = MathUtils.LevinsonDurbin(_cc, _lpc, _order, frameSize - 1); // 4) simple and efficient algorithm for obtaining LPCC coefficients from LPC var lpcc = new float[FeatureCount]; lpcc[0] = (float)Math.Log(err); for (var n = 1; n < FeatureCount; n++) { var acc = 0.0f; for (var k = 1; k < n; k++) { acc += k * lpcc[k] * _lpc[n - k]; } lpcc[n] = -_lpc[n] - acc / n; } // (optional) liftering if (_lifterCoeffs != null) { lpcc.ApplyWindow(_lifterCoeffs); } // add LPC vector to output sequence featureVectors.Add(new FeatureVector { Features = lpcc, TimePosition = (double)i / SamplingRate }); } return(featureVectors); }
/// <summary> /// Pitch tracking /// </summary> /// <param name="samples"></param> /// <returns></returns> public override List <FeatureVector> ComputeFrom(float[] samples, int startSample, int endSample) { Guard.AgainstInvalidRange(startSample, endSample, "starting pos", "ending pos"); var samplingRate = SamplingRate; var frameSize = FrameSize; var hopSize = HopSize; var pitches = new List <FeatureVector>(); var pitch1 = (int)(samplingRate / _high); // 2,5 ms = 400Hz var pitch2 = (int)(samplingRate / _low); // 12,5 ms = 80Hz var prevSample = startSample > 0 ? samples[startSample - 1] : 0.0f; var lastSample = endSample - Math.Max(frameSize, hopSize); for (var i = startSample; i < lastSample; i += hopSize) { // prepare all blocks in memory for the current step: samples.FastCopyTo(_block, frameSize, i); // 0) pre-emphasis (if needed) if (_preEmphasis > 1e-10) { for (var k = 0; k < frameSize; k++) { var y = _block[k] - prevSample * _preEmphasis; prevSample = _block[k]; _block[k] = y; } prevSample = samples[i + hopSize - 1]; } // 1) apply window if (_window != WindowTypes.Rectangular) { _block.ApplyWindow(_windowSamples); } _block.FastCopyTo(_reversed, frameSize); // 2) autocorrelation _convolver.CrossCorrelate(_block, _reversed, _cc); // 3) argmax of autocorrelation var start = pitch1 + FrameSize - 1; var end = Math.Min(start + pitch2, _cc.Length); var max = start < _cc.Length ? _cc[start] : 0; var peakIndex = start; for (var k = start; k < end; k++) { if (_cc[k] > max) { max = _cc[k]; peakIndex = k - FrameSize + 1; } } var f0 = max > 1.0f ? (float)samplingRate / peakIndex : 0; pitches.Add(new FeatureVector { Features = new float[] { f0 }, TimePosition = (double)i / SamplingRate }); } return(pitches); }