From 001b28c60eb91cb4d50ee155d601ccd16de49e42 Mon Sep 17 00:00:00 2001 From: goyuken Date: Fri, 7 Sep 2012 18:49:18 +0000 Subject: [PATCH] replace junk and bad license resamplers with libspeexdsp (using p/invoke). MIT licensed, sounds pretty decent. the p/invoke wrapper class is a hackjob i was using for testing and will be replaced. --- BizHawk.Emulation/BizHawk.Emulation.csproj | 8 +- .../Consoles/Nintendo/SNES/LibsnesCore.cs | 12 +- .../Sound/Utilities/CubicResampler.cs | 87 --- .../Sound/Utilities/DualSound.cs | 109 --- .../Sound/Utilities/FilterKit.cs | 263 ------- .../Sound/Utilities/IStereoResampler.cs | 27 - .../Sound/Utilities/LinearResampler.cs | 70 -- .../Sound/Utilities/Resampler.cs | 648 ------------------ .../Sound/Utilities/SampleBuffers.cs | 50 -- .../Sound/Utilities/SpeexResampler.cs | 313 +++++++++ BizHawk.MultiClient/output/libspeexdsp.dll | Bin 0 -> 157184 bytes 11 files changed, 322 insertions(+), 1265 deletions(-) delete mode 100644 BizHawk.Emulation/Sound/Utilities/CubicResampler.cs delete mode 100644 BizHawk.Emulation/Sound/Utilities/DualSound.cs delete mode 100644 BizHawk.Emulation/Sound/Utilities/FilterKit.cs delete mode 100644 BizHawk.Emulation/Sound/Utilities/IStereoResampler.cs delete mode 100644 BizHawk.Emulation/Sound/Utilities/LinearResampler.cs delete mode 100644 BizHawk.Emulation/Sound/Utilities/Resampler.cs delete mode 100644 BizHawk.Emulation/Sound/Utilities/SampleBuffers.cs create mode 100644 BizHawk.Emulation/Sound/Utilities/SpeexResampler.cs create mode 100644 BizHawk.MultiClient/output/libspeexdsp.dll diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj index 8a14f61da8..9ec852fc16 100644 --- a/BizHawk.Emulation/BizHawk.Emulation.csproj +++ b/BizHawk.Emulation/BizHawk.Emulation.csproj @@ -356,14 +356,8 @@ - - - - - - - + diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index b333a1b382..bdda651f58 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -490,15 +490,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES /// actual sampling factor used const double resamplingfactor = 44100.0 / 32040.5; - Sound.Utilities.IStereoResampler resampler = new Sound.Utilities.BizhawkResampler(false); + //Sound.Utilities.IStereoResampler resampler = new Sound.Utilities.BizhawkResampler(false); + //Sound.Utilities.IStereoResampler resampler = new Sound.Utilities.SinkResampler(12); //Sound.Utilities.IStereoResampler resampler = new Sound.Utilities.CubicResampler(); //Sound.Utilities.IStereoResampler resampler = new Sound.Utilities.LinearResampler(); + Sound.Utilities.SpeexResampler resampler = new Sound.Utilities.SpeexResampler(6); Sound.MetaspuSoundProvider metaspu = new Sound.MetaspuSoundProvider(Sound.ESynchMethod.ESynchMethod_V); void snes_audio_sample(ushort left, ushort right) { - + AudioInBuffer.Enqueue((short)left); AudioInBuffer.Enqueue((short)right); @@ -537,8 +539,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES if (true) { - resampler.ResampleChunk(AudioInBuffer, AudioOutBuffer, false); - + //lock (AudioInBuffer) + //{ + resampler.ResampleChunk(AudioInBuffer, AudioOutBuffer, false); + //} // drain into the metaspu immediately // we could skip this step and drain directly by changing SampleBuffers implementation while (AudioOutBuffer.Count > 0) diff --git a/BizHawk.Emulation/Sound/Utilities/CubicResampler.cs b/BizHawk.Emulation/Sound/Utilities/CubicResampler.cs deleted file mode 100644 index 0e99066b9e..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/CubicResampler.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - /// - /// a simple cubic interpolation resampler. no lowpass. original code - /// - public class CubicResampler : IStereoResampler - { - int[] data = new int[8]; - - double mu; - /// input rate / output rate - double ratio; - - public CubicResampler() - { - } - - public void StartSession(double ratio) - { - this.ratio = 1.0 / ratio; - mu = 0.0; - for (int i = 0; i < data.Length; i++) - data[i] = 0; - } - - public void ResampleChunk(Queue input, Queue output, bool finish) - { - while (true) - { - while (mu >= 1.0 && input.Count >= 2) - { - mu -= 1.0; - for (int i = 0; i < 6; i++) - data[i] = data[i + 2]; - data[6] = input.Dequeue(); - data[7] = input.Dequeue(); - } - if (mu >= 1.0) - return; - - double mu2 = mu * mu; - double mu3 = mu2 * mu2; - - int l0 = data[6] - data[4] - data[0] + data[2]; - int l1 = data[0] - data[2] - l0; - int l2 = data[4] - data[0]; - int l3 = data[2]; - - int r0 = data[7] - data[5] - data[1] + data[3]; - int r1 = data[1] - data[3] - r0; - int r2 = data[5] - data[1]; - int r3 = data[3]; - - double ls = l0 * mu3 + l1 * mu2 + l2 * mu + l3; - double rs = r0 * mu3 + r1 * mu2 + r2 * mu + r3; - - short l, r; - - if (ls > 32767.0) - l = 32767; - else if (ls < -32768.0) - l = -32768; - else - l = (short)ls; - - if (rs > 32767.0) - r = 32767; - else if (ls < -32768.0) - r = -32768; - else - r = (short)ls; - - output.Enqueue(l); - output.Enqueue(r); - - mu += ratio; - - } - - } - } -} diff --git a/BizHawk.Emulation/Sound/Utilities/DualSound.cs b/BizHawk.Emulation/Sound/Utilities/DualSound.cs deleted file mode 100644 index a84c5bccc4..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/DualSound.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - /// - /// provides pass-through sound for the dumping tool to use, while making a "best effort" - /// to have something available for audio output - /// - public class DualSound : ISoundProvider - { - /// - /// implementation of a "slave" ISoundProvider that recieves best effort audio - /// - class SecondPin : ISoundProvider - { - /// - /// the source to draw from - /// - DualSound master; - - public SecondPin(DualSound master) - { - this.master = master; - } - - public void GetSamples(short[] samples) - { - int i; - for (i = 0; i < Math.Min(samples.Length, master.ringbuffer.Count); i++) - samples[i] = master.ringbuffer.Dequeue(); - for (; i < samples.Length; i++) - // underflow - samples[i] = 0; - } - - public void DiscardSamples() - { - master.ringbuffer.Clear(); - } - - public int MaxVolume - { - // ignored - get; - set; - } - } - - /// - /// original input source - /// - ISoundProvider input; - - /// - /// threshold at which to discard samples - /// - int killsize; - - /// - /// storage of samples waiting to go to second pin - /// - Queue ringbuffer; - - /// - /// get the slave pin - /// - public ISoundProvider secondpin - { - get; - private set; - } - - /// - /// default constructor - /// - /// the ISoundProvider to use as input - /// how many sample pairs to save for the second pin - public DualSound(ISoundProvider input, int buffsize) - { - this.input = input; - killsize = buffsize * 2; - ringbuffer = new Queue(killsize); - secondpin = new SecondPin(this); - } - - public void GetSamples(short[] samples) - { - input.GetSamples(samples); - if (ringbuffer.Count >= killsize) - ringbuffer.Clear(); - foreach (var sample in samples) - ringbuffer.Enqueue(sample); - } - - public void DiscardSamples() - { - throw new Exception("Dumpers should never discard samples!"); - } - - public int MaxVolume - { - get { return input.MaxVolume; } - set { input.MaxVolume = value; } - } - } -} diff --git a/BizHawk.Emulation/Sound/Utilities/FilterKit.cs b/BizHawk.Emulation/Sound/Utilities/FilterKit.cs deleted file mode 100644 index 5a696caedc..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/FilterKit.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - /****************************************************************************** - * - * libresample4j - * Copyright (c) 2009 Laszlo Systems, Inc. All Rights Reserved. - * - * libresample4j is a Java port of Dominic Mazzoni's libresample 0.1.3, - * which is in turn based on Julius Smith's Resample 1.7 library. - * http://www-ccrma.stanford.edu/~jos/resample/ - * - * License: LGPL -- see the file LICENSE.txt for more information - * - *****************************************************************************/ - - /** - * This file provides Kaiser-windowed low-pass filter support, - * including a function to create the filter coefficients, and - * two functions to apply the filter at a particular point. - * - *
-	 * reference: "Digital Filters, 2nd edition"
-	 *            R.W. Hamming, pp. 178-179
-	 *
-	 * Izero() computes the 0th order modified bessel function of the first kind.
-	 *    (Needed to compute Kaiser window).
-	 *
-	 * LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with
-	 *    the following characteristics:
-	 *
-	 *       c[]  = array in which to store computed coeffs
-	 *       frq  = roll-off frequency of filter
-	 *       N    = Half the window length in number of coeffs
-	 *       Beta = parameter of Kaiser window
-	 *       Num  = number of coeffs before 1/frq
-	 *
-	 * Beta trades the rejection of the lowpass filter against the transition
-	 *    width from passband to stopband.  Larger Beta means a slower
-	 *    transition and greater stopband rejection.  See Rabiner and Gold
-	 *    (Theory and Application of DSP) under Kaiser windows for more about
-	 *    Beta.  The following table from Rabiner and Gold gives some feel
-	 *    for the effect of Beta:
-	 *
-	 * All ripples in dB, width of transition band = D*N where N = window length
-	 *
-	 *               BETA    D       PB RIP   SB RIP
-	 *               2.120   1.50  +-0.27      -30
-	 *               3.384   2.23    0.0864    -40
-	 *               4.538   2.93    0.0274    -50
-	 *               5.658   3.62    0.00868   -60
-	 *               6.764   4.32    0.00275   -70
-	 *               7.865   5.0     0.000868  -80
-	 *               8.960   5.7     0.000275  -90
-	 *               10.056  6.4     0.000087  -100
-	 * 
- */ - public static class FilterKit - { - - // Max error acceptable in Izero - private static double IzeroEPSILON = 1E-21; - - private static double Izero(double x) - { - double sum, u, halfx, temp; - int n; - - sum = u = n = 1; - halfx = x / 2.0; - do - { - temp = halfx / (double)n; - n += 1; - temp *= temp; - u *= temp; - sum += u; - } while (u >= IzeroEPSILON * sum); - return (sum); - } - - public static void lrsLpFilter(double[] c, int N, double frq, double Beta, int Num) - { - double IBeta, temp, temp1, inm1; - int i; - - // Calculate ideal lowpass filter impulse response coefficients: - c[0] = 2.0 * frq; - for (i = 1; i < N; i++) - { - temp = Math.PI * (double)i / (double)Num; - c[i] = Math.Sin(2.0 * temp * frq) / temp; // Analog sinc function, - // cutoff = frq - } - - /* - * Calculate and Apply Kaiser window to ideal lowpass filter. Note: last - * window value is IBeta which is NOT zero. You're supposed to really - * truncate the window here, not ramp it to zero. This helps reduce the - * first sidelobe. - */ - IBeta = 1.0 / Izero(Beta); - inm1 = 1.0 / ((double)(N - 1)); - for (i = 1; i < N; i++) - { - temp = (double)i * inm1; - temp1 = 1.0 - temp * temp; - temp1 = (temp1 < 0 ? 0 : temp1); /* - * make sure it's not negative - * since we're taking the square - * root - this happens on Pentium - * 4's due to tiny roundoff errors - */ - c[i] *= Izero(Beta * Math.Sqrt(temp1)) * IBeta; - } - } - - /// - /// - /// - /// impulse response - /// impulse response deltas - /// length of one wing of filter - /// Interpolate coefs using deltas? - /// Current sample array - /// Current sample index - /// Phase - /// increment (1 for right wing or -1 for left) - /// - public static float lrsFilterUp(float[] Imp, float[] ImpD, int Nwing, bool Interp, float[] Xp_array, int Xp_index, double Ph, int Inc) - { - double a = 0; - float v, t; - - Ph *= Resampler.Npc; // Npc is number of values per 1/delta in impulse - // response - - v = 0.0f; // The output value - - float[] Hp_array = Imp; - int Hp_index = (int)Ph; - - float[] End_array = Imp; - int End_index = Nwing; - - float[] Hdp_array = ImpD; - int Hdp_index = (int)Ph; - - if (Interp) - { - // Hdp = &ImpD[(int)Ph]; - a = Ph - Math.Floor(Ph); /* fractional part of Phase */ - } - - if (Inc == 1) // If doing right wing... - { // ...drop extra coeff, so when Ph is - End_index--; // 0.5, we don't do too many mult's - if (Ph == 0) // If the phase is zero... - { // ...then we've already skipped the - Hp_index += Resampler.Npc; // first sample, so we must also - Hdp_index += Resampler.Npc; // skip ahead in Imp[] and ImpD[] - } - } - - if (Interp) - while (Hp_index < End_index) - { - t = Hp_array[Hp_index]; /* Get filter coeff */ - t += (float)(Hdp_array[Hdp_index] * a); /* t is now interp'd filter coeff */ - Hdp_index += Resampler.Npc; /* Filter coeff differences step */ - t *= Xp_array[Xp_index]; /* Mult coeff by input sample */ - v += t; /* The filter output */ - Hp_index += Resampler.Npc; /* Filter coeff step */ - Xp_index += Inc; /* Input signal step. NO CHECK ON BOUNDS */ - } - else - while (Hp_index < End_index) - { - t = Hp_array[Hp_index]; /* Get filter coeff */ - t *= Xp_array[Xp_index]; /* Mult coeff by input sample */ - v += t; /* The filter output */ - Hp_index += Resampler.Npc; /* Filter coeff step */ - Xp_index += Inc; /* Input signal step. NO CHECK ON BOUNDS */ - } - - return v; - } - - /// - /// - /// - /// impulse response - /// impulse response deltas - /// length of one wing of filter - /// Interpolate coefs using deltas? - /// Current sample array - /// Current sample index - /// Phase - /// increment (1 for right wing or -1 for left) - /// filter sampling period - /// - public static float lrsFilterUD(float[] Imp, float[] ImpD, int Nwing, bool Interp, float[] Xp_array, int Xp_index, double Ph, int Inc, double dhb) - { - float a; - float v, t; - double Ho; - - v = 0.0f; // The output value - Ho = Ph * dhb; - - float[] End_array = Imp; - int End_index = Nwing; - - if (Inc == 1) // If doing right wing... - { // ...drop extra coeff, so when Ph is - End_index--; // 0.5, we don't do too many mult's - if (Ph == 0) // If the phase is zero... - Ho += dhb; // ...then we've already skipped the - } // first sample, so we must also - // skip ahead in Imp[] and ImpD[] - - float[] Hp_array = Imp; - int Hp_index; - - if (Interp) - { - float[] Hdp_array = ImpD; - int Hdp_index; - - while ((Hp_index = (int)Ho) < End_index) - { - t = Hp_array[Hp_index]; // Get IR sample - Hdp_index = (int)Ho; // get interp bits from diff table - a = (float)(Ho - Math.Floor(Ho)); // a is logically between 0 - // and 1 - t += Hdp_array[Hdp_index] * a; // t is now interp'd filter coeff - t *= Xp_array[Xp_index]; // Mult coeff by input sample - v += t; // The filter output - Ho += dhb; // IR step - Xp_index += Inc; // Input signal step. NO CHECK ON BOUNDS - } - } - else - { - while ((Hp_index = (int)Ho) < End_index) - { - t = Hp_array[Hp_index]; // Get IR sample - t *= Xp_array[Xp_index]; // Mult coeff by input sample - v += t; // The filter output - Ho += dhb; // IR step - Xp_index += Inc; // Input signal step. NO CHECK ON BOUNDS - } - } - - return v; - } - - } -} diff --git a/BizHawk.Emulation/Sound/Utilities/IStereoResampler.cs b/BizHawk.Emulation/Sound/Utilities/IStereoResampler.cs deleted file mode 100644 index 31f6971bd5..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/IStereoResampler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - /// - /// describes an audio resampler that works with stereo streams of shorts (interleaved) - /// - public interface IStereoResampler - { - /// - /// start a resampling session, with the given conversion rate - /// - /// outrate / inrate - void StartSession(double ratio); - - /// - /// process any available input - /// - /// input samples. all might not be consumed unless finish == true - /// where to put output samples. - /// if true, consume all input and end session - void ResampleChunk(Queue input, Queue output, bool finish); - } -} diff --git a/BizHawk.Emulation/Sound/Utilities/LinearResampler.cs b/BizHawk.Emulation/Sound/Utilities/LinearResampler.cs deleted file mode 100644 index a0f2c6bf63..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/LinearResampler.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - // a simple linear resampler - public class LinearResampler : IStereoResampler - { - short[] data = new short[4]; - - double mu; - /// input rate / output rate - double ratio; - - public LinearResampler() - { - } - - public void StartSession(double ratio) - { - this.ratio = 1.0 / ratio; - mu = 0.0; - for (int i = 0; i < data.Length; i++) - data[i] = 0; - } - - public void ResampleChunk(Queue input, Queue output, bool finish) - { - while (true) - { - while (mu >= 1.0 && input.Count >= 2) - { - mu -= 1.0; - data[0] = data[2]; - data[1] = data[3]; - data[2] = input.Dequeue(); - data[3] = input.Dequeue(); - } - if (mu >= 1.0) - return; - - double ls = data[0] * (1.0 - mu) + data[1] * mu; - double rs = data[1] * (1.0 - mu) + data[3] * mu; - - short l, r; - - if (ls > 32767.0) - l = 32767; - else if (ls < -32768.0) - l = -32768; - else - l = (short)ls; - - if (rs > 32767.0) - r = 32767; - else if (ls < -32768.0) - r = -32768; - else - r = (short)ls; - - output.Enqueue(l); - output.Enqueue(r); - - mu += ratio; - } - } - } -} diff --git a/BizHawk.Emulation/Sound/Utilities/Resampler.cs b/BizHawk.Emulation/Sound/Utilities/Resampler.cs deleted file mode 100644 index 346eaa6a62..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/Resampler.cs +++ /dev/null @@ -1,648 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - /****************************************************************************** - * - * libresample4j - * Copyright (c) 2009 Laszlo Systems, Inc. All Rights Reserved. - * - * libresample4j is a Java port of Dominic Mazzoni's libresample 0.1.3, - * which is in turn based on Julius Smith's Resample 1.7 library. - * http://www-ccrma.stanford.edu/~jos/resample/ - * - * License: LGPL -- see the file LICENSE.txt for more information - * - *****************************************************************************/ - - //import java.nio.FloatBuffer; - - public class Resampler - { - - public class Result - { - public int inputSamplesConsumed { get; private set; } - public int outputSamplesGenerated { get; private set; } - - public Result(int inputSamplesConsumed, int outputSamplesGenerated) - { - this.inputSamplesConsumed = inputSamplesConsumed; - this.outputSamplesGenerated = outputSamplesGenerated; - } - } - - /// number of values per 1/delta in impulse response - public const int Npc = 4096; - - private float[] Imp; - private float[] ImpD; - private float LpScl; - private int Nmult; - private int Nwing; - private double minFactor; - private double maxFactor; - private int XSize; - private float[] X; - /// - /// Current "now"-sample pointer for input - /// - private int Xp; - /// - /// Position to put new samples - /// - private int Xread; - private int Xoff; - private float[] Y; - private int Yp; - private double Time; - - /** - * Clone an existing resampling session. Faster than creating one from scratch. - * - * @param other - */ - public Resampler(Resampler other) - { - this.Imp = (float[])other.Imp.Clone(); - this.ImpD = (float[])other.ImpD.Clone(); - this.LpScl = other.LpScl; - this.Nmult = other.Nmult; - this.Nwing = other.Nwing; - this.minFactor = other.minFactor; - this.maxFactor = other.maxFactor; - this.XSize = other.XSize; - this.X = (float[])other.X.Clone(); - this.Xp = other.Xp; - this.Xread = other.Xread; - this.Xoff = other.Xoff; - this.Y = (float[])other.Y.Clone(); - this.Yp = other.Yp; - this.Time = other.Time; - } - - /** - * Create a new resampling session. - * - * @param highQuality true for better quality, slower processing time - * @param minFactor lower bound on resampling factor for this session - * @param maxFactor upper bound on resampling factor for this session - * @throws IllegalArgumentException if minFactor or maxFactor is not - * positive, or if maxFactor is less than minFactor - */ - public Resampler(bool highQuality, double minFactor, double maxFactor) - { - if (minFactor <= 0.0 || maxFactor <= 0.0) - throw new ArgumentException("minFactor and maxFactor must be positive"); - - if (maxFactor < minFactor) - throw new ArgumentException("minFactor must be <= maxFactor"); - - this.minFactor = minFactor; - this.maxFactor = maxFactor; - this.Nmult = highQuality ? 35 : 11; - this.LpScl = 1.0f; - this.Nwing = Npc * (this.Nmult - 1) / 2; // # of filter coeffs in right wing - - double Rolloff = 0.90; - double Beta = 6; - - double[] Imp64 = new double[this.Nwing]; - - FilterKit.lrsLpFilter(Imp64, this.Nwing, 0.5 * Rolloff, Beta, Npc); - this.Imp = new float[this.Nwing]; - this.ImpD = new float[this.Nwing]; - - for (int i = 0; i < this.Nwing; i++) - { - this.Imp[i] = (float)Imp64[i]; - } - - // Storing deltas in ImpD makes linear interpolation - // of the filter coefficients faster - for (int i = 0; i < this.Nwing - 1; i++) - { - this.ImpD[i] = this.Imp[i + 1] - this.Imp[i]; - } - - // Last coeff. not interpolated - this.ImpD[this.Nwing - 1] = -this.Imp[this.Nwing - 1]; - - // Calc reach of LP filter wing (plus some creeping room) - int Xoff_min = (int)(((this.Nmult + 1) / 2.0) * Math.Max(1.0, 1.0 / minFactor) + 10); - int Xoff_max = (int)(((this.Nmult + 1) / 2.0) * Math.Max(1.0, 1.0 / maxFactor) + 10); - this.Xoff = Math.Max(Xoff_min, Xoff_max); - - // Make the inBuffer size at least 4096, but larger if necessary - // in order to store the minimum reach of the LP filter and then some. - // Then allocate the buffer an extra Xoff larger so that - // we can zero-pad up to Xoff zeros at the end when we reach the - // end of the input samples. - this.XSize = Math.Max(2 * this.Xoff + 10, 4096); - this.X = new float[this.XSize + this.Xoff]; - this.Xp = this.Xoff; - this.Xread = this.Xoff; - - // Make the outBuffer long enough to hold the entire processed - // output of one inBuffer - int YSize = (int)(((double)this.XSize) * maxFactor + 2.0); - this.Y = new float[YSize]; - this.Yp = 0; - - this.Time = (double)this.Xoff; // Current-time pointer for converter - } - - public int getFilterWidth() - { - return this.Xoff; - } - - /** - * Process a batch of samples. There is no guarantee that the input buffer will be drained. - * - * @param factor factor at which to resample this batch - * @param buffers sample buffer for producing input and consuming output - * @param lastBatch true if this is known to be the last batch of samples - * @return true iff resampling is complete (ie. no input samples consumed and no output samples produced) - */ - public bool process(double factor, SampleBuffers buffers, bool lastBatch) - { - if (factor < this.minFactor || factor > this.maxFactor) - { - throw new ArgumentException("factor " + factor + " is not between minFactor=" + minFactor - + " and maxFactor=" + maxFactor); - } - - int outBufferLen = buffers.getOutputBufferLength(); - int inBufferLen = buffers.getInputBufferLength(); - - float[] Imp = this.Imp; - float[] ImpD = this.ImpD; - float LpScl = this.LpScl; - int Nwing = this.Nwing; - bool interpFilt = false; // TRUE means interpolate filter coeffs - - int inBufferUsed = 0; - int outSampleCount = 0; - - // Start by copying any samples still in the Y buffer to the output - // buffer - if ((this.Yp != 0) && (outBufferLen - outSampleCount) > 0) - { - int len = Math.Min(outBufferLen - outSampleCount, this.Yp); - - buffers.consumeOutput(this.Y, 0, len); - //for (int i = 0; i < len; i++) { - // outBuffer[outBufferOffset + outSampleCount + i] = this.Y[i]; - //} - - outSampleCount += len; - for (int i = 0; i < this.Yp - len; i++) - { - this.Y[i] = this.Y[i + len]; - } - this.Yp -= len; - } - - // If there are still output samples left, return now - we need - // the full output buffer available to us... - if (this.Yp != 0) - { - return inBufferUsed == 0 && outSampleCount == 0; - } - - // Account for increased filter gain when using factors less than 1 - if (factor < 1) - { - LpScl = (float)(LpScl * factor); - } - - while (true) - { - - // This is the maximum number of samples we can process - // per loop iteration - - /* - * #ifdef DEBUG - * printf("XSize: %d Xoff: %d Xread: %d Xp: %d lastFlag: %d\n", - * this.XSize, this.Xoff, this.Xread, this.Xp, lastFlag); #endif - */ - - // Copy as many samples as we can from the input buffer into X - int len = this.XSize - this.Xread; - - if (len >= inBufferLen - inBufferUsed) - { - len = inBufferLen - inBufferUsed; - } - - buffers.produceInput(this.X, this.Xread, len); - //for (int i = 0; i < len; i++) { - // this.X[this.Xread + i] = inBuffer[inBufferOffset + inBufferUsed + i]; - //} - - inBufferUsed += len; - this.Xread += len; - - int Nx; - if (lastBatch && (inBufferUsed == inBufferLen)) - { - // If these are the last samples, zero-pad the - // end of the input buffer and make sure we process - // all the way to the end - Nx = this.Xread - this.Xoff; - for (int i = 0; i < this.Xoff; i++) - { - this.X[this.Xread + i] = 0; - } - } - else - { - Nx = this.Xread - 2 * this.Xoff; - } - - /* - * #ifdef DEBUG fprintf(stderr, "new len=%d Nx=%d\n", len, Nx); - * #endif - */ - - if (Nx <= 0) - { - break; - } - - // Resample stuff in input buffer - int Nout; - if (factor >= 1) - { // SrcUp() is faster if we can use it */ - Nout = lrsSrcUp(this.X, this.Y, factor, /* &this.Time, */Nx, Nwing, LpScl, Imp, ImpD, interpFilt); - } - else - { - Nout = lrsSrcUD(this.X, this.Y, factor, /* &this.Time, */Nx, Nwing, LpScl, Imp, ImpD, interpFilt); - } - - /* - * #ifdef DEBUG - * printf("Nout: %d\n", Nout); - * #endif - */ - - this.Time -= Nx; // Move converter Nx samples back in time - this.Xp += Nx; // Advance by number of samples processed - - // Calc time accumulation in Time - int Ncreep = (int)(this.Time) - this.Xoff; - if (Ncreep != 0) - { - this.Time -= Ncreep; // Remove time accumulation - this.Xp += Ncreep; // and add it to read pointer - } - - // Copy part of input signal that must be re-used - int Nreuse = this.Xread - (this.Xp - this.Xoff); - - for (int i = 0; i < Nreuse; i++) - { - this.X[i] = this.X[i + (this.Xp - this.Xoff)]; - } - - /* - #ifdef DEBUG - printf("New Xread=%d\n", Nreuse); - #endif */ - - this.Xread = Nreuse; // Pos in input buff to read new data into - this.Xp = this.Xoff; - - this.Yp = Nout; - - // Copy as many samples as possible to the output buffer - if (this.Yp != 0 && (outBufferLen - outSampleCount) > 0) - { - len = Math.Min(outBufferLen - outSampleCount, this.Yp); - - buffers.consumeOutput(this.Y, 0, len); - //for (int i = 0; i < len; i++) { - // outBuffer[outBufferOffset + outSampleCount + i] = this.Y[i]; - //} - - outSampleCount += len; - for (int i = 0; i < this.Yp - len; i++) - { - this.Y[i] = this.Y[i + len]; - } - this.Yp -= len; - } - - // If there are still output samples left, return now, - // since we need the full output buffer available - if (this.Yp != 0) - { - break; - } - } - - return inBufferUsed == 0 && outSampleCount == 0; - } - - /** - * Process a batch of samples. Convenience method for when the input and output are both floats. - * - * @param factor factor at which to resample this batch - * @param inputBuffer contains input samples in the range -1.0 to 1.0 - * @param outputBuffer output samples will be deposited here - * @param lastBatch true if this is known to be the last batch of samples - * @return true iff resampling is complete (ie. no input samples consumed and no output samples produced) - */ - /* - public bool process(double factor, FloatBuffer inputBuffer, bool lastBatch, FloatBuffer outputBuffer) { - SampleBuffers sampleBuffers = new SampleBuffers() { - public int getInputBufferLength() { - return inputBuffer.remaining(); - } - - public int getOutputBufferLength() { - return outputBuffer.remaining(); - } - - public void produceInput(float[] array, int offset, int length) { - inputBuffer.get(array, offset, length); - } - - public void consumeOutput(float[] array, int offset, int length) { - outputBuffer.put(array, offset, length); - } - }; - return process(factor, sampleBuffers, lastBatch); - } - */ - - /** - * Process a batch of samples. Alternative interface if you prefer to work with arrays. - * - * @param factor resampling rate for this batch - * @param inBuffer array containing input samples in the range -1.0 to 1.0 - * @param inBufferOffset offset into inBuffer at which to start processing - * @param inBufferLen number of valid elements in the inputBuffer - * @param lastBatch pass true if this is the last batch of samples - * @param outBuffer array to hold the resampled data - * @return the number of samples consumed and generated - */ - /* - public Result process(double factor, float[] inBuffer, int inBufferOffset, int inBufferLen, boolean lastBatch, float[] outBuffer, int outBufferOffset, int outBufferLen) { - FloatBuffer inputBuffer = FloatBuffer.wrap(inBuffer, inBufferOffset, inBufferLen); - FloatBuffer outputBuffer = FloatBuffer.wrap(outBuffer, outBufferOffset, outBufferLen); - - process(factor, inputBuffer, lastBatch, outputBuffer); - - return new Result(inputBuffer.position() - inBufferOffset, outputBuffer.position() - outBufferOffset); - } - */ - - /// - /// Sampling rate up-conversion only subroutine; Slightly faster than down-conversion - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - private int lrsSrcUp(float[] X, float[] Y, double factor, int Nx, int Nwing, float LpScl, float[] Imp, - float[] ImpD, bool Interp) - { - - float[] Xp_array = X; - int Xp_index; - - float[] Yp_array = Y; - int Yp_index = 0; - - float v; - - double CurrentTime = this.Time; - double dt; // Step through input signal - double endTime; // When Time reaches EndTime, return to user - - dt = 1.0 / factor; // Output sampling period - - endTime = CurrentTime + Nx; - while (CurrentTime < endTime) - { - double LeftPhase = CurrentTime - Math.Floor(CurrentTime); - double RightPhase = 1.0 - LeftPhase; - - Xp_index = (int)CurrentTime; // Ptr to current input sample - // Perform left-wing inner product - v = FilterKit.lrsFilterUp(Imp, ImpD, Nwing, Interp, Xp_array, Xp_index++, LeftPhase, -1); - // Perform right-wing inner product - v += FilterKit.lrsFilterUp(Imp, ImpD, Nwing, Interp, Xp_array, Xp_index, RightPhase, 1); - - v *= LpScl; // Normalize for unity filter gain - - Yp_array[Yp_index++] = v; // Deposit output - CurrentTime += dt; // Move to next sample by time increment - } - - this.Time = CurrentTime; - return Yp_index; // Return the number of output samples - } - - private int lrsSrcUD(float[] X, float[] Y, double factor, int Nx, int Nwing, float LpScl, float[] Imp, - float[] ImpD, bool Interp) - { - - float[] Xp_array = X; - int Xp_index; - - float[] Yp_array = Y; - int Yp_index = 0; - - float v; - - double CurrentTime = this.Time; - double dh; // Step through filter impulse response - double dt; // Step through input signal - double endTime; // When Time reaches EndTime, return to user - - dt = 1.0 / factor; // Output sampling period - - dh = Math.Min(Npc, factor * Npc); // Filter sampling period - - endTime = CurrentTime + Nx; - while (CurrentTime < endTime) - { - double LeftPhase = CurrentTime - Math.Floor(CurrentTime); - double RightPhase = 1.0 - LeftPhase; - - Xp_index = (int)CurrentTime; // Ptr to current input sample - // Perform left-wing inner product - v = FilterKit.lrsFilterUD(Imp, ImpD, Nwing, Interp, Xp_array, Xp_index++, LeftPhase, -1, dh); - // Perform right-wing inner product - v += FilterKit.lrsFilterUD(Imp, ImpD, Nwing, Interp, Xp_array, Xp_index, RightPhase, 1, dh); - - v *= LpScl; // Normalize for unity filter gain - - Yp_array[Yp_index++] = v; // Deposit output - - CurrentTime += dt; // Move to next sample by time increment - } - - this.Time = CurrentTime; - return Yp_index; // Return the number of output samples - } - - } - - /// - /// implements a pair of Resamplers that work off of interleaved stereo buffers of shorts - /// this is what's used inside most of bizhawk - /// - public class BizhawkResampler : IStereoResampler - { - bool highQuality; - double ratio; - - public void StartSession(double ratio) - { - this.ratio = ratio; - left = new Resampler(highQuality, ratio, ratio); - right = new Resampler(highQuality, ratio, ratio); - } - - public void ResampleChunk(Queue input, Queue output, bool finish) - { - LeftBuffer lb = new LeftBuffer(input, output); - - SampleBuffers rb = lb.GetRightBuffer(); - - bool doneleft = left.process(ratio, lb, finish); - bool doneright = right.process(ratio, rb, finish); - - if (finish) - { - left = null; - right = null; - } - } - - private Resampler left; - private Resampler right; - - /// - /// - /// - /// true for high quality resampling - public BizhawkResampler(bool highQuality) - { - this.highQuality = highQuality; - } - - /// - /// ugly wrapper class that handles interleaved writes and reads - /// made under the assumption that LeftBuffer gets called first - /// both buffers must consume and produce the same amount of data, or else - /// - class LeftBuffer : SampleBuffers - { - int inbufferlen; - - Queue input; - Queue output; - - Queue rightin = new Queue(); - Queue leftout = new Queue(); - - RightBuffer child; - - public SampleBuffers GetRightBuffer() - { - return child; - } - - public LeftBuffer(Queue input, Queue output) - { - this.input = input; - this.output = output; - if (input.Count % 2 != 0) - throw new ArgumentException("Input must contain an even number of samples! (stereo stacked)"); - inbufferlen = input.Count / 2; - child = new RightBuffer(this); - } - - public int getInputBufferLength() - { - return inbufferlen; - } - - public int getOutputBufferLength() - { - // queues resize, so don't care - return 1000000; - } - - public void produceInput(float[] array, int offset, int length) - { - for (int i = offset; i < length + offset; i++) - { - // remove left sample - short left = input.Dequeue(); - // remove right sample and save for later - rightin.Enqueue(input.Dequeue()); - - array[i] = left / 32768.0f; - } - } - - public void consumeOutput(float[] array, int offset, int length) - { - for (int i = offset; i < length + offset; i++) - leftout.Enqueue(array[i]); - } - - class RightBuffer : SampleBuffers - { - LeftBuffer parent; - public RightBuffer(LeftBuffer parent) - { - this.parent = parent; - } - - public int getInputBufferLength() - { - return parent.getInputBufferLength(); - } - - public int getOutputBufferLength() - { - return parent.getOutputBufferLength(); - } - - public void produceInput(float[] array, int offset, int length) - { - for (int i = offset; i < length + offset; i++) - array[i] = parent.rightin.Dequeue() / 32768.0f; - } - - public void consumeOutput(float[] array, int offset, int length) - { - for (int i = offset; i < length + offset; i++) - { - parent.output.Enqueue((short)(parent.leftout.Dequeue() * 32768.0f)); - parent.output.Enqueue((short)(array[i] * 32768.0f)); - } - } - } - } - } - -} diff --git a/BizHawk.Emulation/Sound/Utilities/SampleBuffers.cs b/BizHawk.Emulation/Sound/Utilities/SampleBuffers.cs deleted file mode 100644 index eee23758ac..0000000000 --- a/BizHawk.Emulation/Sound/Utilities/SampleBuffers.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace BizHawk.Emulation.Sound.Utilities -{ - /****************************************************************************** - * - * libresample4j - * Copyright (c) 2009 Laszlo Systems, Inc. All Rights Reserved. - * - * libresample4j is a Java port of Dominic Mazzoni's libresample 0.1.3, - * which is in turn based on Julius Smith's Resample 1.7 library. - * http://www-ccrma.stanford.edu/~jos/resample/ - * - * License: LGPL -- see the file LICENSE.txt for more information - * - *****************************************************************************/ - - /// - /// Callback for producing and consuming samples. Enables on-the-fly conversion between sample types - /// (signed 16-bit integers to floats, for example) and/or writing directly to an output stream. - /// - public interface SampleBuffers - { - /// number of input samples available - int getInputBufferLength(); - - /// number of samples the output buffer has room for - int getOutputBufferLength(); - - /// - /// Copy length samples from the input buffer to the given array, starting at the given offset. - /// Samples should be in the range -1.0f to 1.0f. - /// - /// array to hold samples from the input buffer - /// start writing samples here - /// write this many samples - void produceInput(float[] array, int offset, int length); - - /// - /// Copy length samples from the given array to the output buffer, starting at the given offset. - /// - /// array to read from - /// start reading samples here - /// read this many samples - void consumeOutput(float[] array, int offset, int length); - } -} diff --git a/BizHawk.Emulation/Sound/Utilities/SpeexResampler.cs b/BizHawk.Emulation/Sound/Utilities/SpeexResampler.cs new file mode 100644 index 0000000000..ea95eed21b --- /dev/null +++ b/BizHawk.Emulation/Sound/Utilities/SpeexResampler.cs @@ -0,0 +1,313 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace BizHawk.Emulation.Sound.Utilities +{ + /// + /// junk wrapper around LibSpeexDSP. quite inefficient. will be replaced + /// + public class SpeexResampler + { + static class LibSpeexDSP + { + public const int QUALITY_MAX = 10; + public const int QUALITY_MIN = 0; + public const int QUALITY_DEFAULT = 4; + public const int QUALITY_VOIP = 3; + public const int QUALITY_DESKTOP = 5; + + public enum RESAMPLER_ERR + { + SUCCESS = 0, + ALLOC_FAILED = 1, + BAD_STATE = 2, + INVALID_ARG = 3, + PTR_OVERLAP = 4, + MAX_ERROR + }; + + /// + /// Create a new resampler with integer input and output rates. + /// + /// Number of channels to be processed + /// Input sampling rate (integer number of Hz). + /// Output sampling rate (integer number of Hz). + /// Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality. + /// + /// Newly created resampler state + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr speex_resampler_init(uint nb_channels, uint in_rate, uint out_rate, int quality, ref RESAMPLER_ERR err); + + /// + /// Create a new resampler with fractional input/output rates. The sampling + /// rate ratio is an arbitrary rational number with both the numerator and + /// denominator being 32-bit integers. + /// + /// Number of channels to be processed + /// Numerator of the sampling rate ratio + /// 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). + /// Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality. + /// + /// Newly created resampler state + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr speex_resampler_init_frac(uint nb_channels, uint ratio_num, uint ratio_den, uint in_rate, uint out_rate, int quality, ref RESAMPLER_ERR err); + + /// + /// Destroy a resampler state. + /// + /// Resampler state + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_destroy(IntPtr st); + + /// + /// Resample a float array. The input and output buffers must *not* overlap. + /// + /// Resampler state + /// Index of the channel to process for the multi-channel base (0 otherwise) + /// Input buffer + /// 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); + + /// + /// Resample an int array. The input and output buffers must *not* overlap. + /// + /// Resampler state + /// Index of the channel to process for the multi-channel base (0 otherwise) + /// Input buffer + /// 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); + + /// + /// Resample an interleaved float array. The input and output buffers must *not* overlap. + /// + /// Resampler state + /// Input buffer + /// 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); + + /// + /// Resample an interleaved int array. The input and output buffers must *not* overlap. + /// + /// Resampler state + /// Input buffer + /// 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); + + /// + /// Set (change) the input/output sampling rates (integer value). + /// + /// 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); + + /// + /// Get the current input/output sampling rates (integer value). + /// + /// Resampler state + /// Input sampling rate (integer number of Hz) copied. + /// Output sampling rate (integer number of Hz) copied. + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_get_rate(IntPtr st, ref uint in_rate, ref uint out_rate); + + /// + /// Set (change) the input/output sampling rates and resampling ratio (fractional values in Hz supported). + /// + /// esampler state + /// Numerator of the sampling rate ratio + /// 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); + + /// + /// Get the current resampling ratio. This will be reduced to the least common denominator. + /// + /// Resampler state + /// Numerator of the sampling rate ratio copied + /// Denominator of the sampling rate ratio copied + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_get_ratio(IntPtr st, ref uint ratio_num, ref uint ratio_den); + + /// + /// Set (change) the conversion quality. + /// + /// Resampler state + /// Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality. + /// + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern RESAMPLER_ERR speex_resampler_set_quality(IntPtr st, int quality); + + /// + /// Get the conversion quality. + /// + /// Resampler state + /// Resampling quality between 0 and 10, where 0 has poor quality and 10 has very high quality. + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_get_quality(IntPtr st, ref int quality); + + /// + /// Set (change) the input stride. + /// + /// Resampler state + /// Input stride + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_set_input_stride(IntPtr st, uint stride); + + /// + /// Get the input stride. + /// + /// Resampler state + /// Input stride copied + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_get_input_stride(IntPtr st, ref uint stride); + + /// + /// Set (change) the output stride. + /// + /// Resampler state + /// Output stride + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_set_output_stride(IntPtr st, uint stride); + + /// + /// Get the output stride. + /// + /// Resampler state + /// Output stride copied + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void speex_resampler_get_output_stride(IntPtr st, ref uint stride); + + /// + /// Get the latency in input samples introduced by the resampler. + /// + /// Resampler state + /// + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int speex_resampler_get_input_latency(IntPtr st); + + /// + /// Get the latency in output samples introduced by the resampler. + /// + /// Resampler state + /// + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int speex_resampler_get_output_latency(IntPtr st); + + /// + /// Make sure that the first samples to go out of the resamplers don't have + /// leading zeros. This is only useful before starting to use a newly created + /// resampler. It is recommended to use that when resampling an audio file, as + /// it will generate a file with the same length. For real-time processing, + /// it is probably easier not to use this call (so that the output duration + /// 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); + + /// + /// 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); + + /// + /// Returns the English meaning for an error code + /// + /// Error code + /// English string + [DllImport("libspeexdsp.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern string speex_resampler_strerror(RESAMPLER_ERR err); + } + + + /// + /// opaque pointer to state + /// + IntPtr st; + + public SpeexResampler(int quality) + { + LibSpeexDSP.RESAMPLER_ERR err = 0; + + st = LibSpeexDSP.speex_resampler_init_frac(2, 64081, 88200, 32041, 44100, quality, ref err); + } + + public void StartSession(double ratio) + { + + } + + + public void ResampleChunk(Queue input, Queue output, bool finish) + { + while (input.Count > 0) + { + short[] ina = input.ToArray(); + + short[] outa = new short[8192]; + + uint inal = (uint)ina.Length / 2; + uint outal = (uint)outa.Length / 2; + + // very important: feeding too big a buffer at once causes garbage to come back + // don't know what "too big a buffer" is in general + if (inal > 512) inal = 512; + + + LibSpeexDSP.speex_resampler_process_interleaved_int(st, ina, ref inal, outa, ref outal); + + + while (inal > 0) + { + input.Dequeue(); + input.Dequeue(); + inal--; + } + + int i = 0; + if (outal == 0) + { + // resampler refuses to make more data; bail + return; + } + while (outal > 0) + { + output.Enqueue(outa[i++]); + output.Enqueue(outa[i++]); + outal--; + } + } + } + } +} + diff --git a/BizHawk.MultiClient/output/libspeexdsp.dll b/BizHawk.MultiClient/output/libspeexdsp.dll new file mode 100644 index 0000000000000000000000000000000000000000..aad1a4e7f564d5e2c7ff6714c4b58adb32f01476 GIT binary patch literal 157184 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�QAK!;P2m3)?@sDfg5eZ?Kp8 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%0Avzi8cpwjMC14^F&>=Zaw;?+T6Ct`^=Rk}|2osU~ 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

-(2vZT$Rz8 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 literal 0 HcmV?d00001