Added AY38912 support
This commit is contained in:
@@ -1,21 +1,28 @@
|
||||
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; // 100ms latency to prevent buffer stutter
|
||||
_waveOut.DesiredLatency = 50;
|
||||
|
||||
// 44.1kHz, 1 channel (Mono), Float format
|
||||
_buffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 1));
|
||||
@@ -26,21 +33,53 @@ namespace Desktop
|
||||
_waveOut.Play();
|
||||
}
|
||||
|
||||
public void AddSample(bool isHigh)
|
||||
public void AddSample(bool isHigh, float freqA, float volA, float freqB, float volB, float freqC, float volC)
|
||||
{
|
||||
//Buffer overrun check and dump
|
||||
// Buffer overrun check
|
||||
while (_buffer.BufferedDuration.TotalMilliseconds > 80)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
// Convert the boolean into a physical sound wave (-0.2 or +0.2)
|
||||
float rawSample = isHigh ? 0.2f : -0.2f;
|
||||
// 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 the float to bytes and drop it in the pipe
|
||||
// Convert to bytes and drop it in the pipe
|
||||
byte[] bytes = BitConverter.GetBytes(filteredSample);
|
||||
_buffer.AddSamples(bytes, 0, 4);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user