mirror of
https://github.com/DarthAffe/KeyboardAudioVisualizer.git
synced 2025-12-12 15:18:30 +00:00
Updated audio capturing to make use of the SingleBlockRead-event
This commit is contained in:
parent
4141a5dd36
commit
8f53049bdf
@ -1,4 +1,6 @@
|
|||||||
namespace KeyboardAudioVisualizer.AudioCapture
|
using System;
|
||||||
|
|
||||||
|
namespace KeyboardAudioVisualizer.AudioCapture
|
||||||
{
|
{
|
||||||
public class AudioBuffer
|
public class AudioBuffer
|
||||||
{
|
{
|
||||||
@ -29,64 +31,68 @@
|
|||||||
|
|
||||||
#region Methods
|
#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)
|
public void Put(float[] src, int offset, int count)
|
||||||
{
|
{
|
||||||
lock (_bufferLeft)
|
if ((count & 1) != 0) return; // we expect stereo-data to be an even amount of values
|
||||||
lock (_bufferRight)
|
|
||||||
|
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
|
_bufferLeft[_currentIndex] = src[offset + i] / Prescale.Value;
|
||||||
|
_bufferRight[_currentIndex] = src[offset + i + 1] / Prescale.Value;
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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)
|
public void CopyLeftInto(ref float[] data, int offset, int count)
|
||||||
{
|
{
|
||||||
lock (_bufferLeft)
|
int bufferOffset = _capacity - count;
|
||||||
for (int i = _capacity - count; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
data[offset + i] = _bufferLeft[(_currentIndex + i) % _capacity];
|
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)
|
public void CopyRightInto(ref float[] data, int offset, int count)
|
||||||
{
|
{
|
||||||
lock (_bufferRight)
|
int bufferOffset = _capacity - count;
|
||||||
for (int i = _capacity - count; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
data[offset + i] = _bufferRight[(_currentIndex + i) % _capacity];
|
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)
|
public void CopyMixInto(ref float[] data, int offset, int count)
|
||||||
{
|
{
|
||||||
lock (_bufferLeft)
|
int bufferOffset = _capacity - count;
|
||||||
lock (_bufferRight)
|
for (int i = 0; i < count; i++)
|
||||||
for (int i = _capacity - count; i < count; i++)
|
{
|
||||||
{
|
int index = (_currentIndex + (bufferOffset + i)) % _capacity;
|
||||||
int index = (_currentIndex + i) % _capacity;
|
data[offset + i] = (_bufferLeft[index] + _bufferRight[index]) / 2f;
|
||||||
data[offset + i] = (_bufferLeft[index] + _bufferRight[index]) / 2f;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -12,11 +12,10 @@ namespace KeyboardAudioVisualizer.AudioCapture
|
|||||||
|
|
||||||
private WasapiCapture _capture;
|
private WasapiCapture _capture;
|
||||||
private SoundInSource _soundInSource;
|
private SoundInSource _soundInSource;
|
||||||
|
private IWaveSource _source;
|
||||||
private SingleBlockNotificationStream _stream;
|
private SingleBlockNotificationStream _stream;
|
||||||
private AudioEndpointVolume _audioEndpointVolume;
|
private AudioEndpointVolume _audioEndpointVolume;
|
||||||
|
|
||||||
private readonly float[] _readBuffer = new float[2048];
|
|
||||||
|
|
||||||
public int SampleRate => _soundInSource?.WaveFormat?.SampleRate ?? -1;
|
public int SampleRate => _soundInSource?.WaveFormat?.SampleRate ?? -1;
|
||||||
public float MasterVolume => _audioEndpointVolume.MasterVolumeLevelScalar;
|
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
|
//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++)
|
for (int i = 1; i < 13; i++)
|
||||||
{
|
try { _capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i)); } catch { /* We're just trying ... */ }
|
||||||
try
|
|
||||||
{
|
|
||||||
_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_capture == null)
|
if (_capture == null)
|
||||||
throw new NullReferenceException("Failed to initialize WasapiLoopbackCapture");
|
throw new NullReferenceException("Failed to initialize WasapiLoopbackCapture");
|
||||||
|
|
||||||
_capture.Initialize();
|
_capture.Initialize();
|
||||||
|
|
||||||
_soundInSource = new SoundInSource(_capture) { FillWithZeros = false };
|
_soundInSource = new SoundInSource(_capture) { FillWithZeros = false };
|
||||||
|
_source = _soundInSource.WaveFormat.SampleRate == 44100
|
||||||
|
? _soundInSource.ToStereo()
|
||||||
|
: _soundInSource.ChangeSampleRate(44100).ToStereo();
|
||||||
|
|
||||||
_stream = _soundInSource.WaveFormat.SampleRate == 44100
|
_stream = new SingleBlockNotificationStream(_source.ToSampleSource());
|
||||||
? new SingleBlockNotificationStream(_soundInSource.ToStereo().ToSampleSource())
|
_stream.SingleBlockRead += StreamOnSingleBlockRead;
|
||||||
: new SingleBlockNotificationStream(_soundInSource.ChangeSampleRate(44100).ToStereo().ToSampleSource());
|
|
||||||
|
|
||||||
_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();
|
_capture.Start();
|
||||||
}
|
}
|
||||||
@ -68,12 +69,8 @@ namespace KeyboardAudioVisualizer.AudioCapture
|
|||||||
_capture?.Dispose();
|
_capture?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSoundDataAvailable(object sender, DataAvailableEventArgs dataAvailableEventArgs)
|
private void StreamOnSingleBlockRead(object sender, SingleBlockReadEventArgs singleBlockReadEventArgs)
|
||||||
{
|
=> DataAvailable?.Invoke(singleBlockReadEventArgs.Left, singleBlockReadEventArgs.Right);
|
||||||
int readCount;
|
|
||||||
while ((readCount = _stream.Read(_readBuffer, 0, _readBuffer.Length)) > 0)
|
|
||||||
DataAvailable?.Invoke(_readBuffer, 0, readCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace KeyboardAudioVisualizer.AudioCapture
|
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
|
public interface IAudioInput : IDisposable
|
||||||
{
|
{
|
||||||
|
|||||||
@ -54,7 +54,7 @@ namespace KeyboardAudioVisualizer.AudioProcessing
|
|||||||
_audioInput.Initialize();
|
_audioInput.Initialize();
|
||||||
|
|
||||||
_audioBuffer = new AudioBuffer(4096); // Working with ~93ms -
|
_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));
|
_processors.Add(new FourierSpectrumProvider(_audioBuffer));
|
||||||
|
|
||||||
|
|||||||
@ -80,9 +80,9 @@ namespace KeyboardAudioVisualizer.AudioProcessing.VisualizationProvider
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_sampleDataLeft = new float[_audioBuffer.Size];
|
_sampleDataLeft = new float[2048];
|
||||||
_sampleDataRight = new float[_audioBuffer.Size];
|
_sampleDataRight = new float[2048];
|
||||||
_sampleDataMix = new float[_audioBuffer.Size];
|
_sampleDataMix = new float[2048];
|
||||||
|
|
||||||
RecalculateConfigValues(null);
|
RecalculateConfigValues(null);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user