new sync using audio DMA

This commit is contained in:
ekeeke31 2008-12-18 22:34:55 +00:00
parent fefc260ec4
commit 840a370418
5 changed files with 44 additions and 96 deletions

View File

@ -113,7 +113,6 @@ void reloadrom ()
audio_init(48000); /* Audio System initialization */ audio_init(48000); /* Audio System initialization */
ClearGGCodes (); /* Clear Game Genie patches */ ClearGGCodes (); /* Clear Game Genie patches */
system_reset (); /* System Power ON */ system_reset (); /* System Power ON */
ogc_audio__reset(); /* reset audio buffers */
} }
/*************************************************************************** /***************************************************************************
@ -132,8 +131,6 @@ int main (int argc, char *argv[])
DI_Init(); DI_Init();
#endif #endif
u16 usBetweenFrames;
long long now, prev;
int RenderedFrameCount = 0; int RenderedFrameCount = 0;
int FrameCount = 0; int FrameCount = 0;
@ -189,41 +186,12 @@ int main (int argc, char *argv[])
MainMenu(); MainMenu();
ConfigRequested = 0; ConfigRequested = 0;
/* Initialize Frame timings */
frameticker = 0;
prev = gettime();
/* Emulation Loop */ /* Emulation Loop */
while (1) while (1)
{ {
/* audio DMA starting point */
ogc_audio__start(); ogc_audio__start();
/* Frame synchronization */
if (gc_pal != vdp_pal)
{
/* use timers */
usBetweenFrames = vdp_pal ? 20000 : 16666;
now = gettime();
if (diff_usec(prev, now) > usBetweenFrames)
{
/* Frame skipping */
prev = now;
system_frame(1);
}
else
{
/* Delay */
while (diff_usec(prev, now) < usBetweenFrames) now = gettime();
/* Render Frame */
prev = now;
system_frame(0);
RenderedFrameCount++;
}
}
else
{
/* use VSync */
if (frameticker > 1) if (frameticker > 1)
{ {
/* Frame skipping */ /* Frame skipping */
@ -241,7 +209,6 @@ int main (int argc, char *argv[])
} }
frameticker--; frameticker--;
}
/* update video & audio */ /* update video & audio */
ogc_audio__update(); ogc_audio__update();
@ -268,7 +235,6 @@ int main (int argc, char *argv[])
/* reset frame timings */ /* reset frame timings */
frameticker = 0; frameticker = 0;
prev = gettime();
FrameCount = 0; FrameCount = 0;
RenderedFrameCount = 0; RenderedFrameCount = 0;
} }

View File

@ -24,59 +24,55 @@
#include "shared.h" #include "shared.h"
/* global datas */ /* global datas */
unsigned char soundbuffer[16][3840] ATTRIBUTE_ALIGN(32); unsigned char soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
int mixbuffer = 0; u8 mixbuffer = 0;
static int playbuffer = 0;
static int IsPlaying = 0; static int IsPlaying = 0;
static u32 dma_len = 3200; static int dma_len = 3200;
/*** AudioSwitchBuffers /*** AudioDmaCallback
Genesis Plus only provides sound data on completion of each frame. Genesis Plus only provides sound data on completion of each frame.
To try to make the audio less choppy, this function is called from both the To try to make the audio less choppy, we synchronize emulation with audio DMA
DMA completion and update_audio. This ensure we only update audio framebuffer when DMA is finished
Testing for data in the buffer ensures that there are no clashes.
***/ ***/
static void AudioSwitchBuffers() static void AudioDmaCallback()
{ {
/* increment soundbuffers index */ frameticker++;
playbuffer++;
playbuffer &= 0xf;
/* reset audio DMA parameters */
AUDIO_InitDMA((u32) soundbuffer[playbuffer], dma_len);
} }
void ogc_audio__init(void) void ogc_audio__init(void)
{ {
AUDIO_Init (NULL); AUDIO_Init (NULL);
AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ); AUDIO_SetDSPSampleRate (AI_SAMPLERATE_48KHZ);
// AUDIO_RegisterDMACallback (AudioSwitchBuffers); AUDIO_RegisterDMACallback (AudioDmaCallback);
}
void ogc_audio__reset(void)
{
IsPlaying = 0;
mixbuffer = 0; mixbuffer = 0;
playbuffer = 0; memset(soundbuffer, 0, 2 * 3840);
memset(soundbuffer, 0, 16 * 3840);
} }
void ogc_audio__update(void) void ogc_audio__update(void)
{ {
/* buffer size */
uint32 dma_len = vdp_pal ? 3840 : 3200;
/* update DMA settings (this will only be taken in account when current DMA finishes) */
AUDIO_InitDMA((u32) soundbuffer[mixbuffer], dma_len);
/* flush data from CPU cache */ /* flush data from CPU cache */
DCFlushRange(soundbuffer[mixbuffer], dma_len); DCFlushRange(soundbuffer[mixbuffer], dma_len);
AUDIO_InitDMA((u32) soundbuffer[mixbuffer], dma_len);
/* switch buffer */
mixbuffer ^= 1;
} }
void ogc_audio__stop(void) void ogc_audio__stop(void)
{ {
/* stop audio DMA */ /* stop audio DMA */
AUDIO_StopDMA (); AUDIO_StopDMA ();
AUDIO_InitDMA((u32) soundbuffer[0], dma_len);
IsPlaying = 0; IsPlaying = 0;
/* reset audio buffers */
mixbuffer = 0; mixbuffer = 0;
playbuffer = 0; memset(soundbuffer, 0, 2 * 3840);
} }
void ogc_audio__start(void) void ogc_audio__start(void)
@ -86,8 +82,8 @@ void ogc_audio__start(void)
/* buffer size */ /* buffer size */
dma_len = vdp_pal ? 3840 : 3200; dma_len = vdp_pal ? 3840 : 3200;
/* set default DMA parameters */ /* set first DMA parameters */
AUDIO_InitDMA((u32) soundbuffer[0], dma_len); AUDIO_InitDMA((u32) soundbuffer[1], dma_len);
/* start audio DMA */ /* start audio DMA */
AUDIO_StartDMA(); AUDIO_StartDMA();

View File

@ -24,11 +24,10 @@
#ifndef _GC_AUDIO_H_ #ifndef _GC_AUDIO_H_
#define _GC_AUDIO_H_ #define _GC_AUDIO_H_
extern u8 soundbuffer[16][3840]; extern u8 soundbuffer[2][3840];
extern int mixbuffer; extern u8 mixbuffer;
extern void ogc_audio__init(void); extern void ogc_audio__init(void);
extern void ogc_audio__reset(void);
extern void ogc_audio__stop(void); extern void ogc_audio__stop(void);
extern void ogc_audio__start(void); extern void ogc_audio__start(void);
extern void ogc_audio__update(void); extern void ogc_audio__update(void);

View File

@ -346,13 +346,6 @@ static inline void draw_square (void)
GX_End (); GX_End ();
} }
/* retrace handler */
static void framestart(u32 retraceCnt)
{
/* simply increment the tick counter */
frameticker++;
}
/* Initialize GX */ /* Initialize GX */
static void gxStart(void) static void gxStart(void)
{ {
@ -725,9 +718,6 @@ void ogc_video__init(void)
/* Set the framebuffer to be displayed at next VBlank */ /* Set the framebuffer to be displayed at next VBlank */
VIDEO_SetNextFramebuffer (xfb[0]); VIDEO_SetNextFramebuffer (xfb[0]);
/* Register Video Retrace handlers */
VIDEO_SetPreRetraceCallback(framestart);
/* Enable Video Interface */ /* Enable Video Interface */
VIDEO_SetBlack (FALSE); VIDEO_SetBlack (FALSE);

View File

@ -61,7 +61,7 @@ static inline uint32 psg_sample_cnt(uint8 is_z80)
/* update FM samples */ /* update FM samples */
static inline void fm_update() static inline void fm_update()
{ {
if(snd.fm.curStage - snd.fm.lastStage > 0) if(snd.fm.curStage - snd.fm.lastStage > 1)
{ {
int *tempBuffer[2]; int *tempBuffer[2];
@ -84,7 +84,7 @@ static inline void fm_update()
/* update PSG samples */ /* update PSG samples */
static inline void psg_update() static inline void psg_update()
{ {
if(snd.psg.curStage - snd.psg.lastStage > 0) if(snd.psg.curStage - snd.psg.lastStage > 1)
{ {
int16 *tempBuffer = snd.psg.buffer + snd.psg.lastStage; int16 *tempBuffer = snd.psg.buffer + snd.psg.lastStage;
SN76489_Update (0, tempBuffer, snd.psg.curStage - snd.psg.lastStage); SN76489_Update (0, tempBuffer, snd.psg.curStage - snd.psg.lastStage);
@ -220,12 +220,9 @@ void fm_restore(void)
/* write FM chip */ /* write FM chip */
void fm_write(unsigned int cpu, unsigned int address, unsigned int data) void fm_write(unsigned int cpu, unsigned int address, unsigned int data)
{
if (address & 1)
{ {
snd.fm.curStage = fm_sample_cnt(cpu); snd.fm.curStage = fm_sample_cnt(cpu);
fm_update(); fm_update();
}
_YM2612_Write(address & 3, data); _YM2612_Write(address & 3, data);
} }