add logic to update the playback rate dynamically

This commit is contained in:
Daryl Borth 2018-08-22 17:24:37 -06:00
parent babf402d01
commit 3d298ff126
3 changed files with 30 additions and 22 deletions

View File

@ -39,43 +39,51 @@ extern int ConfigRequested;
static u8 soundbuffer[BUFFERCOUNT][AUDIOBUFFER] __attribute__ ((__aligned__ (32)));
static int playab = 0;
static int nextab = 0;
int available = 0;
static int unplayed = 0;
static inline void updateAvailable(int diff) {
available += diff;
static inline void updateUnplayed(int diff) {
unplayed += diff;
if(available < 0) {
available = 0;
if(unplayed < 0) {
unplayed = 0;
}
else if(available > BUFFERCOUNT-1) {
available = BUFFERCOUNT-1;
else if(unplayed > BUFFERCOUNT-1) {
unplayed = BUFFERCOUNT-1;
}
}
static void DMACallback () {
if (!ScreenshotRequested && !ConfigRequested) {
updateUnplayed(-1);
AUDIO_InitDMA ((u32) soundbuffer[playab], AUDIOBUFFER);
updateAvailable(-1);
playab = (playab + 1) % BUFFERCOUNT;
}
}
static void S9xAudioCallback (void *data) {
//S9xUpdateDynamicRate(); // TODO: what arguments should be passed here?
double rate = 1.0;
if(unplayed > 8) {
rate = 1.005;
}
else if(unplayed < 4) {
rate = 0.995;
}
S9xUpdateDynamicRate(rate);
S9xFinalizeSamples();
int availableSamples = S9xGetSampleCount();
if (ScreenshotRequested || ConfigRequested) {
AUDIO_StopDMA();
}
else if(availableSamples >= SAMPLES_TO_PROCESS) {
nextab = (nextab + 1) % BUFFERCOUNT;
updateAvailable(1);
else if(S9xGetSampleCount() >= SAMPLES_TO_PROCESS) {
S9xMixSamples (soundbuffer[nextab], SAMPLES_TO_PROCESS);
DCFlushRange (soundbuffer[nextab], AUDIOBUFFER);
updateUnplayed(1);
nextab = (nextab + 1) % BUFFERCOUNT;
if(playab == -1) {
if(available > 2) {
if(unplayed > 2) {
playab = 0;
AUDIO_StartDMA();
}
@ -150,7 +158,7 @@ void ShutdownAudio()
void
AudioStart ()
{
available = 0;
unplayed = 0;
nextab = 0;
playab = -1;
}

View File

@ -465,13 +465,13 @@ void S9xSetSamplesAvailableCallback (apu_callback callback, void *data)
spc::extra_data = data;
}
void S9xUpdateDynamicRate (int avail, int buffer_size)
void S9xUpdateDynamicRate (double rate)
{
spc::dynamic_rate_multiplier = 1.0 + (Settings.DynamicRateLimit * (buffer_size - 2 * avail)) /
(double)(1000 * buffer_size);
if(spc::dynamic_rate_multiplier != rate) {
spc::dynamic_rate_multiplier = rate;
UpdatePlaybackRate();
}
}
void UpdatePlaybackRate (void)
{

View File

@ -214,7 +214,7 @@ void S9xFinalizeSamples (void);
void S9xClearSamples (void);
bool8 S9xMixSamples (uint8 *, int);
void S9xSetSamplesAvailableCallback (apu_callback, void *);
void S9xUpdateDynamicRate (int, int);
void S9xUpdateDynamicRate (double rate);
extern SNES_SPC *spc_core;