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 */
ClearGGCodes (); /* Clear Game Genie patches */
system_reset (); /* System Power ON */
ogc_audio__reset(); /* reset audio buffers */
}
/***************************************************************************
@ -132,8 +131,6 @@ int main (int argc, char *argv[])
DI_Init();
#endif
u16 usBetweenFrames;
long long now, prev;
int RenderedFrameCount = 0;
int FrameCount = 0;
@ -189,41 +186,12 @@ int main (int argc, char *argv[])
MainMenu();
ConfigRequested = 0;
/* Initialize Frame timings */
frameticker = 0;
prev = gettime();
/* Emulation Loop */
while (1)
{
/* audio DMA starting point */
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)
{
/* Frame skipping */
@ -241,7 +209,6 @@ int main (int argc, char *argv[])
}
frameticker--;
}
/* update video & audio */
ogc_audio__update();
@ -268,7 +235,6 @@ int main (int argc, char *argv[])
/* reset frame timings */
frameticker = 0;
prev = gettime();
FrameCount = 0;
RenderedFrameCount = 0;
}

View File

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

View File

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

View File

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

View File

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