Essgee:GAMEBOY DMGAudio 修改掉接口访问器设置音量的做法,避免每帧14万次的volume访问器堆栈耗费性能

This commit is contained in:
sin365 2025-11-17 23:22:26 +08:00
parent bb32fd3736
commit 7f20da42e6
5 changed files with 63 additions and 48 deletions

View File

@ -2,7 +2,8 @@
{
public partial class CGBAudio
{
public class CGBWave : Wave, IDMGAudioChannel
//本身wave就继承了IDMGAudioChannel
public class CGBWave : Wave//, IDMGAudioChannel
{
public override void Reset()
{

View File

@ -39,16 +39,16 @@ namespace Essgee.Emulation.Audio
bool isChannelEnabled, isDacEnabled;
int lengthCounter;
public int OutputVolume { get; private set; }
//public int OutputVolume { get; private set; }
public bool IsActive { get { return lengthCounter != 0; } }
public override bool IsActive { get { return lengthCounter != 0; } }
public Noise()
{
//
}
public void Reset()
public override void Reset()
{
noiseCounter = 0;
lfsr = 0;
@ -63,7 +63,7 @@ namespace Essgee.Emulation.Audio
OutputVolume = volume;
}
public void LengthCounterClock()
public override void LengthCounterClock()
{
if (lengthCounter > 0 && lengthEnable)
{
@ -73,12 +73,12 @@ namespace Essgee.Emulation.Audio
}
}
public void SweepClock()
public override void SweepClock()
{
throw new Exception("Channel type does not support sweep");
}
public void VolumeEnvelopeClock()
public override void VolumeEnvelopeClock()
{
envelopeCounter--;
if (envelopeCounter == 0)
@ -99,7 +99,7 @@ namespace Essgee.Emulation.Audio
}
}
public void Step()
public override void Step()
{
if (!isChannelEnabled) return;
@ -132,7 +132,7 @@ namespace Essgee.Emulation.Audio
lfsr = 0x7FFF;
}
public void WritePort(byte port, byte value)
public override void WritePort(byte port, byte value)
{
switch (port)
{
@ -168,7 +168,7 @@ namespace Essgee.Emulation.Audio
}
}
public byte ReadPort(byte port)
public override byte ReadPort(byte port)
{
switch (port)
{
@ -200,12 +200,12 @@ namespace Essgee.Emulation.Audio
}
}
public void WriteWaveRam(byte offset, byte value)
public override void WriteWaveRam(byte offset, byte value)
{
throw new Exception("Channel type does have Wave RAM");
}
public byte ReadWaveRam(byte offset)
public override byte ReadWaveRam(byte offset)
{
throw new Exception("Channel type does have Wave RAM");
}

View File

@ -74,16 +74,16 @@ namespace Essgee.Emulation.Audio
bool isChannelEnabled, isDacEnabled;
int lengthCounter, dutyCounter;
public int OutputVolume { get; private set; }
//public int OutputVolume { get; private set; }
public bool IsActive { get { return lengthCounter != 0; } }
public override bool IsActive { get { return lengthCounter != 0; } }
public Square(bool hasSweep)
{
channelSupportsSweep = hasSweep;
}
public void Reset()
public override void Reset()
{
isSweepEnabled = false;
sweepCounter = sweepFreqShadow = 0;
@ -100,7 +100,7 @@ namespace Essgee.Emulation.Audio
OutputVolume = volume;
}
public void LengthCounterClock()
public override void LengthCounterClock()
{
if (lengthCounter > 0 && lengthEnable)
{
@ -110,7 +110,7 @@ namespace Essgee.Emulation.Audio
}
}
public void SweepClock()
public override void SweepClock()
{
if (!channelSupportsSweep) return;
@ -133,7 +133,7 @@ namespace Essgee.Emulation.Audio
}
}
public void VolumeEnvelopeClock()
public override void VolumeEnvelopeClock()
{
envelopeCounter--;
if (envelopeCounter == 0)
@ -154,7 +154,7 @@ namespace Essgee.Emulation.Audio
}
}
public void Step()
public override void Step()
{
if (!isChannelEnabled) return;
@ -202,7 +202,7 @@ namespace Essgee.Emulation.Audio
return newFrequency;
}
public void WritePort(byte port, byte value)
public override void WritePort(byte port, byte value)
{
switch (port)
{
@ -244,7 +244,7 @@ namespace Essgee.Emulation.Audio
}
}
public byte ReadPort(byte port)
public override byte ReadPort(byte port)
{
switch (port)
{
@ -281,12 +281,12 @@ namespace Essgee.Emulation.Audio
}
}
public void WriteWaveRam(byte offset, byte value)
public override void WriteWaveRam(byte offset, byte value)
{
throw new Exception("Channel type does have Wave RAM");
}
public byte ReadWaveRam(byte offset)
public override byte ReadWaveRam(byte offset)
{
throw new Exception("Channel type does have Wave RAM");
}

View File

@ -30,16 +30,16 @@ namespace Essgee.Emulation.Audio
bool isChannelEnabled;
int lengthCounter;
public int OutputVolume { get; private set; }
//public int OutputVolume { get; private set; }
public bool IsActive { get { return isDacEnabled; } } // TODO: correct? lengthCounter check makes Zelda Oracle games hang
public override bool IsActive { get { return isDacEnabled; } } // TODO: correct? lengthCounter check makes Zelda Oracle games hang
public Wave()
{
sampleBuffer = new byte[16];
}
public virtual void Reset()
public override void Reset()
{
for (var i = 0; i < sampleBuffer.Length; i++) sampleBuffer[i] = (byte)EmuStandInfo.Random.Next(255);
frequencyCounter = positionCounter = 0;
@ -51,7 +51,7 @@ namespace Essgee.Emulation.Audio
OutputVolume = volume;
}
public void LengthCounterClock()
public override void LengthCounterClock()
{
if (lengthCounter > 0 && lengthEnable)
{
@ -61,17 +61,17 @@ namespace Essgee.Emulation.Audio
}
}
public void SweepClock()
public override void SweepClock()
{
throw new Exception("Channel type does not support sweep");
}
public void VolumeEnvelopeClock()
public override void VolumeEnvelopeClock()
{
throw new Exception("Channel type does not support envelope");
}
public void Step()
public override void Step()
{
if (!isChannelEnabled) return;
@ -105,7 +105,7 @@ namespace Essgee.Emulation.Audio
positionCounter = 0;
}
public void WritePort(byte port, byte value)
public override void WritePort(byte port, byte value)
{
switch (port)
{
@ -137,7 +137,7 @@ namespace Essgee.Emulation.Audio
}
}
public byte ReadPort(byte port)
public override byte ReadPort(byte port)
{
switch (port)
{
@ -166,7 +166,7 @@ namespace Essgee.Emulation.Audio
// TODO: more details on behavior on access w/ channel enabled
public void WriteWaveRam(byte offset, byte value)
public override void WriteWaveRam(byte offset, byte value)
{
if (!isDacEnabled)
sampleBuffer[offset & (sampleBuffer.Length - 1)] = value;
@ -174,7 +174,7 @@ namespace Essgee.Emulation.Audio
sampleBuffer[positionCounter & (sampleBuffer.Length - 1)] = value;
}
public byte ReadWaveRam(byte offset)
public override byte ReadWaveRam(byte offset)
{
if (!isDacEnabled)
return sampleBuffer[offset & (sampleBuffer.Length - 1)];

View File

@ -1,19 +1,33 @@
namespace Essgee.Emulation.Audio
{
public interface IDMGAudioChannel
//public interface IDMGAudioChannel
// {
// int OutputVolume { get; }
// bool IsActive { get; }
// void Reset();
// void LengthCounterClock();
// void SweepClock();
// void VolumeEnvelopeClock();
// void Step();
// void WritePort(byte port, byte value);
// byte ReadPort(byte port);
// void WriteWaveRam(byte offset, byte value);
// byte ReadWaveRam(byte offset);
//}
public abstract class IDMGAudioChannel
{
int OutputVolume { get; }
bool IsActive { get; }
void Reset();
void LengthCounterClock();
void SweepClock();
void VolumeEnvelopeClock();
void Step();
void WritePort(byte port, byte value);
byte ReadPort(byte port);
void WriteWaveRam(byte offset, byte value);
byte ReadWaveRam(byte offset);
public int OutputVolume;
public abstract bool IsActive { get; }
public abstract void Reset();
public abstract void LengthCounterClock();
public abstract void SweepClock();
public abstract void VolumeEnvelopeClock();
public abstract void Step();
public abstract void WritePort(byte port, byte value);
public abstract byte ReadPort(byte port);
public abstract void WriteWaveRam(byte offset, byte value);
public abstract byte ReadWaveRam(byte offset);
}
}