Essgee.Unity/Assets/Plugins/Essgee/Emulation/Audio/SegaGGPSG.cs

78 lines
2.3 KiB
C#
Raw Normal View History

2025-01-02 17:55:16 +08:00
using System;
using Essgee.Utilities;
namespace Essgee.Emulation.Audio
{
public class SegaGGPSG : SegaSMSPSG
{
public const int PortStereoControl = 0x06;
[StateRequired]
readonly bool[] channel0Enable, channel1Enable, channel2Enable, channel3Enable;
public SegaGGPSG() : base()
{
channel0Enable = new bool[2];
channel1Enable = new bool[2];
channel2Enable = new bool[2];
channel3Enable = new bool[2];
}
public override void Reset()
{
base.Reset();
WritePort(PortStereoControl, 0xFF);
}
protected override void GenerateSample()
{
for (int i = 0; i < numOutputChannels; i++)
{
/* Generate samples */
var ch1 = (channel0Enable[i] ? (short)(volumeTable[volumeRegisters[0]] * ((toneRegisters[0] < 2 ? true : channelOutput[0]) ? 1.0 : 0.0)) : (short)0);
var ch2 = (channel1Enable[i] ? (short)(volumeTable[volumeRegisters[1]] * ((toneRegisters[1] < 2 ? true : channelOutput[1]) ? 1.0 : 0.0)) : (short)0);
var ch3 = (channel2Enable[i] ? (short)(volumeTable[volumeRegisters[2]] * ((toneRegisters[2] < 2 ? true : channelOutput[2]) ? 1.0 : 0.0)) : (short)0);
var ch4 = (channel3Enable[i] ? (short)(volumeTable[volumeRegisters[3]] * (noiseLfsr & 0x1)) : (short)0);
channelSampleBuffer[0].Add(ch1);
channelSampleBuffer[1].Add(ch2);
channelSampleBuffer[2].Add(ch3);
channelSampleBuffer[3].Add(ch4);
/* Mix samples */
var mixed = 0;
if (channel1ForceEnable) mixed += ch1;
if (channel2ForceEnable) mixed += ch2;
if (channel3ForceEnable) mixed += ch3;
if (channel4ForceEnable) mixed += ch4;
mixed /= numChannels;
mixedSampleBuffer.Add((short)mixed);
}
}
public override void WritePort(byte port, byte data)
{
if (port == PortStereoControl)
{
/* Stereo control */
channel0Enable[0] = ((data & 0x10) != 0); /* Ch1 Left */
channel0Enable[1] = ((data & 0x01) != 0); /* Ch1 Right */
channel1Enable[0] = ((data & 0x20) != 0); /* Ch2 Left */
channel1Enable[1] = ((data & 0x02) != 0); /* Ch2 Right */
channel2Enable[0] = ((data & 0x40) != 0); /* Ch3 Left */
channel2Enable[1] = ((data & 0x04) != 0); /* Ch3 Right */
channel3Enable[0] = ((data & 0x80) != 0); /* Ch4 Left */
channel3Enable[1] = ((data & 0x08) != 0); /* Ch4 Right */
}
else
base.WritePort(port, data);
}
}
}