using System; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Nintendo.N64.NativeApi; namespace BizHawk.Emulation.Cores.Nintendo.N64 { class N64Audio : IDisposable { /// /// mupen64 DLL Api /// private mupen64plusAudioApi api; private mupen64plusApi coreAPI; /// /// Buffer for audio data /// private short[] audioBuffer = new short[0]; private uint _samplingRate = 0; /// /// Currently active sampling rate /// public uint SamplingRate { get { return _samplingRate; } private set { _samplingRate = value; Resampler.ChangeRate(_samplingRate, 44100, _samplingRate, 44100); } } /// /// Resampler for audio output /// public SpeexResampler Resampler { get; private set; } public bool RenderSound { get; set; } /// /// Creates a N64 Audio subsystem /// /// Mupen64 api which is used for fetching sound public N64Audio(mupen64plusApi core) { this.api = new mupen64plusAudioApi(core); _samplingRate = api.GetSamplingRate(); Resampler = new SpeexResampler(6, SamplingRate, 44100, SamplingRate, 44100); coreAPI = core; coreAPI.VInterrupt += DoAudioFrame; } /// /// Fetches the audio buffer from mupen64plus and pushes it into the /// Resampler for audio output /// public void DoAudioFrame() { uint m64pSamplingRate = api.GetSamplingRate(); if (m64pSamplingRate != SamplingRate) SamplingRate = m64pSamplingRate; int audioBufferSize = api.GetAudioBufferSize(); if (audioBuffer.Length < audioBufferSize) audioBuffer = new short[audioBufferSize]; if (audioBufferSize > 0) { api.GetAudioBuffer(audioBuffer); if (RenderSound) Resampler.EnqueueSamples(audioBuffer, audioBufferSize / 2); } } public void Dispose() { coreAPI.VInterrupt -= DoAudioFrame; if(Resampler != null) Resampler.Dispose(); Resampler = null; api = null; } } }