X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fsound.cpp;fp=src%2Fsound.cpp;h=df2de2b4ab59d3c64b80cbc49eb8002ee68734cf;hb=92fbd445099cf43df759ccff12df762ac46b6809;hp=a68956788fa118e84150efcaf95477809230ba1d;hpb=01d41f5b9d4900e89a9b61bbc06fb743254eb1a1;p=apple2 diff --git a/src/sound.cpp b/src/sound.cpp index a689567..df2de2b 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -24,13 +24,13 @@ #include // For memset, memcpy #include +#include "ay8910.h" #include "log.h" // Useful defines //#define DEBUG -#define SAMPLE_RATE (48000.0) #define SAMPLES_PER_FRAME (SAMPLE_RATE / 60.0) #define CYCLES_PER_SAMPLE (1024000.0 / SAMPLE_RATE) // 32K ought to be enough for anybody @@ -45,13 +45,13 @@ static SDL_AudioSpec desired, obtained; static SDL_AudioDeviceID device; static bool soundInitialized = false; static bool speakerState = false; -static int16_t soundBuffer[SOUND_BUFFER_SIZE]; +static uint16_t soundBuffer[SOUND_BUFFER_SIZE]; static uint32_t soundBufferPos; -static uint64_t lastToggleCycles; -static SDL_cond * conditional = NULL; -static SDL_mutex * mutex = NULL; -static SDL_mutex * mutex2 = NULL; -static int16_t sample; +//static uint64_t lastToggleCycles; +//static SDL_cond * conditional = NULL; +//static SDL_mutex * mutex = NULL; +//static SDL_mutex * mutex2 = NULL; +static uint16_t sample; static uint8_t ampPtr = 12; // Start with -2047 - +2047 static int16_t amplitude[17] = { 0, 1, 2, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; @@ -67,10 +67,10 @@ static void SDLSoundCallback(void * userdata, Uint8 * buffer, int length); void SoundInit(void) { SDL_zero(desired); - desired.freq = SAMPLE_RATE; // 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.freq = SAMPLE_RATE; // SDL will do conversion on the fly, if it can't get the exact rate. Nice! + desired.format = AUDIO_U16SYS; // This uses the native endian (for portability)... desired.channels = 1; - desired.samples = 512; // Let's try a 1/2K buffer (can always go lower) + desired.samples = 512; // Let's try a 1/2K buffer desired.callback = SDLSoundCallback; device = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0); @@ -81,11 +81,11 @@ void SoundInit(void) return; } - conditional = SDL_CreateCond(); - mutex = SDL_CreateMutex(); - mutex2 = SDL_CreateMutex();// Let's try real signalling... +// conditional = SDL_CreateCond(); +// mutex = SDL_CreateMutex(); +// mutex2 = SDL_CreateMutex();// Let's try real signalling... soundBufferPos = 0; - lastToggleCycles = 0; +// lastToggleCycles = 0; sample = desired.silence; // ? wilwok ? yes SDL_PauseAudioDevice(device, 0); // Start playback! @@ -103,9 +103,9 @@ void SoundDone(void) { SDL_PauseAudioDevice(device, 1); SDL_CloseAudioDevice(device); - SDL_DestroyCond(conditional); - SDL_DestroyMutex(mutex); - SDL_DestroyMutex(mutex2); +// SDL_DestroyCond(conditional); +// SDL_DestroyMutex(mutex); +// SDL_DestroyMutex(mutex2); WriteLog("Sound: Done.\n"); } } @@ -128,28 +128,31 @@ void SoundResume(void) // // Sound card callback handler // +static uint32_t sndFrmCnt = 0; +static uint32_t lastStarve = 0; static void SDLSoundCallback(void * /*userdata*/, Uint8 * buffer8, int length8) { +sndFrmCnt++; //WriteLog("SDLSoundCallback(): begin (soundBufferPos=%i)\n", soundBufferPos); - // The sound buffer should only starve when starting which will cause it to - // lag behind the emulation at most by around 1 frame... - // (Actually, this should never happen since we fill the buffer beforehand.) - // (But, then again, if the sound hasn't been toggled for a while, then this - // makes perfect sense as the buffer won't have been filled at all!) - // (Should NOT starve now, now that we properly handle frame edges...) // Let's try using a mutex for shared resource consumption... //Actually, I think Lock/UnlockAudio() does this already... //WriteLog("SDLSoundCallback: soundBufferPos = %i\n", soundBufferPos); - SDL_mutexP(mutex2); +// SDL_mutexP(mutex2); // Recast this as a 16-bit type... - int16_t * buffer = (int16_t *)buffer8; + uint16_t * buffer = (uint16_t *)buffer8; uint32_t length = (uint32_t)length8 / 2; //WriteLog("SDLSoundCallback(): filling buffer...\n"); if (soundBufferPos < length) { +WriteLog("*** Sound buffer starved (%d short) *** [%d delta %d]\n", length - soundBufferPos, sndFrmCnt, sndFrmCnt - lastStarve); +lastStarve = sndFrmCnt; +#if 1 + for(uint32_t i=0; i= (SOUND_BUFFER_SIZE - 1)) { //WriteLog("WriteSampleToBuffer(): Waiting for sound thread. soundBufferPos=%i, SOUNDBUFFERSIZE-1=%i\n", soundBufferPos, SOUND_BUFFER_SIZE-1); - SDL_mutexV(mutex2); // Release it so sound thread can get it, - SDL_mutexP(mutex); // Must lock the mutex for the cond to work properly... - SDL_CondWait(conditional, mutex); // Sleep/wait for the sound thread - SDL_mutexV(mutex); // Must unlock the mutex for the cond to work properly... - SDL_mutexP(mutex2); // Re-lock it until we're done with it... +// SDL_mutexV(mutex2); // Release it so sound thread can get it, +// SDL_mutexP(mutex); // Must lock the mutex for the cond to work properly... +// SDL_CondWait(conditional, mutex); // Sleep/wait for the sound thread +// SDL_mutexV(mutex); // Must unlock the mutex for the cond to work properly... +// SDL_mutexP(mutex2); // Re-lock it until we're done with it... + SDL_Delay(1); } - soundBuffer[soundBufferPos++] = sample; + SDL_LockAudioDevice(device); + soundBuffer[soundBufferPos++] = sample + adjustedMockingboard; + SDL_UnlockAudioDevice(device); + +// soundBuffer[soundBufferPos++] = sample; //WriteLog("WriteSampleToBuffer(): SDL_mutexV(mutex2)\n"); - SDL_mutexV(mutex2); +// SDL_mutexV(mutex2); } @@ -212,7 +236,7 @@ void ToggleSpeaker(void) return; speakerState = !speakerState; - sample = (speakerState ? amplitude[ampPtr] : -amplitude[ampPtr]); + sample = (speakerState ? amplitude[ampPtr] : 0);//-amplitude[ampPtr]); }