public AudioSampleHistoryBuffer(float bufferTime) { size = (int)(bufferTime * WaveOutput.InternalFormat.SampleRate); AudioEngine.Log($"AudioSampleHistoryBuffer: Create buffer for {bufferTime}s -> {size} samples"); buffer = new float[size]; }
public void Dispose() { AudioEngine.Log($"AudioSampleBuffer({GetHashCode()}): Disposed "); Processor = null; }
public AudioSampleBuffer(WaveFormat format) { AudioEngine.Log($"AudioSampleBuffer({GetHashCode()}): Created {format}"); WaveFormat = format; }
public void Update(WaveOutputDevice device, AudioSampleBuffer input, out string status, out WaveFormat waveFormat, out int latency, out float cpuUsage, out int bufferUnderRuns, int sampleRate = 44100, int driverLatency = 200, int internalLatency = 300, int bufferSize = 512, bool reset = false) { bool hasDeviceChanged = device?.Value != Device?.Value || sampleRate != SampleRate || driverLatency != DriverLatency || bufferSize != BufferSize || reset; Device = device; Input = input; SampleRate = sampleRate; InternalLatency = internalLatency; DriverLatency = driverLatency; BufferSize = bufferSize; if (hasDeviceChanged) { processor?.Dispose(); processor = null; if (waveOut != null) { AudioEngine.Log("Stopping WaveOut..."); waveOut.Stop(); waveOut.Dispose(); } } if (processor == null) { processor = new AudioThread.AudioThreadProcessor(BufferSize); } processor.EnsureThreadIsRunning(); processor.RequestedLatency = InternalLatency; if (hasDeviceChanged) { InternalFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, 2); SingleChannelFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, 1); processor.WaveFormat = InternalFormat; if (device != null) { AudioEngine.Log( $"WaveOutput: Configuration changed, device={device.Value}, sampleRate={sampleRate}, latency={InternalLatency} {HotSwapped} "); try { waveOut = ((IWaveOutputFactory)device.Tag).Create(DriverLatency); var wave16 = new SampleToWaveProvider16(processor); waveOut.Init(wave16); waveOut.Play(); AudioEngine.Log("WaveOutput: Started"); OutputFormat = wave16.WaveFormat; } catch (Exception e) { AudioEngine.Log(e); waveOut = null; } } } processor.Input = Input; status = waveOut != null?waveOut.PlaybackState.ToString() : "Uninitialized"; waveFormat = OutputFormat; latency = processor.Latency; cpuUsage = processor.CpuUsage; bufferUnderRuns = processor.BufferUnderRuns; }
public AudioSampleBuffer Update(WaveInputDevice device, out string status, out WaveFormat waveFormat, out int latency, out float cpuUsage, out int bufferUnderRuns, int driverLatency = 150, int internalLatency = 8, int bufferSize = 512, bool reset = false) { bool hasDeviceChanged = Device?.Value != device?.Value || DriverLatency != driverLatency || BufferSize != bufferSize || reset; Device = device; DriverLatency = driverLatency; InternalLatency = internalLatency; BufferSize = bufferSize; if (hasDeviceChanged) { processor?.Dispose(); processor = null; if (waveIn != null) { AudioEngine.Log("Stopping WaveIn..."); waveIn.StopRecording(); waveIn.Dispose(); } } if (processor == null) { processor = new AudioThread.AudioThreadProcessor(bufferSize); } processor.EnsureThreadIsRunning(); processor.RequestedLatency = internalLatency; if (hasDeviceChanged) { if (device != null) { AudioEngine.Log( $"WaveInput: Configuration changed, device={device.Value}, requested latency={DriverLatency}"); try { waveIn = ((IWaveInputFactory)device.Tag).Create(DriverLatency); bufferedWave = new BufferedWaveProvider(waveIn.WaveFormat); bufferedWave.DiscardOnBufferOverflow = true; sampleProvider = new WaveToSampleProvider(bufferedWave); OutputFormat = sampleProvider.WaveFormat; processor.WaveFormat = OutputFormat; processor.Input = sampleProvider; waveIn.DataAvailable += (s, a) => { bufferedWave.AddSamples(a.Buffer, 0, a.BytesRecorded); }; waveIn.StartRecording(); AudioEngine.Log("WaveInput: Started"); output = new AudioSampleBuffer(OutputFormat) { Processor = processor }; } catch (Exception e) { AudioEngine.Log(e); waveIn = null; } } } status = waveIn != null ? "Recording" : "Uninitialized"; waveFormat = OutputFormat; latency = processor.Latency; cpuUsage = processor.CpuUsage; bufferUnderRuns = processor.BufferUnderRuns; return(output); }
private void RunInThread() { float[] buffer = new float[bufferSize]; var stopWatch = Stopwatch.StartNew(); var clock = Stopwatch.StartNew(); var lastElapsed = 0.0; AudioEngine.Log($"Starting AudioThread {GetHashCode()}..."); try { while (Running) { if (playBuffer.IsValid && Input != null) { if (playBuffer.BufferedDuration.Milliseconds < RequestedLatency) { try { stopWatch.Stop(); var idleTime = stopWatch.ElapsedTicks; stopWatch.Restart(); while (playBuffer.BufferedDuration.Milliseconds < RequestedLatency) { Input?.Read(buffer, 0, buffer.Length); playBuffer.AddSamples(buffer, 0, buffer.Length); } Latency = playBuffer.BufferedDuration.Milliseconds; stopWatch.Stop(); var calcTime = stopWatch.ElapsedTicks; stopWatch.Restart(); CpuUsage = (float)calcTime / (idleTime + calcTime); } catch (Exception e) { AudioEngine.Log(e); } } else { if (RunWithoutOutput) { var elapsed = clock.Elapsed.TotalSeconds; var delta = elapsed - lastElapsed; lastElapsed = elapsed; playBuffer.Advance(TimeSpan.FromSeconds(delta)); Thread.Sleep(RequestedLatency); } } } else { Thread.Sleep(100); } } } catch (Exception e) { AudioEngine.Log(e); } AudioEngine.Log($"AudioThread {GetHashCode()} terminated"); }