From: Neils Wagenaar Date: Sat, 16 Aug 2003 17:27:06 +0000 (+0000) Subject: Brand new sound code uses SDL! X-Git-Tag: 1.0.5~30 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d57a03aa1aa1f1ee55bfaed762fabe6d6154992;p=virtualjaguar Brand new sound code uses SDL! --- diff --git a/src/dac.cpp b/src/dac.cpp new file mode 100644 index 0000000..be2f2c5 --- /dev/null +++ b/src/dac.cpp @@ -0,0 +1,219 @@ +// +// DAC (really, Synchronous Serial Interface) Handler +// +// by cal2 +// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) +// Rewritten by James L. Hammons +// + +#include +#include "jaguar.h" +#include "dac.h" + +#define BUFFER_SIZE 0x8000 // Make the DAC buffers 32K x 16 bits + +// Jaguar memory locations + +#define LTXD 0xF1A148 +#define RTXD 0xF1A14C +#define SCLK 0xF1A150 +#define SMODE 0xF1A154 + +// Local variables + +uint32 LeftFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOHeadPtr, RightFIFOTailPtr; +SDL_AudioSpec desired; + +// We can get away with using native endian here because we can tell SDL to use the native +// when looking at the sample buffer, i.e., no need to worry about it. + +uint16 * DACBuffer; +uint8 SCLKFrequencyDivider = 9; // Start out roughly 44.1K (46164 Hz in NTSC mode) +uint16 serialMode = 0; + +// Private function prototypes + +void SDLSoundCallback(void * userdata, Uint8 * buffer, int length); +int GetCalculatedFrequency(void); + +// +// Initialize the SDL sound system (?) (!) +// +void DACInit(void) +{ + memory_malloc_secure((void **)&DACBuffer, BUFFER_SIZE * sizeof(uint16), "DAC buffer"); + + desired.freq = GetCalculatedFrequency(); // SDL will do conversion on the fly, if it can't get the exact rate. Nice! + desired.format = AUDIO_S16SYS; // This uses the native endian (for portability)... + desired.channels = 2; + desired.samples = 4096; // Let's try a 4K buffer (can always go lower) + desired.callback = SDLSoundCallback; + + if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want + { + WriteLog("DAC: Failed to initialize SDL sound. Shutting down!\n"); + log_done(); + exit(1); + } + + DACReset(); + SDL_PauseAudio(false); // Start playback! + WriteLog("DAC: Successfully initialized.\n"); +} + +// +// Reset the sound buffer FIFOs +// +void DACReset(void) +{ + LeftFIFOHeadPtr = LeftFIFOTailPtr = 0, RightFIFOHeadPtr = RightFIFOTailPtr = 1; +} + +// +// Close down the SDL sound subsystem (?) (!) +// +void DACDone(void) +{ + SDL_PauseAudio(true); + SDL_CloseAudio(); + WriteLog("DAC: Done.\n"); +} + +// +// SDL callback routine to fill audio buffer +// +// Note: The samples are packed in the buffer in 16 bit left/16 bit right pairs. +// +void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) +{ +//WriteLog("DAC: Inside callback...\n"); + if (LeftFIFOHeadPtr != LeftFIFOTailPtr) + { +//WriteLog("DAC: About to write some data!\n"); + int numLeftSamplesReady + = (LeftFIFOTailPtr + (LeftFIFOTailPtr < LeftFIFOHeadPtr ? BUFFER_SIZE : 0)) + - LeftFIFOHeadPtr; + int numRightSamplesReady + = (RightFIFOTailPtr + (RightFIFOTailPtr < RightFIFOHeadPtr ? BUFFER_SIZE : 0)) + - RightFIFOHeadPtr; + int numSamplesReady + = (numLeftSamplesReady < numRightSamplesReady + ? numLeftSamplesReady : numRightSamplesReady) * 2; + + if (numSamplesReady > length) + numSamplesReady = length; + + // Actually, it's a bit more involved than this, but this is the general idea: +// memcpy(buffer, DACBuffer, length); + for(int i=0; i