~fixed ASND support, DSP task is now allocated only once.

~fixed oggplayer memory leak (LWP queue was not closed properly)
~do no use VSYNC callback for emulation synchronization anymore, (always uses DMA interrupt regardless the video mode)
This commit is contained in:
ekeeke31 2009-06-15 08:07:48 +00:00
parent aa970d66a6
commit 256d534ea6
5 changed files with 54 additions and 57 deletions

View File

@ -183,11 +183,9 @@ void legal ()
} }
gxSetScreen(); gxSetScreen();
ASND_Init();
ASND_Pause(0); ASND_Pause(0);
int voice = ASND_GetFirstUnusedVoice(); int voice = ASND_GetFirstUnusedVoice();
ASND_SetVoice(voice,VOICE_MONO_16BIT,44100,0,(u8 *)intro_pcm,intro_pcm_size,200,200,NULL); ASND_SetVoice(voice,VOICE_MONO_16BIT,44100,0,(u8 *)intro_pcm,intro_pcm_size,200,200,NULL);
sleep (2); sleep (2);
ASND_Pause(1); ASND_Pause(1);
ASND_End();
} }

View File

@ -224,6 +224,8 @@ static void * ogg_player_thread(private_data_ogg * priv)
priv[0].fd = -1; priv[0].fd = -1;
priv[0].pcm_indx = 0; priv[0].pcm_indx = 0;
ogg_thread_running = 0; ogg_thread_running = 0;
/* free */
LWP_CloseQueue(oggplayer_queue);
return 0; return 0;
} }
@ -281,11 +283,11 @@ int PlayOgg(int fd, int time_pos, int mode)
private_ogg.fd = -1; private_ogg.fd = -1;
return -1; return -1;
} }
LWP_ThreadSignal(oggplayer_queue);
while (((volatile int) ogg_thread_running) == 0) while (((volatile int) ogg_thread_running) == 0)
{ {
;;; ;;;
} }
LWP_ThreadSignal(oggplayer_queue);
return 0; return 0;
} }

View File

@ -62,12 +62,15 @@ static void ai_callback(void)
frameticker++; frameticker++;
} }
/* AUDIO engine initialization */
void gx_audio_Init(void) void gx_audio_Init(void)
{ {
AUDIO_Init (NULL); /* Initialize AUDIO hardware */
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ); /* Default samplerate is 48kHZ */
/* Default DMA callback is programmed */
ASND_Init();
/* load background music from FAT device */ /* Load background music from FAT device */
char fname[MAXPATHLEN]; char fname[MAXPATHLEN];
sprintf(fname,"%s/Bg_music.ogg",DEFAULT_PATH); sprintf(fname,"%s/Bg_music.ogg",DEFAULT_PATH);
FILE *f = fopen(fname,"rb"); FILE *f = fopen(fname,"rb");
@ -82,6 +85,7 @@ void gx_audio_Init(void)
} }
} }
/* AUDIO engine shutdown */
void gx_audio_Shutdown(void) void gx_audio_Shutdown(void)
{ {
PauseOgg(1); PauseOgg(1);
@ -92,7 +96,7 @@ void gx_audio_Shutdown(void)
} }
/*** /***
gx_audio__update gx_audio_Update
This function is called at the end of each frame This function is called at the end of each frame
Genesis Plus only provides sound data on completion of each frame. Genesis Plus only provides sound data on completion of each frame.
@ -102,12 +106,26 @@ void gx_audio_Shutdown(void)
***/ ***/
void gx_audio_Update(void) void gx_audio_Update(void)
{ {
/* current DMA length */
u32 size = dma_len; u32 size = dma_len;
/* get audio samples */ /* VIDEO interrupt synchronization: we approximate next DMA length (see below) */
audio_update(dma_len); /* VSYNC period is 16715 us which is approx. 802.32 samples */
/* DMA length should be a multiple of 32 bytes so we use either 800 or 808 samples */
if (dma_sync)
{
/* current samples delay */
delta += (size * 100) - dma_sync;
/* update DMA parameters */ /* adjust next DMA length */
if (delta < 0) dma_len = 808;
else dma_len = 800;
}
/* retrieve audio samples */
audio_update(size);
/* set next DMA soundbuffer */
s16 *sb = (s16 *)(soundbuffer[mixbuffer]); s16 *sb = (s16 *)(soundbuffer[mixbuffer]);
mixbuffer ^= 1; mixbuffer ^= 1;
size = size << 2; size = size << 2;
@ -115,29 +133,20 @@ void gx_audio_Update(void)
AUDIO_InitDMA((u32) sb, size); AUDIO_InitDMA((u32) sb, size);
/* Start Audio DMA */ /* Start Audio DMA */
/* this is only called once, DMA is automatically restarted when previous one is over */ /* this is only called once, DMA being automatically restarted when previous one is over */
/* When DMA parameters are not updated, same soundbuffer is played again */ /* If DMA settings are not updated at that time, the same soundbuffer will be played again */
if (!audioStarted) if (!audioStarted)
{ {
audioStarted = 1; audioStarted = 1;
AUDIO_StartDMA(); AUDIO_StartDMA();
if (frameticker > 1) frameticker = 1; if (frameticker > 1) frameticker = 1;
} }
/* VIDEO interrupt sync: we approximate DMA length (see below) */
/* DMA length should be 32 bytes so we use 800 or 808 samples */
if (dma_sync)
{
delta += (dma_len * 100) - dma_sync;
if (delta < 0) dma_len = 808;
else dma_len = 800;
}
} }
/*** /***
gx_audio__start gx_audio_Start
This function resets the audio engine This function restart the audio engine
This is called when coming back from Main Menu This is called when coming back from Main Menu
***/ ***/
void gx_audio_Start(void) void gx_audio_Start(void)
@ -146,35 +155,34 @@ void gx_audio_Start(void)
PauseOgg(1); PauseOgg(1);
StopOgg(); StopOgg();
ASND_Pause(1); ASND_Pause(1);
ASND_End(); AUDIO_StopDMA ();
audioStarted = 0;
/* initialize default DMA length */ /* initialize default DMA length */
/* PAL (50Hz): 20000 us period --> 960 samples/frame @48kHz */ /* PAL (50Hz): 20000 us period --> 960 samples/frame @48kHz */
/* NTSC (60Hz): 16667 us period --> 800 samples/frame @48kHz */ /* NTSC (60Hz): 16667 us period --> 800 samples/frame @48kHz */
dma_len = vdp_pal ? 960 : 800; dma_len = vdp_pal ? 960 : 800;
dma_sync = 0;
mixbuffer = 0; mixbuffer = 0;
delta = 0; delta = 0;
/* reset sound buffers */ /* reset sound buffers */
memset(soundbuffer, 0, 2 * 3840); memset(soundbuffer, 0, 2 * 3840);
/* default */
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
AUDIO_RegisterDMACallback(NULL);
/* let's use audio DMA to synchronize frame emulation */ /* let's use audio DMA to synchronize frame emulation */
if (vdp_pal | gc_pal) AUDIO_RegisterDMACallback(ai_callback); AUDIO_RegisterDMACallback(ai_callback);
/* 60hz video mode requires synchronization with Video interrupt */ /* 60hz video mode requires synchronization with Video interrupt */
/* VSYNC period is 16715 us which is approx. 802.32 samples */ /* VSYNC period is 16715 us which is approx. 802.32 samples */
/* to prevent audio/video desynchronization, we approximate the exact */ /* to prevent audio/video desynchronization, we approximate the exact */
/* number of samples by using alternate audio length */ /* number of samples by changing audio DMA length on each frame */
else dma_sync = 80232; if (vdp_pal | gc_pal)
dma_sync = 0;
else
dma_sync = 80232;
} }
/*** /***
gx_audio__stop gx_audio_Stop
This function stops current Audio DMA process This function stops current Audio DMA process
This is called when going back to Main Menu This is called when going back to Main Menu
@ -182,11 +190,7 @@ void gx_audio_Start(void)
***/ ***/
void gx_audio_Stop(void) void gx_audio_Stop(void)
{ {
/* stop emulator audio */ /* restart menu audio (this will automatically stops current audio DMA) */
AUDIO_StopDMA ();
audioStarted = 0;
/* restart menu audio */
ASND_Init(); ASND_Init();
ASND_Pause(0); ASND_Pause(0);
if (Bg_music_ogg && !Shutdown) if (Bg_music_ogg && !Shutdown)

View File

@ -1216,12 +1216,6 @@ void gxTextureClose(gx_texture **p_texture)
/* VIDEO engine */ /* VIDEO engine */
/***************************************************************************************/ /***************************************************************************************/
/* VIDEO callback */
static void vi_callback(u32 cnt)
{
frameticker++;
}
/* Take Screenshot */ /* Take Screenshot */
void gx_video_Capture(void) void gx_video_Capture(void)
{ {
@ -1252,15 +1246,14 @@ void gx_video_Stop(void)
gxResetRendering(1); gxResetRendering(1);
gxResetView(vmode); gxResetView(vmode);
/* reset VI */ /* inputs should be updated during VSYNC */
gxDrawScreenshot(0xff); VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu);
/* adjust overscan */ /* reset VI & adjust overscan */
gxDrawScreenshot(0xff);
vmode->viWidth = config.screen_w; vmode->viWidth = config.screen_w;
vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2; vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2;
VIDEO_Configure(vmode); VIDEO_Configure(vmode);
VIDEO_SetPreRetraceCallback(NULL);
VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu);
gxSetScreen(); gxSetScreen();
} }
@ -1268,13 +1261,13 @@ void gx_video_Stop(void)
void gx_video_Start(void) void gx_video_Start(void)
{ {
/* 50Hz/60Hz mode */ /* 50Hz/60Hz mode */
if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal)) gc_pal = 1; if ((config.tv_mode == 1) || ((config.tv_mode == 2) && vdp_pal))
else gc_pal = 0; gc_pal = 1;
else
gc_pal = 0;
/* VIDEO sync */ /* disable VSYNC callback */
VIDEO_SetPostRetraceCallback(NULL); VIDEO_SetPostRetraceCallback(NULL);
if (!gc_pal && !vdp_pal)
VIDEO_SetPreRetraceCallback(vi_callback);
VIDEO_Flush(); VIDEO_Flush();
/* interlaced/progressive mode */ /* interlaced/progressive mode */

View File

@ -1655,7 +1655,7 @@ static void OPNSetPres(int pres)
/* write a OPN mode register 0x20-0x2f */ /* write a OPN mode register 0x20-0x2f */
static void OPNWriteMode(int r, int v) INLINE void OPNWriteMode(int r, int v)
{ {
UINT8 c; UINT8 c;
FM_CH *CH; FM_CH *CH;
@ -1704,7 +1704,7 @@ static void OPNWriteMode(int r, int v)
} }
/* write a OPN register (0x30-0xff) */ /* write a OPN register (0x30-0xff) */
static void OPNWriteReg(int r, int v) INLINE void OPNWriteReg(int r, int v)
{ {
FM_CH *CH; FM_CH *CH;
FM_SLOT *SLOT; FM_SLOT *SLOT;