mirror of
https://github.com/libretro/RetroArch
synced 2025-02-26 06:40:39 +00:00
(CTR/3DS) improve audio/video sync.
This commit is contained in:
parent
ec284a5db0
commit
48ec5190ba
@ -31,10 +31,7 @@ typedef struct
|
|||||||
uint32_t pos;
|
uint32_t pos;
|
||||||
|
|
||||||
uint32_t playpos;
|
uint32_t playpos;
|
||||||
uint32_t cpu_ticks_per_sample;
|
|
||||||
uint64_t cpu_ticks_last;
|
uint64_t cpu_ticks_last;
|
||||||
|
|
||||||
int rate;
|
|
||||||
} ctr_audio_t;
|
} ctr_audio_t;
|
||||||
|
|
||||||
#define CTR_AUDIO_COUNT (1u << 11u)
|
#define CTR_AUDIO_COUNT (1u << 11u)
|
||||||
@ -42,19 +39,23 @@ typedef struct
|
|||||||
#define CTR_AUDIO_SIZE (CTR_AUDIO_COUNT * sizeof(int16_t))
|
#define CTR_AUDIO_SIZE (CTR_AUDIO_COUNT * sizeof(int16_t))
|
||||||
#define CTR_AUDIO_SIZE_MASK (CTR_AUDIO_SIZE - 1u)
|
#define CTR_AUDIO_SIZE_MASK (CTR_AUDIO_SIZE - 1u)
|
||||||
|
|
||||||
|
#define CTR_AUDIO_RATE 32730
|
||||||
|
#define CTR_CSND_TICKS_PER_SAMPLE 2048
|
||||||
|
#define CTR_CPU_TICKS_PER_SAMPLE (CTR_CSND_TICKS_PER_SAMPLE * 4)
|
||||||
|
|
||||||
static void ctr_audio_update_playpos(ctr_audio_t* ctr)
|
static void ctr_audio_update_playpos(ctr_audio_t* ctr)
|
||||||
{
|
{
|
||||||
uint32_t samples_played;
|
uint32_t samples_played;
|
||||||
uint64_t current_tick;
|
uint64_t current_tick;
|
||||||
|
|
||||||
current_tick = svcGetSystemTick();
|
current_tick = svcGetSystemTick();
|
||||||
samples_played = (current_tick - ctr->cpu_ticks_last) / ctr->cpu_ticks_per_sample;
|
samples_played = (current_tick - ctr->cpu_ticks_last) / CTR_CPU_TICKS_PER_SAMPLE;
|
||||||
ctr->playpos = (ctr->playpos + samples_played) & CTR_AUDIO_COUNT_MASK;
|
ctr->playpos = (ctr->playpos + samples_played) & CTR_AUDIO_COUNT_MASK;
|
||||||
ctr->cpu_ticks_last += samples_played * ctr->cpu_ticks_per_sample;
|
ctr->cpu_ticks_last += samples_played * CTR_CPU_TICKS_PER_SAMPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result csndPlaySound_custom(int chn, u32 flags, u32 sampleRate, float vol, float pan, void* data0, void* data1, u32 size)
|
Result csndPlaySound_custom(int chn, u32 flags, float vol, float pan, void* data0, void* data1, u32 size)
|
||||||
{
|
{
|
||||||
if (!(csndChannels & BIT(chn)))
|
if (!(csndChannels & BIT(chn)))
|
||||||
return 1;
|
return 1;
|
||||||
@ -79,11 +80,8 @@ Result csndPlaySound_custom(int chn, u32 flags, u32 sampleRate, float vol, float
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 timer = CSND_TIMER(sampleRate);
|
|
||||||
if (timer < 0x0042) timer = 0x0042;
|
|
||||||
else if (timer > 0xFFFF) timer = 0xFFFF;
|
|
||||||
flags &= ~0xFFFF001F;
|
flags &= ~0xFFFF001F;
|
||||||
flags |= SOUND_ENABLE | SOUND_CHANNEL(chn) | (timer << 16);
|
flags |= SOUND_ENABLE | SOUND_CHANNEL(chn) | (CTR_CSND_TICKS_PER_SAMPLE << 16);
|
||||||
|
|
||||||
u32 volumes = CSND_VOL(vol, pan);
|
u32 volumes = CSND_VOL(vol, pan);
|
||||||
CSND_SetChnRegs(flags, paddr0, paddr1, size, volumes, volumes);
|
CSND_SetChnRegs(flags, paddr0, paddr1, size, volumes, volumes);
|
||||||
@ -98,10 +96,10 @@ Result csndPlaySound_custom(int chn, u32 flags, u32 sampleRate, float vol, float
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency)
|
static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||||
{
|
{
|
||||||
ctr_audio_t *ctr = (ctr_audio_t*)calloc(1, sizeof(ctr_audio_t));
|
ctr_audio_t *ctr = (ctr_audio_t*)calloc(1, sizeof(ctr_audio_t));
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
|
||||||
if (!ctr)
|
if (!ctr)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -110,6 +108,8 @@ static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency)
|
|||||||
(void)rate;
|
(void)rate;
|
||||||
(void)latency;
|
(void)latency;
|
||||||
|
|
||||||
|
settings->audio.out_rate = CTR_AUDIO_RATE;
|
||||||
|
|
||||||
ctr->l = linearAlloc(CTR_AUDIO_SIZE);
|
ctr->l = linearAlloc(CTR_AUDIO_SIZE);
|
||||||
ctr->r = linearAlloc(CTR_AUDIO_SIZE);
|
ctr->r = linearAlloc(CTR_AUDIO_SIZE);
|
||||||
|
|
||||||
@ -120,16 +120,14 @@ static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency)
|
|||||||
ctr->r_paddr = osConvertVirtToPhys((u32)ctr->r);
|
ctr->r_paddr = osConvertVirtToPhys((u32)ctr->r);
|
||||||
|
|
||||||
ctr->pos = 0;
|
ctr->pos = 0;
|
||||||
ctr->rate = rate;
|
|
||||||
ctr->cpu_ticks_per_sample = CSND_TIMER(rate) * 4;
|
|
||||||
|
|
||||||
GSPGPU_FlushDataCache(NULL, (u8*)ctr->l_paddr, CTR_AUDIO_SIZE);
|
GSPGPU_FlushDataCache(NULL, (u8*)ctr->l_paddr, CTR_AUDIO_SIZE);
|
||||||
GSPGPU_FlushDataCache(NULL, (u8*)ctr->r_paddr, CTR_AUDIO_SIZE);
|
GSPGPU_FlushDataCache(NULL, (u8*)ctr->r_paddr, CTR_AUDIO_SIZE);
|
||||||
csndPlaySound_custom(0x8, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
|
csndPlaySound_custom(0x8, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
|
||||||
rate, 1.0, -1.0, ctr->l, ctr->l, CTR_AUDIO_SIZE);
|
1.0, -1.0, ctr->l, ctr->l, CTR_AUDIO_SIZE);
|
||||||
|
|
||||||
csndPlaySound_custom(0x9, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
|
csndPlaySound_custom(0x9, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
|
||||||
rate, 1.0, 1.0, ctr->r, ctr->r, CTR_AUDIO_SIZE);
|
1.0, 1.0, ctr->r, ctr->r, CTR_AUDIO_SIZE);
|
||||||
|
|
||||||
csndExecCmds(true);
|
csndExecCmds(true);
|
||||||
ctr->playpos = 0;
|
ctr->playpos = 0;
|
||||||
|
@ -582,7 +582,9 @@ static const bool font_enable = true;
|
|||||||
* This value should stay close to 60Hz to avoid large pitch changes.
|
* This value should stay close to 60Hz to avoid large pitch changes.
|
||||||
* If your monitor does not run at 60Hz, or something close to it,
|
* If your monitor does not run at 60Hz, or something close to it,
|
||||||
* disable VSync, and leave this at its default. */
|
* disable VSync, and leave this at its default. */
|
||||||
#if defined(RARCH_CONSOLE)
|
#ifdef _3DS
|
||||||
|
static const float refresh_rate = (32730.0 * 8192.0) / 4481134.0 ;
|
||||||
|
#elif defined(RARCH_CONSOLE)
|
||||||
static const float refresh_rate = 60/1.001;
|
static const float refresh_rate = 60/1.001;
|
||||||
#else
|
#else
|
||||||
static const float refresh_rate = 59.95;
|
static const float refresh_rate = 59.95;
|
||||||
@ -601,6 +603,8 @@ static const bool audio_enable = true;
|
|||||||
/* Output samplerate. */
|
/* Output samplerate. */
|
||||||
#ifdef GEKKO
|
#ifdef GEKKO
|
||||||
static const unsigned out_rate = 32000;
|
static const unsigned out_rate = 32000;
|
||||||
|
#elif defined(_3DS)
|
||||||
|
static const unsigned out_rate = 32730;
|
||||||
#else
|
#else
|
||||||
static const unsigned out_rate = 48000;
|
static const unsigned out_rate = 48000;
|
||||||
#endif
|
#endif
|
||||||
|
@ -345,6 +345,8 @@ static void* ctr_init(const video_info_t* video,
|
|||||||
ctr->empty_framebuffer = linearAlloc(320 * 240 * 2);
|
ctr->empty_framebuffer = linearAlloc(320 * 240 * 2);
|
||||||
memset(ctr->empty_framebuffer, 0, 320 * 240 * 2);
|
memset(ctr->empty_framebuffer, 0, 320 * 240 * 2);
|
||||||
|
|
||||||
|
driver_set_refresh_rate((32730.0 * 8192.0) / 4481134.0);
|
||||||
|
|
||||||
return ctr;
|
return ctr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@
|
|||||||
#define CTRGU_MULTISAMPLE_2x2 (2 << 24)
|
#define CTRGU_MULTISAMPLE_2x2 (2 << 24)
|
||||||
|
|
||||||
#define CTR_CPU_TICKS_PER_SECOND 268123480
|
#define CTR_CPU_TICKS_PER_SECOND 268123480
|
||||||
|
#define CTR_CPU_TICKS_PER_FRAME 4481134
|
||||||
|
|
||||||
|
|
||||||
extern Handle gspEvents[GSPEVENT_MAX];
|
extern Handle gspEvents[GSPEVENT_MAX];
|
||||||
extern u32* gpuCmdBuf;
|
extern u32* gpuCmdBuf;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user