diff --git a/KeyboardAudioVisualizer/AudioCapture/AudioBuffer.cs b/KeyboardAudioVisualizer/AudioCapture/AudioBuffer.cs index cd67816..b0f93cd 100644 --- a/KeyboardAudioVisualizer/AudioCapture/AudioBuffer.cs +++ b/KeyboardAudioVisualizer/AudioCapture/AudioBuffer.cs @@ -1,4 +1,6 @@ -namespace KeyboardAudioVisualizer.AudioCapture +using System; + +namespace KeyboardAudioVisualizer.AudioCapture { public class AudioBuffer { @@ -29,64 +31,68 @@ #region Methods + public void Put(float left, float right) + { + _currentIndex++; + if (_currentIndex >= _capacity) _currentIndex = 0; + + _bufferLeft[_currentIndex] = left; + _bufferRight[_currentIndex] = right; + } + public void Put(float[] src, int offset, int count) { - lock (_bufferLeft) - lock (_bufferRight) + if ((count & 1) != 0) return; // we expect stereo-data to be an even amount of values + + if (count > _capacity) + { + offset += count - _capacity; + count = _capacity; + } + + for (int i = 0; i < count; i += 2) + { + _currentIndex++; + if (_currentIndex >= _capacity) _currentIndex = 0; + + if (Prescale.HasValue) { - if ((count & 1) != 0) return; // we expect stereo-data to be an even amount of values - - if (count > _capacity) - { - offset += count - _capacity; - count = _capacity; - } - - for (int i = 0; i < count; i += 2) - { - _currentIndex++; - if (_currentIndex >= _capacity) _currentIndex = 0; - - if (Prescale.HasValue) - { - _bufferLeft[_currentIndex] = src[offset + i] / Prescale.Value; - _bufferRight[_currentIndex] = src[offset + i + 1] / Prescale.Value; - } - else - { - _bufferLeft[_currentIndex] = src[offset + i]; - _bufferRight[_currentIndex] = src[offset + i + 1]; - } - } + _bufferLeft[_currentIndex] = src[offset + i] / Prescale.Value; + _bufferRight[_currentIndex] = src[offset + i + 1] / Prescale.Value; } + else + { + _bufferLeft[_currentIndex] = src[offset + i]; + _bufferRight[_currentIndex] = src[offset + i + 1]; + } + } } - public void CopyLeftInto(ref float[] data, int offset) => CopyLeftInto(ref data, offset, _capacity); + public void CopyLeftInto(ref float[] data, int offset) => CopyLeftInto(ref data, offset, Math.Min(data.Length, _capacity)); public void CopyLeftInto(ref float[] data, int offset, int count) { - lock (_bufferLeft) - for (int i = _capacity - count; i < count; i++) - data[offset + i] = _bufferLeft[(_currentIndex + i) % _capacity]; + int bufferOffset = _capacity - count; + for (int i = 0; i < count; i++) + data[offset + i] = _bufferLeft[(_currentIndex + (bufferOffset + i)) % _capacity]; } - public void CopyRightInto(ref float[] data, int offset) => CopyRightInto(ref data, offset, _capacity); + public void CopyRightInto(ref float[] data, int offset) => CopyRightInto(ref data, offset, Math.Min(data.Length, _capacity)); public void CopyRightInto(ref float[] data, int offset, int count) { - lock (_bufferRight) - for (int i = _capacity - count; i < count; i++) - data[offset + i] = _bufferRight[(_currentIndex + i) % _capacity]; + int bufferOffset = _capacity - count; + for (int i = 0; i < count; i++) + data[offset + i] = _bufferRight[(_currentIndex + (bufferOffset + i)) % _capacity]; } - public void CopyMixInto(ref float[] data, int offset) => CopyMixInto(ref data, offset, _capacity); + public void CopyMixInto(ref float[] data, int offset) => CopyMixInto(ref data, offset, Math.Min(data.Length, _capacity)); public void CopyMixInto(ref float[] data, int offset, int count) { - lock (_bufferLeft) - lock (_bufferRight) - for (int i = _capacity - count; i < count; i++) - { - int index = (_currentIndex + i) % _capacity; - data[offset + i] = (_bufferLeft[index] + _bufferRight[index]) / 2f; - } + int bufferOffset = _capacity - count; + for (int i = 0; i < count; i++) + { + int index = (_currentIndex + (bufferOffset + i)) % _capacity; + data[offset + i] = (_bufferLeft[index] + _bufferRight[index]) / 2f; + } } #endregion diff --git a/KeyboardAudioVisualizer/AudioCapture/CSCoreAudioInput.cs b/KeyboardAudioVisualizer/AudioCapture/CSCoreAudioInput.cs index 04abb58..c17fd62 100644 --- a/KeyboardAudioVisualizer/AudioCapture/CSCoreAudioInput.cs +++ b/KeyboardAudioVisualizer/AudioCapture/CSCoreAudioInput.cs @@ -12,11 +12,10 @@ namespace KeyboardAudioVisualizer.AudioCapture private WasapiCapture _capture; private SoundInSource _soundInSource; + private IWaveSource _source; private SingleBlockNotificationStream _stream; private AudioEndpointVolume _audioEndpointVolume; - private readonly float[] _readBuffer = new float[2048]; - public int SampleRate => _soundInSource?.WaveFormat?.SampleRate ?? -1; public float MasterVolume => _audioEndpointVolume.MasterVolumeLevelScalar; @@ -38,26 +37,28 @@ namespace KeyboardAudioVisualizer.AudioCapture //DarthAffe 07.02.2018: This is a really stupid workaround to (hopefully) finally fix the surround driver issues for (int i = 1; i < 13; i++) - { - try - { - _capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i)); - } - catch - { } - } + try { _capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i)); } catch { /* We're just trying ... */ } if (_capture == null) throw new NullReferenceException("Failed to initialize WasapiLoopbackCapture"); _capture.Initialize(); + _soundInSource = new SoundInSource(_capture) { FillWithZeros = false }; + _source = _soundInSource.WaveFormat.SampleRate == 44100 + ? _soundInSource.ToStereo() + : _soundInSource.ChangeSampleRate(44100).ToStereo(); - _stream = _soundInSource.WaveFormat.SampleRate == 44100 - ? new SingleBlockNotificationStream(_soundInSource.ToStereo().ToSampleSource()) - : new SingleBlockNotificationStream(_soundInSource.ChangeSampleRate(44100).ToStereo().ToSampleSource()); + _stream = new SingleBlockNotificationStream(_source.ToSampleSource()); + _stream.SingleBlockRead += StreamOnSingleBlockRead; - _soundInSource.DataAvailable += OnSoundDataAvailable; + _source = _stream.ToWaveSource(); + + byte[] buffer = new byte[_source.WaveFormat.BytesPerSecond / 2]; + _soundInSource.DataAvailable += (s, aEvent) => + { + while ((_source.Read(buffer, 0, buffer.Length)) > 0) ; + }; _capture.Start(); } @@ -68,12 +69,8 @@ namespace KeyboardAudioVisualizer.AudioCapture _capture?.Dispose(); } - private void OnSoundDataAvailable(object sender, DataAvailableEventArgs dataAvailableEventArgs) - { - int readCount; - while ((readCount = _stream.Read(_readBuffer, 0, _readBuffer.Length)) > 0) - DataAvailable?.Invoke(_readBuffer, 0, readCount); - } + private void StreamOnSingleBlockRead(object sender, SingleBlockReadEventArgs singleBlockReadEventArgs) + => DataAvailable?.Invoke(singleBlockReadEventArgs.Left, singleBlockReadEventArgs.Right); #endregion } diff --git a/KeyboardAudioVisualizer/AudioCapture/IAudioInput.cs b/KeyboardAudioVisualizer/AudioCapture/IAudioInput.cs index ea3b5c9..8fcda9b 100644 --- a/KeyboardAudioVisualizer/AudioCapture/IAudioInput.cs +++ b/KeyboardAudioVisualizer/AudioCapture/IAudioInput.cs @@ -2,7 +2,7 @@ namespace KeyboardAudioVisualizer.AudioCapture { - public delegate void AudioData(float[] data, int offset, int count); + public delegate void AudioData(float left, float right); public interface IAudioInput : IDisposable { diff --git a/KeyboardAudioVisualizer/AudioProcessing/AudioVisualizationFactory.cs b/KeyboardAudioVisualizer/AudioProcessing/AudioVisualizationFactory.cs index fba8aa7..b97c3d0 100644 --- a/KeyboardAudioVisualizer/AudioProcessing/AudioVisualizationFactory.cs +++ b/KeyboardAudioVisualizer/AudioProcessing/AudioVisualizationFactory.cs @@ -54,7 +54,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing _audioInput.Initialize(); _audioBuffer = new AudioBuffer(4096); // Working with ~93ms - - _audioInput.DataAvailable += (data, offset, count) => _audioBuffer.Put(data, offset, count); + _audioInput.DataAvailable += (left, right) => _audioBuffer.Put(left, right); _processors.Add(new FourierSpectrumProvider(_audioBuffer)); diff --git a/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs b/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs index 4c62f33..b05200c 100644 --- a/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs +++ b/KeyboardAudioVisualizer/AudioProcessing/VisualizationProvider/LevelVisualizationProvider.cs @@ -80,9 +80,9 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider public override void Initialize() { - _sampleDataLeft = new float[_audioBuffer.Size]; - _sampleDataRight = new float[_audioBuffer.Size]; - _sampleDataMix = new float[_audioBuffer.Size]; + _sampleDataLeft = new float[2048]; + _sampleDataRight = new float[2048]; + _sampleDataMix = new float[2048]; RecalculateConfigValues(null); }