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); }
// Update chart of frequency domain private void UpdateSpectra() { var fftSize = int.Parse(fftSizeTextBox.Text); var cepstrumSize = int.Parse(cepstrumSizeTextBox.Text); _hopSize = int.Parse(hopSizeTextBox.Text); if (fftSize != _fftSize) { _fftSize = fftSize; _fft = new Fft(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 = _cepstralTransform.Direct(block); var real = new float[_fftSize]; var imag = new float[_fftSize]; for (var i = 0; i < 32; i++) { real[i] = cepstrum[i]; } _fft.Direct(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 / _fftSize - avg)) .ToArray(); spectrumPanel.Line = spectrum; spectrumPanel.Markline = spectrumEstimate; spectrumPanel.ToDecibel(); spectrumPanel.max_freq_value = spectrum.Length * _signal.SamplingRate / fftSize; }
public void TestInverseComplexCepstrum() { var ct = new CepstralTransform(8); var input = new[] { 1, 7, 2, 100, 59, 32, 11, 72f }; var output = new float[8]; var cepstrum = new float[8]; var d = ct.Direct(input, output); ct.Inverse(output, cepstrum, d); Assert.That(cepstrum, Is.EqualTo(input).Within(1e-4)); }
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> /// Pitch estimation from signal cepstrum /// </summary> /// <param name="signal"></param> /// <param name="startPos"></param> /// <param name="endPos"></param> /// <param name="low"></param> /// <param name="high"></param> /// <param name="cepstrumSize"></param> /// <param name="fftSize"></param> /// <returns></returns> public static float FromCepstrum(DiscreteSignal signal, int startPos = 0, int endPos = -1, float low = 80, float high = 400, int cepstrumSize = 256, int fftSize = 1024) { var samplingRate = signal.SamplingRate; if (endPos == -1) { endPos = signal.Length; } if (startPos != 0 || endPos != signal.Length) { signal = signal[startPos, endPos]; } var pitch1 = (int)(1.0 * samplingRate / high); // 2,5 ms = 400Hz var pitch2 = Math.Min(cepstrumSize - 1, (int)(1.0 * samplingRate / low)); // 12,5 ms = 80Hz var cepstrum = new float[cepstrumSize]; var cepstralTransform = new CepstralTransform(cepstrumSize, fftSize); cepstralTransform.RealCepstrum(signal.Samples, cepstrum); var max = cepstrum[pitch1]; var peakIndex = pitch1; for (var k = pitch1 + 1; k <= pitch2; k++) { if (cepstrum[k] > max) { max = cepstrum[k]; peakIndex = k; } } return((float)samplingRate / peakIndex); }
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 Fft(_fftSize); _cepstralTransform = new CepstralTransform(_cepstrumSize, _fftSize); var pitchTracker = new Pitch((float)_fftSize / _signal.SamplingRate, (float)_hopSize / _signal.SamplingRate); _pitchTrack = pitchTracker.Track(_signal); UpdateSpectra(); UpdateAutoCorrelation(); // obtain spectrogram _stft = new Stft(_fftSize, _hopSize, WindowTypes.Rectangular); var spectrogram = _stft.Spectrogram(_signal); spectrogramPanel.ColorMapName = "viridis"; spectrogramPanel.Spectrogram = spectrogram.Select(s => s.Take(224).ToArray()).ToList(); spectrogramPanel.Markline = _pitchTrack.Select(p => p * _fftSize / _signal.SamplingRate).ToArray(); specNoComboBox.DataSource = Enumerable.Range(1, _pitchTrack.Count).ToArray(); _specNo = 0; }
// Open file private void openToolStripMenuItem_Click(object sender, EventArgs e) { spectrumPanel.refresh(); signalPanel.refresh(); signalPanel.Stride = 64; var ofd = new OpenFileDialog(); if (ofd.ShowDialog() != DialogResult.OK) { return; } txtFilePath.Text = ofd.FileName; _waveFileName = ofd.FileName; try { using (var stream = new FileStream(_waveFileName, FileMode.Open)) { IAudioContainer waveFile = new WaveFile(stream); _signal = waveFile[Channels.Left]; _signal_storage = _signal; } } catch (IOException ex) { Console.WriteLine("Error reading from {0}. Message = {1}", _waveFileName, ex.Message); } // Get duration WaveFileReader wf = new WaveFileReader(_waveFileName); var totalTime = wf.TotalTime; txtTotalTime.Text = totalTime.TotalMilliseconds.ToString() + " ms"; signalPanel.max_time_value = (float)totalTime.TotalMilliseconds; var max_value = _signal[0]; var count = 0; for (int i = 1; i < _signal.Length; i++) { if (max_value < _signal[i]) { max_value = _signal[i]; } if (_signal[i] > 0.2) { count++; } } txtMaxValue.Text = max_value.ToString(); signalPanel.Signal = _signal; _fftSize = int.Parse(fftSizeTextBox.Text); _cepstrumSize = int.Parse(cepstrumSizeTextBox.Text); _hopSize = int.Parse(hopSizeTextBox.Text); _fft = new Fft(_fftSize); _cepstralTransform = new CepstralTransform(_cepstrumSize, _fftSize); var pitchTracker = new Pitch((float)_fftSize / _signal.SamplingRate, (float)_hopSize / _signal.SamplingRate); _pitchTrack = pitchTracker.Track(_signal); // Show chart in frequency domain UpdateAutoCorrelation(); UpdateSpectra(); // obtain spectrogram _stft = new Stft(_fftSize, _hopSize, WindowTypes.Rectangular); var spectrogram = _stft.Spectrogram(_signal); specNoComboBox.DataSource = Enumerable.Range(1, _pitchTrack.Count).ToArray(); _specNo = 0; spectrumPanelAfterFilter.refresh(); signalPanelAfterFilter.refresh(); lblNote.Visible = false; savePWMDataToolStripMenuItem.Enabled = true; }