diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index e1080d4256..ef7648e3d8 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -350,6 +350,7 @@
+
diff --git a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs
index 79e3629ebe..b9ed9d68f6 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs
@@ -441,12 +441,13 @@ namespace BizHawk.Emulation.Consoles.GB
int soundbuffcontains = 0;
Sound.Utilities.SpeexResampler resampler;
- Sound.MetaspuSoundProvider metaspu;
+ ISoundProvider metaspu;
void InitSound()
{
- metaspu = new Sound.MetaspuSoundProvider(Sound.ESynchMethod.ESynchMethod_V);
+ var metaspu = new Sound.MetaspuSoundProvider(Sound.ESynchMethod.ESynchMethod_V);
resampler = new Sound.Utilities.SpeexResampler(2, 2097152, 44100, 2097152, 44100, metaspu.buffer.enqueue_samples);
+ this.metaspu = new Sound.Utilities.DCFilter(metaspu);// metaspu;
}
void DisposeSound()
diff --git a/BizHawk.Emulation/Sound/Utilities/DCFilter.cs b/BizHawk.Emulation/Sound/Utilities/DCFilter.cs
new file mode 100644
index 0000000000..e2575c6ce1
--- /dev/null
+++ b/BizHawk.Emulation/Sound/Utilities/DCFilter.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Emulation.Sound.Utilities
+{
+ ///
+ /// implements a DC block filter on top of an ISoundProvider. rather simple.
+ ///
+ public class DCFilter : ISoundProvider
+ {
+ /*
+ * A note about accuracy:
+ *
+ * DCFilter can be added to the final output of any console, and this change will be faithful to the original hardware.
+ * Analog output hardware ALWAYS has dc blocking caps.
+ */
+
+ ISoundProvider input;
+
+ int sumL = 0;
+ int sumR = 0;
+
+ Queue buffer;
+
+ const int depth = 65536;
+
+ public DCFilter(ISoundProvider input)
+ {
+ this.input = input;
+ this.buffer = new Queue(depth * 2);
+ for (int i = 0; i < depth * 2; i++)
+ buffer.Enqueue(0);
+ }
+
+ ///
+ /// returns the original sound provider (in case you lost it).
+ /// after calling, the DCFilter is no longer valid
+ ///
+ ///
+ public ISoundProvider Detatch()
+ {
+ var ret = input;
+ input = null;
+ return ret;
+ }
+
+ public void GetSamples(short[] samples)
+ {
+
+ input.GetSamples(samples);
+
+ for (int i = 0; i < samples.Length; i += 2)
+ {
+ sumL -= buffer.Dequeue();
+ sumR -= buffer.Dequeue();
+ short L = samples[i];
+ short R = samples[i + 1];
+ sumL += L;
+ sumR += R;
+ buffer.Enqueue(L);
+ buffer.Enqueue(R);
+ int bigL = L - (sumL >> 16); // / depth;
+ int bigR = R - (sumR >> 16); // / depth;
+ // check for clipping
+ if (bigL > 32767)
+ samples[i] = 32767;
+ else if (bigL < -32768)
+ samples[i] = -32768;
+ else
+ samples[i] = (short)bigL;
+ if (bigR > 32767)
+ samples[i + 1] = 32767;
+ else if (bigR < -32768)
+ samples[i + 1] = -32768;
+ else
+ samples[i + 1] = (short)bigR;
+
+ }
+ }
+
+ public void DiscardSamples()
+ {
+ input.DiscardSamples();
+ }
+
+ public int MaxVolume
+ {
+ get
+ {
+ return input.MaxVolume;
+ }
+ set
+ {
+ input.MaxVolume = value;
+ }
+ }
+ }
+}