X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fsound.cpp;h=4191928b2c52584c87680ab6c8701ca7990fe0d6;hb=05e3af22c4bd3c40744505a52bbdb24a13fab694;hp=6cc1860d29ccea31ef5eb6c0c9842be42bb4fdac;hpb=af27a070d6a36e5590c5d24ba255300825c25cf9;p=stargem2 diff --git a/src/sound.cpp b/src/sound.cpp index 6cc1860..4191928 100755 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -10,6 +10,9 @@ // --- ---------- ------------------------------------------------------------ // JLH 06/15/2006 Added changelog ;-) // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// JLH 02/10/2009 Fixed sound IRQ callback so that CPU samples are taken at +// cycle exact boundaries +// JLH 07/21/2009 Moved numeric constants into macros for sanity's sake // // Notes: // The sound CPU (6808) runs at 894,750 (3,579,000 / 4) Hz. @@ -24,13 +27,20 @@ #include "types.h" #include "log.h" #include "v6808.h" +#include "timing.h" //using namespace std; +//#define AUDIO_SAMPLE_RATE 44100.0 +#define AUDIO_SAMPLE_RATE 48000.0 +#define CYCLES_TO_EXECUTE (M6808_CLOCK_SPEED_IN_HZ / AUDIO_SAMPLE_RATE) + // Local variables -SDL_AudioSpec desired; -bool soundInitialized = false; +static SDL_AudioSpec desired; +static bool soundInitialized = false; +static uint32 cyclesToExecuteWholePart; +static double cyclesToExecuteFractionalPart; // Private function prototypes @@ -43,7 +53,7 @@ void SoundInit(void) { // memory_malloc_secure((void **)&DACBuffer, BUFFER_SIZE * sizeof(uint16), "DAC buffer"); - desired.freq = 44100; // SDL will do conversion on the fly, if it can't get the exact rate. Nice! + desired.freq = AUDIO_SAMPLE_RATE; // SDL will do conversion on the fly, if it can't get the exact rate. Nice! desired.format = AUDIO_U8; // This uses the native endian (for portability)... desired.channels = 1; // desired.samples = 4096; // Let's try a 4K buffer (can always go lower) @@ -53,10 +63,16 @@ void SoundInit(void) if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want { WriteLog("Sound: Failed to initialize SDL sound.\n"); -// exit(1); return; } + // Setup clock cycles & etc. + cyclesToExecuteWholePart = (uint32)CYCLES_TO_EXECUTE; + cyclesToExecuteFractionalPart = CYCLES_TO_EXECUTE - (double)cyclesToExecuteWholePart; +#if 0 +printf("Cycles to execute: %lf; cycles W: %u; cycles F: %lf\n", CYCLES_TO_EXECUTE, cyclesToExecuteWholePart, cyclesToExecuteFractionalPart); +#endif + SDL_PauseAudio(false); // Start playback! soundInitialized = true; WriteLog("Sound: Successfully initialized.\n"); @@ -81,16 +97,24 @@ void SoundDone(void) void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) { extern V6808REGS soundCPU; - extern uint8 * sram; + extern uint8 sram[]; int cnt = 0; + static float overflow = 0.0; + static uint32 time = cyclesToExecuteWholePart; + while (cnt != length) { - // This is close, but not cycle exact (exact would be 20.289115646...) - -//Need to figure out how to get that fraction to execute... !!! FIX !!! - Execute6808(&soundCPU, 20); - soundCPU.clock -= 20; + Execute6808(&soundCPU, time); + soundCPU.clock -= time; buffer[cnt++] = sram[0x0400]; // Fill the buffer with the PIA output value + time = cyclesToExecuteWholePart; + overflow += cyclesToExecuteFractionalPart; + + if (overflow > 1.0) + { + overflow -= 1.0; + time++; + } } }