From ee842fbde321335c97102e7ee8991cb992fdca76 Mon Sep 17 00:00:00 2001 From: adelikat Date: Thu, 27 Apr 2017 11:27:26 -0500 Subject: [PATCH] Emulation.Common - cleanup SpeexResampler, and DCFilter --- .../Sound/Utilities/DCFilter.cs | 12 +- .../Sound/Utilities/SpeexResampler.cs | 138 ++++++++---------- BizHawk.sln.DotSettings | 1 + 3 files changed, 69 insertions(+), 82 deletions(-) diff --git a/BizHawk.Emulation.Common/Sound/Utilities/DCFilter.cs b/BizHawk.Emulation.Common/Sound/Utilities/DCFilter.cs index 3dcaaa3d2d..19067916d7 100644 --- a/BizHawk.Emulation.Common/Sound/Utilities/DCFilter.cs +++ b/BizHawk.Emulation.Common/Sound/Utilities/DCFilter.cs @@ -71,14 +71,14 @@ namespace BizHawk.Emulation.Common { for (int i = 0; i < length; i += 2) { - int L = samplesin[i] << 12; - int R = samplesin[i + 1] << 12; + int l = samplesin[i] << 12; + int r = samplesin[i + 1] << 12; _accumL -= _accumL >> _depth; _accumR -= _accumR >> _depth; - _accumL += L - _latchL; - _accumR += R - _latchR; - _latchL = L; - _latchR = R; + _accumL += l - _latchL; + _accumR += r - _latchR; + _latchL = l; + _latchR = r; int bigL = _accumL >> 12; int bigR = _accumR >> 12; diff --git a/BizHawk.Emulation.Common/Sound/Utilities/SpeexResampler.cs b/BizHawk.Emulation.Common/Sound/Utilities/SpeexResampler.cs index cd5bf01caa..9e667f4054 100644 --- a/BizHawk.Emulation.Common/Sound/Utilities/SpeexResampler.cs +++ b/BizHawk.Emulation.Common/Sound/Utilities/SpeexResampler.cs @@ -1,6 +1,8 @@ using System; using System.Runtime.InteropServices; +// ReSharper disable StyleCop.SA1300 +// ReSharper disable InconsistentNaming namespace BizHawk.Emulation.Common { /// @@ -8,6 +10,15 @@ namespace BizHawk.Emulation.Common /// public class SpeexResampler : IDisposable, ISoundProvider { + // to accept an ISyncSoundProvder input + private readonly ISoundProvider _input; + + // function to call to dispatch output + private readonly Action _drainer; + + // TODO: this size is roughly based on how big you can make the buffer before the snes resampling (32040.5 -> 44100) gets screwed up + private readonly short[] _inbuf = new short[512]; // [8192]; // [512]; + private static class LibSpeexDSP { public const int QUALITY_MAX = 10; @@ -70,7 +81,6 @@ namespace BizHawk.Emulation.Common /// Number of input samples in the input buffer. Returns the number of samples processed /// Output buffer /// Size of the output buffer. Returns the number of samples written - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_process_float(IntPtr st, uint channel_index, float[] inp, ref uint in_len, float[] outp, ref uint out_len); @@ -83,7 +93,6 @@ namespace BizHawk.Emulation.Common /// Number of input samples in the input buffer. Returns the number of samples processed /// Output buffer /// Size of the output buffer. Returns the number of samples written - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_process_int(IntPtr st, uint channel_index, short[] inp, ref uint in_len, short[] outp, ref uint out_len); @@ -95,7 +104,6 @@ namespace BizHawk.Emulation.Common /// Number of input samples in the input buffer. Returns the number of samples processed. This is all per-channel. /// Output buffer /// Size of the output buffer. Returns the number of samples written. This is all per-channel. - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_process_interleaved_float(IntPtr st, float[] inp, ref uint in_len, float[] outp, ref uint out_len); @@ -107,7 +115,6 @@ namespace BizHawk.Emulation.Common /// Number of input samples in the input buffer. Returns the number of samples processed. This is all per-channel. /// Output buffer /// Size of the output buffer. Returns the number of samples written. This is all per-channel. - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_process_interleaved_int(IntPtr st, short[] inp, ref uint in_len, short[] outp, ref uint out_len); @@ -117,7 +124,6 @@ namespace BizHawk.Emulation.Common /// Resampler state /// Input sampling rate (integer number of Hz). /// Output sampling rate (integer number of Hz). - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_set_rate(IntPtr st, uint in_rate, uint out_rate); @@ -138,7 +144,6 @@ namespace BizHawk.Emulation.Common /// Denominator of the sampling rate ratio /// Input sampling rate rounded to the nearest integer (in Hz). /// Output sampling rate rounded to the nearest integer (in Hz). - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_set_rate_frac(IntPtr st, uint ratio_num, uint ratio_den, uint in_rate, uint out_rate); @@ -229,7 +234,6 @@ namespace BizHawk.Emulation.Common /// is the same for the first frame). /// /// Resampler state - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_skip_zeroes(IntPtr st); @@ -237,7 +241,6 @@ namespace BizHawk.Emulation.Common /// Reset a resampler so a new (unrelated) stream can be processed. /// /// Resampler state - /// [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] public static extern RESAMPLER_ERR speex_resampler_reset_mem(IntPtr st); @@ -250,37 +253,21 @@ namespace BizHawk.Emulation.Common public static extern string speex_resampler_strerror(RESAMPLER_ERR err); } - /// - /// opaque pointer to state - /// - private IntPtr st = IntPtr.Zero; + // opaque pointer to state + private IntPtr _st = IntPtr.Zero; - /// - /// function to call to dispatch output - /// - private readonly Action drainer; - - // TODO: this size is roughly based on how big you can make the buffer before the snes resampling (32040.5 -> 44100) gets screwed up - private short[] inbuf = new short[512]; //[8192]; // [512]; - - private short[] outbuf; + private short[] _outbuf; // for sync - private short[] outbuf2 = new short[16]; - private int outbuf2pos = 0; + private short[] _outbuf2 = new short[16]; + private int _outbuf2pos = 0; - // to accept an ISyncSoundProvder input - private readonly ISoundProvider input; - - /// - /// in buffer position in samples (not sample pairs) - /// - private int inbufpos = 0; + // in buffer position in samples (not sample pairs) + private int _inbufpos; /// /// throw an exception based on error state /// - /// private static void CheckError(LibSpeexDSP.RESAMPLER_ERR e) { switch (e) @@ -299,14 +286,15 @@ namespace BizHawk.Emulation.Common } /// + /// Initializes a new instance of the class /// /// 0 to 10 - /// numerator of srate change ratio (inrate / outrate) - /// demonenator of srate change ratio (inrate / outrate) + /// numerator of sample rate change ratio (inrate / outrate) + /// denominator of sample rate change ratio (inrate / outrate) /// sampling rate in, rounded to nearest hz /// sampling rate out, rounded to nearest hz - /// function which accepts output as produced. if null, act as an ISyncSoundProvider - /// source to take input from when output is requested. if null, no autofetching + /// function which accepts output as produced. if null, act as an + /// source to take input from when output is requested. if null, no auto-fetching public SpeexResampler(int quality, uint rationum, uint ratioden, uint sratein, uint srateout, Action drainer = null, ISoundProvider input = null) { if (drainer != null && input != null) @@ -315,30 +303,30 @@ namespace BizHawk.Emulation.Common } LibSpeexDSP.RESAMPLER_ERR err = LibSpeexDSP.RESAMPLER_ERR.SUCCESS; - st = LibSpeexDSP.speex_resampler_init_frac(2, rationum, ratioden, sratein, srateout, quality, ref err); + _st = LibSpeexDSP.speex_resampler_init_frac(2, rationum, ratioden, sratein, srateout, quality, ref err); - if (st == IntPtr.Zero) + if (_st == IntPtr.Zero) { throw new Exception("LibSpeexDSP returned null!"); } CheckError(err); - this.drainer = drainer ?? InternalDrain; - this.input = input; + _drainer = drainer ?? InternalDrain; + _input = input; - outbuf = new short[inbuf.Length * ratioden / rationum / 2 * 2 + 128]; + _outbuf = new short[(_inbuf.Length * ratioden / rationum / 2 * 2) + 128]; } /// change sampling rate on the fly - /// numerator of srate change ratio (inrate / outrate) - /// demonenator of srate change ratio (inrate / outrate) + /// numerator of sample rate change ratio (inrate / outrate) + /// denominator of sample rate change ratio (inrate / outrate) /// sampling rate in, rounded to nearest hz /// sampling rate out, rounded to nearest hz public void ChangeRate(uint rationum, uint ratioden, uint sratein, uint srateout) { - CheckError(LibSpeexDSP.speex_resampler_set_rate_frac(st, rationum, ratioden, sratein, srateout)); - outbuf = new short[inbuf.Length * ratioden / rationum / 2 * 2 + 128]; + CheckError(LibSpeexDSP.speex_resampler_set_rate_frac(_st, rationum, ratioden, sratein, srateout)); + _outbuf = new short[(_inbuf.Length * ratioden / rationum / 2 * 2) + 128]; } /// @@ -346,10 +334,10 @@ namespace BizHawk.Emulation.Common /// public void EnqueueSample(short left, short right) { - inbuf[inbufpos++] = left; - inbuf[inbufpos++] = right; + _inbuf[_inbufpos++] = left; + _inbuf[_inbufpos++] = right; - if (inbufpos == inbuf.Length) + if (_inbufpos == _inbuf.Length) { Flush(); } @@ -365,52 +353,51 @@ namespace BizHawk.Emulation.Common int numused = 0; while (numused < nsamp) { - int shortstocopy = Math.Min(inbuf.Length - inbufpos, (nsamp - numused) * 2); + int shortstocopy = Math.Min(_inbuf.Length - _inbufpos, (nsamp - numused) * 2); - Buffer.BlockCopy(userbuf, numused * 2 * sizeof(short), inbuf, inbufpos * sizeof(short), shortstocopy * sizeof(short)); - inbufpos += shortstocopy; + Buffer.BlockCopy(userbuf, numused * 2 * sizeof(short), _inbuf, _inbufpos * sizeof(short), shortstocopy * sizeof(short)); + _inbufpos += shortstocopy; numused += shortstocopy / 2; - if (inbufpos == inbuf.Length) + if (_inbufpos == _inbuf.Length) { Flush(); } } } - /// /// flush as many input samples as possible, generating output samples right now /// public void Flush() { - uint inal = (uint)inbufpos / 2; + uint inal = (uint)_inbufpos / 2; - uint outal = (uint)outbuf.Length / 2; + uint outal = (uint)_outbuf.Length / 2; - LibSpeexDSP.speex_resampler_process_interleaved_int(st, inbuf, ref inal, outbuf, ref outal); + LibSpeexDSP.speex_resampler_process_interleaved_int(_st, _inbuf, ref inal, _outbuf, ref outal); // reset inbuf - if (inal != inbufpos / 2) + if (inal != _inbufpos / 2) { throw new Exception("Speexresampler didn't eat the whole array?"); } - inbufpos = 0; + _inbufpos = 0; - //Buffer.BlockCopy(inbuf, (int)inal * 2 * sizeof(short), inbuf, 0, inbufpos - (int)inal * 2); - //inbufpos -= (int)inal * 2; + ////Buffer.BlockCopy(inbuf, (int)inal * 2 * sizeof(short), inbuf, 0, inbufpos - (int)inal * 2); + ////inbufpos -= (int)inal * 2; // dispatch outbuf - drainer(outbuf, (int)outal); + _drainer(_outbuf, (int)outal); } public void Dispose() { - if (st != IntPtr.Zero) + if (_st != IntPtr.Zero) { - LibSpeexDSP.speex_resampler_destroy(st); - st = IntPtr.Zero; + LibSpeexDSP.speex_resampler_destroy(_st); + _st = IntPtr.Zero; GC.SuppressFinalize(this); } } @@ -422,36 +409,36 @@ namespace BizHawk.Emulation.Common private void InternalDrain(short[] buf, int nsamp) { - if (outbuf2pos + nsamp * 2 > outbuf2.Length) + if (_outbuf2pos + (nsamp * 2) > _outbuf2.Length) { - short[] newbuf = new short[outbuf2pos + nsamp * 2]; - Buffer.BlockCopy(outbuf2, 0, newbuf, 0, outbuf2pos * sizeof(short)); - outbuf2 = newbuf; + short[] newbuf = new short[_outbuf2pos + (nsamp * 2)]; + Buffer.BlockCopy(_outbuf2, 0, newbuf, 0, _outbuf2pos * sizeof(short)); + _outbuf2 = newbuf; } - Buffer.BlockCopy(buf, 0, outbuf2, outbuf2pos * sizeof(short), nsamp * 2 * sizeof(short)); - outbuf2pos += nsamp * 2; + Buffer.BlockCopy(buf, 0, _outbuf2, _outbuf2pos * sizeof(short), nsamp * 2 * sizeof(short)); + _outbuf2pos += nsamp * 2; } public void GetSamplesSync(out short[] samples, out int nsamp) { - if (input != null) + if (_input != null) { short[] sampin; int nsampin; - input.GetSamplesSync(out sampin, out nsampin); + _input.GetSamplesSync(out sampin, out nsampin); EnqueueSamples(sampin, nsampin); } Flush(); - nsamp = outbuf2pos / 2; - samples = outbuf2; - outbuf2pos = 0; + nsamp = _outbuf2pos / 2; + samples = _outbuf2; + _outbuf2pos = 0; } public void DiscardSamples() { - outbuf2pos = 0; + _outbuf2pos = 0; } public bool CanProvideAsync => false; @@ -472,4 +459,3 @@ namespace BizHawk.Emulation.Common } } } - diff --git a/BizHawk.sln.DotSettings b/BizHawk.sln.DotSettings index a25293a148..27fcc51753 100644 --- a/BizHawk.sln.DotSettings +++ b/BizHawk.sln.DotSettings @@ -28,6 +28,7 @@ CGB CRC DB + DC DMG GB GBA