Skip to content

Commit 26df565

Browse files
committed
SNES: Fixed amount of audio samples played each frame
I've also removed the double buffering option, as it's useless.
1 parent ae9133e commit 26df565

File tree

1 file changed

+35
-34
lines changed

1 file changed

+35
-34
lines changed

snes9x/main/main_snes.c

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include <snes9x.h>
33
#include <math.h>
44

5-
#define AUDIO_SAMPLE_RATE (32000)
5+
#define AUDIO_SAMPLE_RATE (32040)
66
#define AUDIO_BUFFER_LENGTH (AUDIO_SAMPLE_RATE / 50 + 1)
77

88
// #define FRAME_DOUBLE_BUFFERING
@@ -96,8 +96,6 @@ static const char *SNES_BUTTONS[] = {
9696
static rg_app_t *app;
9797
static rg_surface_t *updates[2];
9898
static rg_surface_t *currentUpdate;
99-
static rg_audio_sample_t *audioBuffers[2];
100-
static rg_audio_sample_t *currentAudioBuffer;
10199

102100
#ifdef USE_AUDIO_TASK
103101
static rg_task_t *audio_task_handle;
@@ -138,8 +136,6 @@ static bool load_state_handler(const char *filename)
138136
static bool reset_handler(bool hard)
139137
{
140138
S9xReset();
141-
memset(audioBuffers[0], 0, AUDIO_BUFFER_LENGTH * 4);
142-
memset(audioBuffers[1], 0, AUDIO_BUFFER_LENGTH * 4);
143139
return true;
144140
}
145141

@@ -310,26 +306,30 @@ void JustifierButtons(uint32_t *justifiers)
310306
(void)justifiers;
311307
}
312308

313-
static inline void mix_samples(int32_t count)
314-
{
315-
currentAudioBuffer = audioBuffers[currentAudioBuffer == audioBuffers[0]];
316-
if (lowpass_filter)
317-
S9xMixSamplesLowPass((int16_t *)currentAudioBuffer, count, AUDIO_LOW_PASS_RANGE);
318-
else
319-
S9xMixSamples((int16_t *)currentAudioBuffer, count);
320-
}
321-
322309
#ifdef USE_AUDIO_TASK
323310
static void audio_task(void *arg)
324311
{
312+
rg_audio_sample_t audioBuffer[AUDIO_BUFFER_LENGTH];
325313
rg_task_msg_t msg;
314+
bool zeroed = false;
326315
while (rg_task_receive(&msg))
327316
{
328317
if (msg.type == RG_TASK_MSG_STOP)
329318
break;
330-
if (msg.type != 0)
331-
mix_samples(AUDIO_BUFFER_LENGTH << 1);
332-
rg_audio_submit(currentAudioBuffer, AUDIO_BUFFER_LENGTH);
319+
if (msg.type != 0) // Sound enabled, mix
320+
{
321+
if (lowpass_filter)
322+
S9xMixSamplesLowPass((int16_t *)audioBuffer, msg.dataInt << 1, AUDIO_LOW_PASS_RANGE);
323+
else
324+
S9xMixSamples((int16_t *)audioBuffer, msg.dataInt << 1);
325+
zeroed = false;
326+
}
327+
else if (!zeroed) // Sound disabled, zero buffer only if needed
328+
{
329+
memset(audioBuffer, 0, sizeof(audioBuffer));
330+
zeroed = true;
331+
}
332+
rg_audio_submit(audioBuffer, msg.dataInt);
333333
}
334334
}
335335
#endif
@@ -371,22 +371,15 @@ void app_main(void)
371371
#endif
372372
currentUpdate = updates[0];
373373

374-
#ifdef AUDIO_DOUBLE_BUFFERING
375-
audioBuffers[0] = (rg_audio_sample_t *)calloc(AUDIO_BUFFER_LENGTH, 4);
376-
audioBuffers[1] = (rg_audio_sample_t *)calloc(AUDIO_BUFFER_LENGTH, 4);
377-
#else
378-
audioBuffers[0] = (rg_audio_sample_t *)calloc(AUDIO_BUFFER_LENGTH, 4);
379-
audioBuffers[1] = audioBuffers[0];
380-
#endif
381-
currentAudioBuffer = audioBuffers[0];
382-
383-
if (!updates[0] || !updates[1] || !audioBuffers[0] || !audioBuffers[1])
374+
if (!updates[0] || !updates[1])
384375
RG_PANIC("Failed to allocate buffers!");
385376

386377
#ifdef USE_AUDIO_TASK
387378
// Set up multicore audio
388-
audio_task_handle = rg_task_create("snes_audio", &audio_task, NULL, 2048, RG_TASK_PRIORITY_6, 1);
379+
audio_task_handle = rg_task_create("snes_audio", &audio_task, NULL, 4096, RG_TASK_PRIORITY_6, 1);
389380
RG_ASSERT(audio_task_handle, "Failed to create audio task!");
381+
#else
382+
rg_audio_sample_t *audioBuffer = (rg_audio_sample_t *)calloc(AUDIO_BUFFER_LENGTH, 4);
390383
#endif
391384

392385
Settings.CyclesPercentage = 100;
@@ -437,6 +430,8 @@ void app_main(void)
437430
rg_system_set_tick_rate(Memory.ROMFramesPerSecond);
438431
app->frameskip = 3;
439432

433+
const float samplesPerFrame = (float)app->sampleRate / app->tickRate;
434+
float samplesRemaining = 0.f;
440435
bool menuCancelled = false;
441436
bool menuPressed = false;
442437
int skipFrames = 0;
@@ -463,8 +458,6 @@ void app_main(void)
463458
else if (joystick & RG_KEY_OPTION)
464459
{
465460
rg_gui_options_menu();
466-
memset(audioBuffers[0], 0, AUDIO_BUFFER_LENGTH * 4);
467-
memset(audioBuffers[1], 0, AUDIO_BUFFER_LENGTH * 4);
468461
continue;
469462
}
470463

@@ -487,17 +480,25 @@ void app_main(void)
487480
currentUpdate = updates[currentUpdate == updates[0]];
488481
}
489482

483+
samplesRemaining += samplesPerFrame;
484+
int samples = (int)samplesRemaining;
485+
samplesRemaining -= samples;
486+
490487
#ifdef USE_AUDIO_TASK
491488
rg_system_tick(rg_system_timer() - startTime);
492-
rg_task_msg_t msg = {.type = (int)sound_enabled};
489+
rg_task_msg_t msg = {.type = (int)sound_enabled, .dataInt = samples};
493490
if (sound_enabled || app->frameTime - (rg_system_timer() - startTime) > 2000)
494491
rg_task_send(audio_task_handle, &msg);
495492
#else
496-
if (sound_enabled)
497-
mix_samples(AUDIO_BUFFER_LENGTH << 1);
493+
if (sound_enabled && lowpass_filter)
494+
S9xMixSamplesLowPass((int16_t *)audioBuffer, samples << 1, AUDIO_LOW_PASS_RANGE);
495+
else if (sound_enabled)
496+
S9xMixSamples((int16_t *)audioBuffer, samples << 1);
497+
else
498+
memset(audioBuffer, 0, AUDIO_BUFFER_LENGTH * sizeof(rg_audio_sample_t));
498499
rg_system_tick(rg_system_timer() - startTime);
499500
if (sound_enabled || app->frameTime - (rg_system_timer() - startTime) > 2000)
500-
rg_audio_submit(currentAudioBuffer, AUDIO_BUFFER_LENGTH);
501+
rg_audio_submit(audioBuffer, samples);
501502
#endif
502503

503504
if (skipFrames == 0)

0 commit comments

Comments
 (0)