X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdac.cpp;h=1fdadf6ae18410cae7060ff5bc76b07e5200cec2;hb=43107ad33b400f193f81c51305f12206e2228331;hp=2faf2cd73b7dff7dd0f8e09ed39f9ba0108dcec2;hpb=17f14d2b37678921fbf41076796ff5f560cbba3f;p=virtualjaguar diff --git a/src/dac.cpp b/src/dac.cpp index 2faf2cd..1fdadf6 100644 --- a/src/dac.cpp +++ b/src/dac.cpp @@ -31,15 +31,16 @@ uint16 lrxd, rrxd; // I2S ports (into Jaguar) // Local variables -uint32 LeftFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOHeadPtr, RightFIFOTailPtr; -SDL_AudioSpec desired; +static uint32 LeftFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOHeadPtr, RightFIFOTailPtr; +static SDL_AudioSpec desired; +static bool SDLSoundInitialized = false; // We can get away with using native endian here because we can tell SDL to use the native // endian when looking at the sample buffer, i.e., no need to worry about it. -uint16 * DACBuffer; -uint8 SCLKFrequencyDivider = 19; // Default is roughly 22 KHz (20774 Hz in NTSC mode) -uint16 serialMode = 0; +static uint16 * DACBuffer; +static uint8 SCLKFrequencyDivider = 19; // Default is roughly 22 KHz (20774 Hz in NTSC mode) +/*static*/ uint16 serialMode = 0; // Private function prototypes @@ -62,14 +63,18 @@ void DACInit(void) 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); +// WriteLog("DAC: Failed to initialize SDL sound. Shutting down!\n"); +// log_done(); +// exit(1); + WriteLog("DAC: Failed to initialize SDL sound...\n"); + } + else + { + SDLSoundInitialized = true; + DACReset(); + SDL_PauseAudio(false); // Start playback! + WriteLog("DAC: Successfully initialized.\n"); } - - DACReset(); - SDL_PauseAudio(false); // Start playback! - WriteLog("DAC: Successfully initialized.\n"); } // @@ -85,8 +90,12 @@ void DACReset(void) // void DACDone(void) { - SDL_PauseAudio(true); - SDL_CloseAudio(); + if (SDLSoundInitialized) + { + SDL_PauseAudio(true); + SDL_CloseAudio(); + } + memory_free(DACBuffer); WriteLog("DAC: Done.\n"); } @@ -99,6 +108,7 @@ void DACDone(void) void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) { // Clear the buffer to silence, in case the DAC buffer is empty (or short) +//This causes choppy sound... Ick. memset(buffer, desired.silence, length); //WriteLog("DAC: Inside callback...\n"); if (LeftFIFOHeadPtr != LeftFIFOTailPtr) @@ -176,7 +186,7 @@ void DACWriteWord(uint32 offset, uint16 data, uint32 who/*= UNKNOWN*/) //[DONE] // Also, we're taking advantage of the fact that the buffer is a multiple of two // in this check... - while ((LeftFIFOTailPtr + 2) & (BUFFER_SIZE - 1) == LeftFIFOHeadPtr); + while (((LeftFIFOTailPtr + 2) & (BUFFER_SIZE - 1)) == LeftFIFOHeadPtr); SDL_LockAudio(); // Is it necessary to do this? Mebbe. // We use a circular buffer 'cause it's easy. Note that the callback function @@ -190,16 +200,24 @@ void DACWriteWord(uint32 offset, uint16 data, uint32 who/*= UNKNOWN*/) { // Spin until buffer has been drained (for too fast processors!)... //uint32 spin = 0; - while ((RightFIFOTailPtr + 2) & (BUFFER_SIZE - 1) == RightFIFOHeadPtr); + while (((RightFIFOTailPtr + 2) & (BUFFER_SIZE - 1)) == RightFIFOHeadPtr); /* { spin++; -if (spin == 0x10000000) +//if ((spin & 0x0FFFFFFF) == 0) +// WriteLog("Tail=%X, Head=%X, BUFFER_SIZE-1=%X\n", RightFIFOTailPtr, RightFIFOHeadPtr, BUFFER_SIZE - 1); + +if (spin == 0xFFFF0000) { - WriteLog("\nStuck in right DAC spinlock! Tail=%u, Head=%u\nAborting!\n", RightFIFOTailPtr, RightFIFOHeadPtr); +uint32 rtail = RightFIFOTailPtr, rhead = RightFIFOHeadPtr; +WriteLog("Tail=%X, Head=%X\n", rtail, rhead); + + WriteLog("\nStuck in right DAC spinlock!\nAborting!\n\n"); + WriteLog("Tail=%X, Head=%X, BUFFER_SIZE-1=%X\n", RightFIFOTailPtr, RightFIFOHeadPtr, BUFFER_SIZE - 1); + WriteLog("From while: Tail=%X, Head=%X", (RightFIFOTailPtr + 2) & (BUFFER_SIZE - 1), RightFIFOHeadPtr); log_done(); exit(0); } - }*/ + }//*/ //This is wrong if (RightFIFOTailPtr + 2 != RightFIFOHeadPtr) // { @@ -222,19 +240,26 @@ if (spin == 0x10000000) //Of course a better way would be to query the hardware to find the upper limit... if (data > 7) // Anything less than 8 is too high! { - SDL_CloseAudio(); + if (SDLSoundInitialized) + SDL_CloseAudio(); + desired.freq = GetCalculatedFrequency();// SDL will do conversion on the fly, if it can't get the exact rate. Nice! WriteLog("DAC: Changing sample rate to %u Hz!\n", desired.freq); - if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want + if (SDLSoundInitialized) { - WriteLog("DAC: Failed to initialize SDL sound: %s.\nDesired freq: %u\nShutting down!\n", SDL_GetError(), desired.freq); - log_done(); - exit(1); + if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want + { + WriteLog("DAC: Failed to initialize SDL sound: %s.\nDesired freq: %u\nShutting down!\n", SDL_GetError(), desired.freq); + log_done(); + exit(1); + } } DACReset(); - SDL_PauseAudio(false); // Start playback! + + if (SDLSoundInitialized) + SDL_PauseAudio(false); // Start playback! } } }