mame: probably fix audio

This commit is contained in:
feos 2021-05-08 21:01:29 +03:00
parent 547bf6d308
commit 701d340e00
3 changed files with 11 additions and 27 deletions

View File

@ -11,9 +11,8 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
public SyncSoundMode SyncMode => SyncSoundMode.Sync; public SyncSoundMode SyncMode => SyncSoundMode.Sync;
private readonly Queue<short> _audioSamples = new Queue<short>(); private readonly Queue<short> _audioSamples = new Queue<short>();
private decimal _dAudioSamples = 0;
private readonly int _sampleRate = 44100; private readonly int _sampleRate = 44100;
private int _numSamples = 0; private long _soundRemainder = 0;
public void SetSyncMode(SyncSoundMode mode) public void SetSyncMode(SyncSoundMode mode)
{ {
@ -34,31 +33,14 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
* I'm doing my own logic here for now. I grab MAME's audio buffer * I'm doing my own logic here for now. I grab MAME's audio buffer
* whenever it's filled (MAMESoundCallback()) and enqueue it. * whenever it's filled (MAMESoundCallback()) and enqueue it.
* *
* Whenever Hawk wants new audio, I dequeue it, but with a little quirk. * Whenever Hawk wants new audio, I dequeue it, while preserving the
* Since sample count per frame may not align with frame duration, I * fractinal part of the sample count, to use it later.
* subtract the entire decimal fraction of "required" samples from total
* samples. I check if the fractional reminder of total samples is > 0.5
* by rounding it. I invert it to see what number I should add to the
* integer representation of "required" samples, to compensate for
* misalignment between fractional and integral "required" samples.
*
* TODO: Figure out how MAME does this and maybe use their method instead.
*/ */
public void GetSamplesSync(out short[] samples, out int nsamp) public void GetSamplesSync(out short[] samples, out int nsamp)
{ {
decimal dSamplesPerFrame = (decimal)_sampleRate * VsyncDenominator / VsyncNumerator; long nSampNumerator = _sampleRate * (long)VsyncDenominator + _soundRemainder;
nsamp = (int)(nSampNumerator / VsyncNumerator);
if (_audioSamples.Any()) _soundRemainder = nSampNumerator % VsyncNumerator; // exactly remember fractional parts of an audio sample
{
_dAudioSamples -= dSamplesPerFrame;
int remainder = (int)Math.Round(_dAudioSamples - Math.Truncate(_dAudioSamples)) ^ 1;
nsamp = (int)Math.Round(dSamplesPerFrame) + remainder;
}
else
{
nsamp = (int)Math.Round(dSamplesPerFrame);
}
samples = new short[nsamp * 2]; samples = new short[nsamp * 2];
for (int i = 0; i < nsamp * 2; i++) for (int i = 0; i < nsamp * 2; i++)
@ -81,6 +63,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
public void DiscardSamples() public void DiscardSamples()
{ {
_soundRemainder = 0;
_audioSamples.Clear(); _audioSamples.Clear();
} }
} }

View File

@ -51,6 +51,8 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
Frame = reader.ReadInt32(); Frame = reader.ReadInt32();
LagCount = reader.ReadInt32(); LagCount = reader.ReadInt32();
IsLagFrame = reader.ReadBoolean(); IsLagFrame = reader.ReadBoolean();
DiscardSamples();
} }
} }
} }

View File

@ -258,15 +258,14 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
return; return;
} }
_numSamples = lengthInBytes / bytesPerSample; int numSamples = lengthInBytes / bytesPerSample;
unsafe unsafe
{ {
short* pSample = (short*)ptr.ToPointer(); short* pSample = (short*)ptr.ToPointer();
for (int i = 0; i < _numSamples; i++) for (int i = 0; i < numSamples; i++)
{ {
_audioSamples.Enqueue(*(pSample + i)); _audioSamples.Enqueue(*(pSample + i));
_dAudioSamples++;
} }
} }