#include "compiler.h" #include "parts.h" #include "soundmng.h" #include "sound.h" #include "pealstub.h" #define SOUNDBUFFERS 2 typedef struct { SndStreamRef hdl; void* cb; UINT rate; UINT samples; UINT buffersize; SINT32 indata; SINT16* nextdata; SINT16* extendbuffer[SOUNDBUFFERS]; UINT32 pos; } _QSOUND, *QSOUND; static BOOL QS_Avail = FALSE; _QSOUND QSound; static BOOL QSound_Playing = FALSE; void *Callback_sound = NULL; Err m68k_sound_init (void* data) { Err ret = 0; ArgOne params; params.ptr = ByteSwap32(data); ret = (Err)(gCall68KFuncP)(gEmulStateP, (unsigned long)Callback_sound, ¶ms, sizeof(params)); return(ret); } static BOOL SoundBuffer_Init(UINT rate, UINT samples) { QSOUND qs; Err err; UINT32 buffersize; SINT16* buffer[SOUNDBUFFERS]; int i; qs = &QSound; qs->rate = rate; qs->samples = samples; buffersize = samples * 4; qs->buffersize = buffersize; for (i=0;iindata = SOUNDBUFFERS-1; qs->pos = 0; for (i=0;iextendbuffer[i] = buffer[i]; } qs->nextdata = qs->extendbuffer[SOUNDBUFFERS-1]; QS_Avail = TRUE; return(SUCCESS); } return(FAILURE); } static void SoundBuffer_Term(void) { QSOUND qs; int i; qs = &QSound; qs->nextdata = NULL; ARM_SndStreamDelete(qs->hdl); for (i=0;iextendbuffer[i]) { _MFREE(qs->extendbuffer[i]); qs->extendbuffer[i] = NULL; } } } UINT soundmng_create(UINT rate, UINT ms) { UINT samples; QSound_Playing = FALSE; if (rate < 11025) { rate = 11025; } else if (rate > 44100) { rate = 44100; } samples = rate * ms / (SOUNDBUFFERS * 1000); samples = (samples + 3) & (~3); if (SoundBuffer_Init(rate, samples)) { goto qsinit_err; } return(samples); qsinit_err: soundmng_destroy(); return(0); } void soundmng_destroy(void) { if (QS_Avail) { QS_Avail = FALSE; SoundBuffer_Term(); } } void soundmng_play(void) { QSOUND qs; if (QS_Avail == TRUE) { qs = &QSound; ARM_SndStreamStart(qs->hdl); QSound_Playing = TRUE; } } void soundmng_stop(void) { QSOUND qs; if (QS_Avail == TRUE) { qs = &QSound; ARM_SndStreamStop(qs->hdl); QSound_Playing = FALSE; } } void soundmng_sync(void) { QSOUND qs; const SINT32 *src; static int num = -1; if (QS_Avail == FALSE) { return; } qs = &QSound; if (qs->nextdata == NULL) { return; } if (num != qs->indata) { src = sound_pcmlock(); if (src) { satuation_s16(qs->nextdata, src, qs->buffersize); num++; if (num >= SOUNDBUFFERS) { num = 0; } qs->nextdata = qs->extendbuffer[num]; sound_pcmunlock(src); } } }