Pass a callback to some sound internals to read the global IEmulator

This commit is contained in:
YoshiRulz 2020-11-30 16:16:22 +10:00
parent 6d22cdc15f
commit 636a9a4735
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
5 changed files with 24 additions and 13 deletions

View File

@ -919,7 +919,7 @@ namespace BizHawk.Client.EmuHawk
if (form.ApplyNewSoundDevice)
{
Sound.Dispose();
Sound = new Sound(Handle, Config.SoundOutputMethod, Config.SoundDevice);
Sound = new Sound(Handle, Config.SoundOutputMethod, Config.SoundDevice, Emulator.VsyncRate);
Sound.StartSound();
}
else

View File

@ -415,7 +415,7 @@ namespace BizHawk.Client.EmuHawk
InputManager.AutofireStickyXorAdapter.SetOnOffPatternFromConfig(Config.AutofireOn, Config.AutofireOff);
try
{
GlobalWin.Sound = new Sound(Handle, Config.SoundOutputMethod, Config.SoundDevice);
GlobalWin.Sound = new Sound(Handle, Config.SoundOutputMethod, Config.SoundDevice, Emulator.VsyncRate);
}
catch
{
@ -428,7 +428,7 @@ namespace BizHawk.Client.EmuHawk
MessageBox.Show(message, "Initialization Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Config.SoundOutputMethod = ESoundOutputMethod.Dummy;
GlobalWin.Sound = new Sound(Handle, Config.SoundOutputMethod, Config.SoundDevice);
GlobalWin.Sound = new Sound(Handle, Config.SoundOutputMethod, Config.SoundDevice, Emulator.VsyncRate);
}
Sound.StartSound();
@ -3294,7 +3294,7 @@ namespace BizHawk.Client.EmuHawk
else
{
_currentSoundProvider.SetSyncMode(SyncSoundMode.Sync);
_aviSoundInputAsync = new SyncToAsyncProvider(_currentSoundProvider);
_aviSoundInputAsync = new SyncToAsyncProvider(Emulator.VsyncRate, _currentSoundProvider);
}
}

View File

@ -19,18 +19,23 @@ namespace BizHawk.Client.EmuHawk
public int BlockAlign { get; }
private readonly Func<double> _getCoreVsyncRateCallback;
private bool _disposed;
private readonly ISoundOutput _outputDevice;
private readonly SoundOutputProvider _outputProvider = new SoundOutputProvider(); // Buffer for Sync sources
private readonly SoundOutputProvider _outputProvider; // Buffer for Sync sources
private readonly BufferedAsync _bufferedAsync = new BufferedAsync(); // Buffer for Async sources
private IBufferedSoundProvider _bufferedProvider; // One of the preceding buffers, or null if no source is set
public int ConfigBufferSizeMs => GlobalWin.Config.SoundBufferSizeMs;
public Sound(IntPtr mainWindowHandle, ESoundOutputMethod soundOutputMethod, string soundDevice)
public Sound(IntPtr mainWindowHandle, ESoundOutputMethod soundOutputMethod, string soundDevice, Func<double> getCoreVsyncRateCallback)
{
BlockAlign = BytesPerSample * ChannelCount;
_getCoreVsyncRateCallback = getCoreVsyncRateCallback;
_outputProvider = new SoundOutputProvider(_getCoreVsyncRateCallback);
if (OSTailoredCode.IsUnixHost)
{
// if DirectSound or XAudio is chosen, use OpenAL, otherwise comply with the user's choice
@ -118,7 +123,7 @@ namespace BizHawk.Client.EmuHawk
}
else if (source.SyncMode == SyncSoundMode.Async)
{
_bufferedAsync.RecalculateMagic(GlobalWin.Emulator.VsyncRate());
_bufferedAsync.RecalculateMagic(_getCoreVsyncRateCallback());
_bufferedProvider = _bufferedAsync;
}
else throw new InvalidOperationException("Unsupported sync mode.");
@ -131,7 +136,7 @@ namespace BizHawk.Client.EmuHawk
public void HandleInitializationOrUnderrun(bool isUnderrun, ref int samplesNeeded)
{
// Fill device buffer with silence but leave enough room for one frame
int samplesPerFrame = (int)Math.Round(SampleRate / (double)GlobalWin.Emulator.VsyncRate());
int samplesPerFrame = (int)Math.Round(SampleRate / _getCoreVsyncRateCallback());
int silenceSamples = Math.Max(samplesNeeded - samplesPerFrame, 0);
_outputDevice.WriteSamples(new short[silenceSamples * 2], 0, silenceSamples);
samplesNeeded -= silenceSamples;

View File

@ -31,6 +31,8 @@ namespace BizHawk.Client.EmuHawk
private const int BaseSampleRateMaxHistoryLength = 300;
private const int MinResamplingDistanceSamples = 3;
private readonly Func<double> _getCoreVsyncRateCallback;
private readonly Queue<short> _buffer = new Queue<short>();
private readonly bool _standaloneMode;
private readonly int _targetExtraSamples;
@ -51,8 +53,9 @@ namespace BizHawk.Client.EmuHawk
private short[] _resampleBuffer = new short[0];
private double _resampleLengthRoundingError;
public SoundOutputProvider(bool standaloneMode = false)
public SoundOutputProvider(Func<double> getCoreVsyncRateCallback, bool standaloneMode = false)
{
_getCoreVsyncRateCallback = getCoreVsyncRateCallback;
_standaloneMode = standaloneMode;
if (_standaloneMode)
{
@ -114,7 +117,7 @@ namespace BizHawk.Client.EmuHawk
public bool LogDebug { get; set; }
private double AdvertisedSamplesPerFrame => SampleRate / GlobalWin.Emulator.VsyncRate();
private double AdvertisedSamplesPerFrame => SampleRate / _getCoreVsyncRateCallback();
/// <exception cref="InvalidOperationException">not constructed in standalone mode</exception>
public void GetSamples(short[] samples)

View File

@ -6,11 +6,14 @@ namespace BizHawk.Client.EmuHawk
{
public class SyncToAsyncProvider : ISoundProvider
{
private readonly SoundOutputProvider _outputProvider = new SoundOutputProvider(standaloneMode: true);
private readonly SoundOutputProvider _outputProvider;
public SyncToAsyncProvider(ISoundProvider baseProvider)
public SyncToAsyncProvider(Func<double> getCoreVsyncRateCallback, ISoundProvider baseProvider)
{
_outputProvider.BaseSoundProvider = baseProvider;
_outputProvider = new SoundOutputProvider(getCoreVsyncRateCallback, standaloneMode: true)
{
BaseSoundProvider = baseProvider
};
}
public void DiscardSamples()