using NAudio.Wave; using Core.Interfaces; using System; using System.Threading; namespace Desktop { public class BeeperDevice : IAudioDevice { private WaveOutEvent _waveOut; private BufferedWaveProvider _buffer; // Audio Filtering private float _lastSample = 0.0f; private float _lastFiltered = 0.0f; // AY-3-8912 Digital Oscillators (Phase Trackers) private float _phaseA = 0f; private float _phaseB = 0f; private float _phaseC = 0f; public BeeperDevice() { _waveOut = new WaveOutEvent(); _waveOut.DesiredLatency = 50; // 44.1kHz, 1 channel (Mono), Float format _buffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 1)); _buffer.BufferDuration = TimeSpan.FromSeconds(1); _buffer.DiscardOnBufferOverflow = true; _waveOut.Init(_buffer); _waveOut.Play(); } public void AddSample(bool isHigh, float freqA, float volA, float freqB, float volB, float freqC, float volC) { // Buffer overrun check while (_buffer.BufferedDuration.TotalMilliseconds > 80) { Thread.Sleep(1); } // 1. The Beeper (Reduced base volume from 0.2 to 0.1 to make headroom for the AY) float beeper = isHigh ? 0.1f : -0.1f; // 2. Channel A Oscillator float ayA = 0f; if (freqA > 0) { _phaseA += freqA / 44100f; if (_phaseA > 1f) _phaseA -= 1f; // Wrap around ayA = (_phaseA < 0.5f ? 0.1f : -0.1f) * volA; } // 3. Channel B Oscillator float ayB = 0f; if (freqB > 0) { _phaseB += freqB / 44100f; if (_phaseB > 1f) _phaseB -= 1f; ayB = (_phaseB < 0.5f ? 0.1f : -0.1f) * volB; } // 4. Channel C Oscillator float ayC = 0f; if (freqC > 0) { _phaseC += freqC / 44100f; if (_phaseC > 1f) _phaseC -= 1f; ayC = (_phaseC < 0.5f ? 0.1f : -0.1f) * volC; } // Mix them all together! float rawSample = beeper + ayA + ayB + ayC; // Pass the mixed sound wave through your existing High-Pass filter to stop popping float filteredSample = rawSample - _lastSample + 0.995f * _lastFiltered; _lastSample = rawSample; _lastFiltered = filteredSample; // Convert to bytes and drop it in the pipe byte[] bytes = BitConverter.GetBytes(filteredSample); _buffer.AddSamples(bytes, 0, 4); } } }