gambatte now has sound! output from the core is original 2MEGAHURTZ audio, but libspeexdsp handles it fine.

seems to be a lot of DC offset at times; not sure if there's a good way to remove it
This commit is contained in:
goyuken 2012-09-09 00:41:11 +00:00
parent b1568ccc44
commit f18eb2fef2
2 changed files with 75 additions and 7 deletions

View File

@ -9,7 +9,7 @@ namespace BizHawk.Emulation.Consoles.Gambatte
/// <summary>
/// a gameboy/gameboy color emulator wrapped around native C++ libgambatte
/// </summary>
public class Gambatte : IEmulator, IVideoProvider
public class Gambatte : IEmulator, IVideoProvider, ISoundProvider
{
/// <summary>
/// internal gambatte state
@ -34,6 +34,8 @@ namespace BizHawk.Emulation.Consoles.Gambatte
if (LibGambatte.gambatte_load(GambatteState, "gambattetmp.gb", 0) != 0)
throw new Exception("gambatte_load() returned non-zero (is this not a gb or gbc rom?)");
InitSound();
}
public IVideoProvider VideoProvider
@ -43,7 +45,7 @@ namespace BizHawk.Emulation.Consoles.Gambatte
public ISoundProvider SoundProvider
{
get { return new NullSound(); }
get { return this; }
}
@ -65,13 +67,15 @@ namespace BizHawk.Emulation.Consoles.Gambatte
public IController Controller { get; set; }
short[] soundscratch = new short[(35112 + 2064) * 2];
uint[] videoscratch = new uint[160 * 144];
public void FrameAdvance(bool render)
{
uint nsamp = 35112;
LibGambatte.gambatte_runfor(GambatteState, videoscratch, 160, soundscratch, ref nsamp);
LibGambatte.gambatte_runfor(GambatteState, videoscratch, 160, soundbuff, ref nsamp);
soundbuffcontains = (int)nsamp;
// can't convert uint[] to int[], so we do this instead
// TODO: lie in the p/invoke layer and claim unsigned* is really int*
@ -144,8 +148,8 @@ namespace BizHawk.Emulation.Consoles.Gambatte
CoreOutputComm GbOutputComm = new CoreOutputComm
{
VsyncNum = 60,
VsyncDen = 1,
VsyncNum = 262144,
VsyncDen = 4389,
RomStatusAnnotation = "Bizwhackin it up",
RomStatusDetails = "LEVAR BURTON"
};
@ -205,5 +209,47 @@ namespace BizHawk.Emulation.Consoles.Gambatte
}
#endregion
#region ISoundProvider
/// <summary>
/// sample pairs before resampling
/// </summary>
short[] soundbuff = new short[(35112 + 2064) * 2];
/// <summary>
/// how many sample pairs are in soundbuff
/// </summary>
int soundbuffcontains = 0;
Sound.Utilities.SpeexResampler resampler;
Sound.MetaspuSoundProvider metaspu;
void InitSound()
{
metaspu = new Sound.MetaspuSoundProvider(Sound.ESynchMethod.ESynchMethod_V);
resampler = new Sound.Utilities.SpeexResampler(5, 2097152, 44100, 2097152, 44100, metaspu.buffer.enqueue_samples);
}
public void GetSamples(short[] samples)
{
resampler.EnqueueSamples(soundbuff, soundbuffcontains);
//for (int i = 0; soundbuffcontains >= 0; soundbuffcontains--)
//{
// resampler.EnqueueSample(soundbuff[i], soundbuff[i + 1]);
// i += 2;
//}
soundbuffcontains = 0;
resampler.Flush();
metaspu.GetSamples(samples);
}
public void DiscardSamples()
{
metaspu.DiscardSamples();
}
public int MaxVolume { get; set; }
#endregion
}
}

View File

@ -264,7 +264,8 @@ namespace BizHawk.Emulation.Sound.Utilities
/// </summary>
Action<short[], int> drainer;
short[] inbuf = new short[512];
// TODO: this size is roughly based on how big you can make the buffer before the snes resampling (32040.5 -> 44100) gets screwed up
short[] inbuf = new short[512]; //[8192]; // [512];
short[] outbuf;
@ -336,6 +337,27 @@ namespace BizHawk.Emulation.Sound.Utilities
Flush();
}
/// <summary>
/// add multiple samples to the queue
/// </summary>
/// <param name="userbuf">interleaved stereo samples</param>
/// <param name="nsamp">number of sample pairs</param>
public void EnqueueSamples(short[] userbuf, int nsamp)
{
int numused = 0;
while (numused < nsamp)
{
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;
numused += shortstocopy / 2;
if (inbufpos == inbuf.Length)
Flush();
}
}
/// <summary>
/// flush as many input samples as possible, generating output samples right now