add Sound.Utilities.DCFilter and use it in gambatte

haven't decided yet whether i like the idea; it's mostly about playing nice with other audio mixing (from other applications)
well, it's not bad anyway...
This commit is contained in:
goyuken 2012-09-11 21:30:50 +00:00
parent d57e195e52
commit 1e6a9415c1
3 changed files with 104 additions and 2 deletions

View File

@ -350,6 +350,7 @@
<Compile Include="Properties\svnrev.cs" />
<Compile Include="QuickCollections.cs" />
<Compile Include="Sound\CDAudio.cs" />
<Compile Include="Sound\Utilities\DCFilter.cs" />
<Compile Include="Sound\Utilities\Equalizer.cs" />
<Compile Include="Sound\Utilities\SpeexResampler.cs" />
<Compile Include="Sound\VRC6.cs" />

View File

@ -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()

View File

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Sound.Utilities
{
/// <summary>
/// implements a DC block filter on top of an ISoundProvider. rather simple.
/// </summary>
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<short> buffer;
const int depth = 65536;
public DCFilter(ISoundProvider input)
{
this.input = input;
this.buffer = new Queue<short>(depth * 2);
for (int i = 0; i < depth * 2; i++)
buffer.Enqueue(0);
}
/// <summary>
/// returns the original sound provider (in case you lost it).
/// after calling, the DCFilter is no longer valid
/// </summary>
/// <returns></returns>
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;
}
}
}
}