Swag up NullSound
This commit is contained in:
parent
b465eaa470
commit
eb72ff9053
|
@ -22,7 +22,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
// Sound refactor TODO: we could try set it here, but we want the client to be responsible for mode switching? There may be non-trivial complications with when to switch modes that we don't want this object worrying about
|
||||
if (asyncSoundProvider.SyncMode != SyncSoundMode.Async)
|
||||
{
|
||||
throw new InvalidOperationException("Only sync mode is supported, set sync mode before passing in the sound provider");
|
||||
throw new InvalidOperationException("Only async mode is supported, set async mode before passing in the sound provider");
|
||||
}
|
||||
|
||||
if (!aset || !vset)
|
||||
|
|
|
@ -734,16 +734,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
_currentVideoProvider = NullVideo.Instance;
|
||||
}
|
||||
|
||||
if (Global.Emulator.HasSoundProvider())
|
||||
{
|
||||
_currentSoundProvider = Global.Emulator.AsSoundProvider();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the samples per frame based on VSync rate (which is 60 unless the core states otherwise)
|
||||
// Use 44.1 khz because we like to do that
|
||||
_currentSoundProvider = new NullSound((int)(44100 / Global.Emulator.CoreComm.VsyncRate));
|
||||
}
|
||||
_currentSoundProvider = Global.Emulator.AsSoundProviderOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,43 +4,76 @@ namespace BizHawk.Emulation.Common
|
|||
{
|
||||
public class NullSound : ISoundProvider
|
||||
{
|
||||
private readonly int _spf;
|
||||
private readonly long _spfNumerator;
|
||||
private readonly long _spfDenominator;
|
||||
private long _remainder = 0;
|
||||
private short[] _buff = new short[0];
|
||||
|
||||
public NullSound(int spf)
|
||||
private NullSound()
|
||||
{
|
||||
_spf = spf;
|
||||
SyncMode = SyncSoundMode.Sync;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// create a NullSound that provides an exact number of audio samples per call when in sync mode
|
||||
/// </summary>
|
||||
/// <param name="spf"></param>
|
||||
public NullSound(int spf)
|
||||
:this()
|
||||
{
|
||||
_spfNumerator = spf;
|
||||
_spfDenominator = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// create a NullSound that exactly matches a given framerate when in sync mode
|
||||
/// </summary>
|
||||
/// <param name="fpsNum"></param>
|
||||
/// <param name="fpsDen"></param>
|
||||
public NullSound(long fpsNum, long fpsDen)
|
||||
{
|
||||
_spfNumerator = fpsDen * 44100;
|
||||
_spfDenominator = fpsNum;
|
||||
}
|
||||
|
||||
public bool CanProvideAsync
|
||||
{
|
||||
get { return false; }
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public SyncSoundMode SyncMode
|
||||
{
|
||||
get { return SyncSoundMode.Sync; }
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public void GetSamplesSync(out short[] samples, out int nsamp)
|
||||
{
|
||||
short[] ret = new short[_spf * 2];
|
||||
samples = ret;
|
||||
nsamp = _spf;
|
||||
if (SyncMode != SyncSoundMode.Sync)
|
||||
throw new InvalidOperationException("Wrong sound mode");
|
||||
|
||||
int s = (int)((_spfNumerator + _remainder) / _spfDenominator);
|
||||
_remainder = (_spfNumerator + _remainder) % _spfDenominator;
|
||||
|
||||
if (_buff.Length < s * 2)
|
||||
_buff = new short[s * 2];
|
||||
|
||||
samples = _buff;
|
||||
nsamp = s;
|
||||
}
|
||||
|
||||
public void DiscardSamples() { }
|
||||
|
||||
public void SetSyncMode(SyncSoundMode mode)
|
||||
{
|
||||
if (mode == SyncSoundMode.Async)
|
||||
{
|
||||
throw new NotSupportedException("Async mode is not supported.");
|
||||
}
|
||||
SyncMode = mode;
|
||||
}
|
||||
|
||||
public void GetSamplesAsync(short[] samples)
|
||||
{
|
||||
throw new InvalidOperationException("Async mode is not supported.");
|
||||
if (SyncMode != SyncSoundMode.Async)
|
||||
throw new InvalidOperationException("Wrong sound mode");
|
||||
Array.Clear(samples, 0, samples.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace BizHawk.Emulation.Common.IEmulatorExtensions
|
||||
{
|
||||
|
@ -48,6 +49,19 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
|
|||
return core.ServiceProvider.GetService<ISoundProvider>();
|
||||
}
|
||||
|
||||
private static readonly ConditionalWeakTable<IEmulator, ISoundProvider> CachedNullSoundProviders = new ConditionalWeakTable<IEmulator, ISoundProvider>();
|
||||
|
||||
/// <summary>
|
||||
/// returns the core's SoundProvider, or a suitable dummy provider
|
||||
/// </summary>
|
||||
public static ISoundProvider AsSoundProviderOrDefault(this IEmulator core)
|
||||
{
|
||||
var ret = core.ServiceProvider.GetService<ISoundProvider>();
|
||||
if (ret == null)
|
||||
ret = CachedNullSoundProviders.GetValue(core, e => new NullSound(e.CoreComm.VsyncNum, e.CoreComm.VsyncDen));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static bool HasMemoryDomains(this IEmulator core)
|
||||
{
|
||||
if (core == null)
|
||||
|
|
Loading…
Reference in New Issue