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 partial class CGBAudio
{ {
public class CGBWave : Wave, IDMGAudioChannel //本身wave就继承了IDMGAudioChannel
public class CGBWave : Wave//, IDMGAudioChannel
{ {
public override void Reset() public override void Reset()
{ {

View File

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

View File

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

View File

@ -30,16 +30,16 @@ namespace Essgee.Emulation.Audio
bool isChannelEnabled; bool isChannelEnabled;
int lengthCounter; 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() public Wave()
{ {
sampleBuffer = new byte[16]; 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); for (var i = 0; i < sampleBuffer.Length; i++) sampleBuffer[i] = (byte)EmuStandInfo.Random.Next(255);
frequencyCounter = positionCounter = 0; frequencyCounter = positionCounter = 0;
@ -51,7 +51,7 @@ namespace Essgee.Emulation.Audio
OutputVolume = volume; OutputVolume = volume;
} }
public void LengthCounterClock() public override void LengthCounterClock()
{ {
if (lengthCounter > 0 && lengthEnable) 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"); 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"); throw new Exception("Channel type does not support envelope");
} }
public void Step() public override void Step()
{ {
if (!isChannelEnabled) return; if (!isChannelEnabled) return;
@ -105,7 +105,7 @@ namespace Essgee.Emulation.Audio
positionCounter = 0; positionCounter = 0;
} }
public void WritePort(byte port, byte value) public override void WritePort(byte port, byte value)
{ {
switch (port) switch (port)
{ {
@ -137,7 +137,7 @@ namespace Essgee.Emulation.Audio
} }
} }
public byte ReadPort(byte port) public override byte ReadPort(byte port)
{ {
switch (port) switch (port)
{ {
@ -166,7 +166,7 @@ namespace Essgee.Emulation.Audio
// TODO: more details on behavior on access w/ channel enabled // 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) if (!isDacEnabled)
sampleBuffer[offset & (sampleBuffer.Length - 1)] = value; sampleBuffer[offset & (sampleBuffer.Length - 1)] = value;
@ -174,7 +174,7 @@ namespace Essgee.Emulation.Audio
sampleBuffer[positionCounter & (sampleBuffer.Length - 1)] = value; sampleBuffer[positionCounter & (sampleBuffer.Length - 1)] = value;
} }
public byte ReadWaveRam(byte offset) public override byte ReadWaveRam(byte offset)
{ {
if (!isDacEnabled) if (!isDacEnabled)
return sampleBuffer[offset & (sampleBuffer.Length - 1)]; return sampleBuffer[offset & (sampleBuffer.Length - 1)];

View File

@ -1,19 +1,33 @@
namespace Essgee.Emulation.Audio 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; } public int OutputVolume;
bool IsActive { get; } public abstract bool IsActive { get; }
public abstract void Reset();
void Reset(); public abstract void LengthCounterClock();
void LengthCounterClock(); public abstract void SweepClock();
void SweepClock(); public abstract void VolumeEnvelopeClock();
void VolumeEnvelopeClock(); public abstract void Step();
void Step(); public abstract void WritePort(byte port, byte value);
public abstract byte ReadPort(byte port);
void WritePort(byte port, byte value); public abstract void WriteWaveRam(byte offset, byte value);
byte ReadPort(byte port); public abstract byte ReadWaveRam(byte offset);
void WriteWaveRam(byte offset, byte value);
byte ReadWaveRam(byte offset);
} }
} }