private void AnalyzeWaveform(AudioSampleData[] data, double sampleTime) { double lVal = 0, rVal = 0; double[][] dataWaveform = new double[2][]; dataWaveform[0] = new double[data.Length]; dataWaveform[1] = new double[data.Length]; int i = 0; for (i = 0; i < data.Length; i++) { double absL = Math.Abs(data[i].LVOL); double absR = Math.Abs(data[i].RVOL); if (lVal < absL) { lVal = absL; } if (rVal < absR) { rVal = absR; } dataWaveform[0][i] = data[i].LVOL; dataWaveform[1][i] = data[i].RVOL; if (i % 32 == 0) { lock (_vuLock) { _vuMeterData = new AudioSampleData( lVal / _maxLevel, rVal / _maxLevel); } lVal = rVal = 0; } } lock (_waveformLock) { _waveformData = dataWaveform; } }
void _tmrUpdate_Tick(object sender, EventArgs e) { try { _tmrUpdate.Stop(); if (ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.VUMeter)) { AudioSampleData vuData = MediaRenderer.DefaultInstance.VuMeterData; if (vuData != null) { vuLeft.Value = 0.5 * (vuLeft.Value + vuLeft.Maximum * vuData.LVOL); vuRight.Value = 0.5 * (vuRight.Value + vuRight.Maximum * vuData.RVOL); } else { vuLeft.Value = 0; vuRight.Value = 0; } } if (ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.Waveform)) { gpWaveform.Reset(false); double[][] waveformData = MediaRenderer.DefaultInstance.WaveformData; if (waveformData != null && waveformData[0].Length > 0) { if (_prevWaveform == null) { _prevWaveform = new double[waveformData[0].Length]; } for (int k = 0; k < _prevWaveform.Length; k++) { _prevWaveform[k] = 0.5 * (_prevWaveform[k] + waveformData[0][k]); } gpWaveform.MinVal = -1 * MediaRenderer.DefaultInstance.MaxLevel; gpWaveform.MaxVal = MediaRenderer.DefaultInstance.MaxLevel; gpWaveform.AddDataRange(_prevWaveform, ThemeManager.GradientGaugeColor1); } else { gpWaveform.Reset(true); } } if (ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.Spectrogram)) { double maxFftLevel = SpectrogramTransferFunction(MediaRenderer.DefaultInstance.MaxFFTLevel); spSpectrogram.Reset(false); spSpectrogram.MinVal = maxFftLevel / 2; // Min level = -6 dBM spSpectrogram.MaxVal = maxFftLevel; // Max level = 0 dBM double[] spectrogramData = MediaRenderer.DefaultInstance.SpectrogramData; if (spectrogramData != null && spectrogramData.Length > 0) { double[] spectrogramData2 = new double[spectrogramData.Length]; Array.Clear(spectrogramData2, 0, spectrogramData.Length); double[] bands = new double[BandCount]; Array.Clear(bands, 0, BandCount); int jBand = 0; int div = spectrogramData.Length / (BandCount); try { int maxSize = (int)Math.Min(BandCount, spectrogramData.Length); for (int i = 0; i < maxSize; i++) { bands[i] = Math.Max(0, Math.Min(maxFftLevel, SpectrogramTransferFunction(spectrogramData[i]))); _bands[i] = 0.5 * (_bands[i] + bands[i]); } spSpectrogram.AddDataRange(_bands, Color.Transparent); } catch (Exception ex) { string s = ex.Message; spSpectrogram.Reset(true); Array.Clear(_bands, 0, _bands.Length); } } else { spSpectrogram.Reset(true); Array.Clear(_bands, 0, _bands.Length); } } } finally { _tmrUpdate.Start(); } }
private void AnalyzeFFT(AudioSampleData[] data) { if (data.Length == _fftWindowSize) { double[] dataIn = new double[data.Length]; double[] dataOut = new double[data.Length]; for (int i = 0; i < data.Length; i++) dataIn[i] = data[i].RmsLevel; FFT.Forward(dataIn, dataOut); lock (_spectrogramLock) { _spectrogramData = dataOut .Skip(1 /* First band represents the 'total energy' of the signal */ ) .Take(_fftWindowSize / 2 /* The spectrum is 'mirrored' horizontally around the sample rate / 2 according to Nyquist theorem */ ) .ToArray(); } } }
private void AnalyzeWaveform(AudioSampleData[] data, double sampleTime) { double lVal = 0, rVal = 0; double[] dataWaveform = new double[data.Length]; int i = 0; for (i = 0; i < data.Length; i++) { double absL = Math.Abs(data[i].LVOL); double absR = Math.Abs(data[i].RVOL); if (lVal < absL) lVal = absL; if (rVal < absR) rVal = absR; dataWaveform[i] = data[i].AvgLevel; if (i % 32 == 0) { lock (_vuLock) { _vuMeterData = new AudioSampleData( lVal / _maxLevel, rVal / _maxLevel); } lVal = rVal = 0; } } lock (_waveformLock) { _waveformData = dataWaveform; } }
private void ExtractSamples(AudioSample smp) { if (smp == null || _actualAudioFormat == null || mediaPosition == null) { return; } double mediaTime = 0; mediaPosition.get_CurrentPosition(out mediaTime); double delay = smp.SampleTime - mediaTime; double absDelay = Math.Abs(delay); // Discard samples too far in time from current media time if (absDelay > 1) { return; } //CalculateAverageDelay(delay * 1000); if (delay > 0) { Thread.Sleep(TimeSpan.FromSeconds(delay)); } FilterState ms = GetFilterState(); if (smp.RawSamples.Length <= 0 || ms != FilterState.Running || _actualAudioFormat == null) { return; } int bytesPerChannel = _actualAudioFormat.wBitsPerSample / 8; int totalChannels = _actualAudioFormat.nChannels; int totalChannelsInArray = Math.Min(2, totalChannels); int i = 0; while (i < smp.RawSamples.Length) { double[] channels = new double[totalChannelsInArray]; Array.Clear(channels, 0, totalChannelsInArray); int j = 0; while (j < totalChannelsInArray) { int k = 0; while (k < bytesPerChannel) { if (bytesPerChannel <= 2) { channels[j] += (short)(smp.RawSamples[i] << (8 * k)); } else { channels[j] += (int)(smp.RawSamples[i] << (8 * k)); } i++; k++; } j++; } if (channels.Length >= 2) { _sampleData.Enqueue(new AudioSampleData((double)channels[0], (double)channels[1])); } else { _sampleData.Enqueue(new AudioSampleData((double)channels[0], 0)); } _gatheredSamples++; if (_gatheredSamples % _waveformWindowSize == 0) { if (ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.VUMeter) || ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.Waveform) || ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.WCFInterface)) { AnalyzeWaveform(_sampleData.Skip(_sampleData.Count - _waveformWindowSize).Take(_waveformWindowSize).ToArray(), smp.SampleTime); } } Thread.Yield(); } AudioSampleData lostSample = null; while (_sampleData.Count > _fftWindowSize) { _sampleData.TryDequeue(out lostSample); } if (ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.Spectrogram) || ProTONEConfig.SignalAnalisysFunctionActive(SignalAnalisysFunction.WCFInterface)) { AnalyzeFFT(_sampleData.ToArray()); } Thread.Yield(); }