Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions workspace/all/common/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2275,6 +2275,9 @@ SDL_Color GFX_mapColor(uint32_t c)
#ifndef SAMPLES
#define SAMPLES 512 // default
#endif
#ifndef BUFFER_MULTIPLIER
#define BUFFER_MULTIPLIER 8 // default
#endif

#define ms SDL_GetTicks

Expand Down Expand Up @@ -2343,6 +2346,33 @@ void SND_setQuality(int quality)
soundQuality = qualityLevels[quality];
resetSrcState = 1;
}

static int audio_buffer_samples = SAMPLES;
static int audio_buffer_multiplier = BUFFER_MULTIPLIER;

void SND_setBufferSize(int samples) {
if (samples != audio_buffer_samples) {
audio_buffer_samples = samples;
LOG_info("Audio buffer size set to %d samples\n", samples);
if (snd.initialized) {
SND_resetAudio(snd.sample_rate_in, snd.frame_rate);
}
}
}

void SND_setBufferMultiplier(int multiplier) {
if (multiplier != audio_buffer_multiplier) {
audio_buffer_multiplier = multiplier;
if (snd.initialized && snd.sample_rate_out > 0) {
snd.frame_count = ((float)snd.sample_rate_out / SCREEN_FPS) * audio_buffer_multiplier;
perf.buffer_size = snd.frame_count;
SND_resizeBuffer();
SND_pauseAudio(true);
LOG_info("Audio buffer multiplier set to %d, new frame_count: %d\n", multiplier, snd.frame_count);
}
}
}

ResampledFrames resample_audio(const SND_Frame *input_frames,
int input_frame_count, int input_sample_rate,
int output_sample_rate, double ratio)
Expand Down Expand Up @@ -2796,7 +2826,7 @@ void SND_init(double sample_rate, double frame_rate)
spec_in.freq = PLAT_pickSampleRate(sample_rate, MAX_SAMPLE_RATE);
spec_in.format = AUDIO_S16;
spec_in.channels = 2;
spec_in.samples = SAMPLES;
spec_in.samples = audio_buffer_samples;
spec_in.callback = SND_audioCallback;

#if defined(USE_SDL2)
Expand All @@ -2821,7 +2851,7 @@ void SND_init(double sample_rate, double frame_rate)

LOG_info("We now have audio device #%d\n", snd.device_id);

snd.frame_count = ((float)spec_out.freq / SCREEN_FPS) * 8; // buffer size based on sample rate out (times 12 samples headroom)
snd.frame_count = ((float)spec_out.freq / SCREEN_FPS) * audio_buffer_multiplier;
perf.buffer_size = snd.frame_count;
snd.sample_rate_in = sample_rate;
snd.sample_rate_out = spec_out.freq;
Expand All @@ -2832,7 +2862,7 @@ void SND_init(double sample_rate, double frame_rate)

// start with audiodevice paused so buffer can fill a little, snd_batchsamples will unpause it
SND_pauseAudio(true);
LOG_info("sample rate: %i (req) %i (rec) [samples %i]\n", snd.sample_rate_in, snd.sample_rate_out, SAMPLES);
LOG_info("sample rate: %i (req) %i (rec) [samples %i]\n", snd.sample_rate_in, snd.sample_rate_out, audio_buffer_samples);
snd.initialized = 1;

}
Expand Down Expand Up @@ -4388,4 +4418,4 @@ FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamBegin(int buffersize) {}
FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamEnd() {}
FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamQuit() {}
FALLBACK_IMPLEMENTATION int PLAT_bluetoothVolume() { return 100; }
FALLBACK_IMPLEMENTATION void PLAT_bluetoothSetVolume(int vol) {}
FALLBACK_IMPLEMENTATION void PLAT_bluetoothSetVolume(int vol) {}
2 changes: 2 additions & 0 deletions workspace/all/common/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ void SND_quit(void);
void SND_resetAudio(double sample_rate, double frame_rate);
void SND_pauseAudio(bool paused);
void SND_setQuality(int quality);
void SND_setBufferSize(int samples);
void SND_setBufferMultiplier(int multiplier);

// watch audio device changes
typedef enum {
Expand Down
40 changes: 40 additions & 0 deletions workspace/all/minarch/minarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,14 @@ static char* resample_labels[] = {
"Max",
NULL
};
static char* buffer_size_labels[] = {
"128", "256", "512", "1024",
NULL
};
static char* buffer_multiplier_labels[] = {
"4", "6", "8", "10",
NULL
};
static char* rewind_enable_labels[] = {
"Off",
"On",
Expand Down Expand Up @@ -2319,6 +2327,8 @@ enum {
FE_OPT_REWIND_COMPRESSION,
FE_OPT_REWIND_COMPRESSION_ACCEL,
FE_OPT_REWIND_AUDIO,
FE_OPT_AUDIO_BUFFER,
FE_OPT_AUDIO_LATENCY,
FE_OPT_COUNT,
};

Expand Down Expand Up @@ -2737,6 +2747,26 @@ static struct Config {
.values = onoff_labels,
.labels = onoff_labels,
},
[FE_OPT_AUDIO_BUFFER] = {
.key = "minarch__audio_buffer",
.name = "Audio Buffer Size",
.desc = "Size of audio chunks sent to the device.\nSmaller values lower latency but use more CPU.",
.default_value = 2,
.value = 2,
.count = 4,
.values = buffer_size_labels,
.labels = buffer_size_labels,
},
[FE_OPT_AUDIO_LATENCY] = {
.key = "minarch__audio_latency",
.name = "Audio Buffer Headroom",
.desc = "How much audio is buffered ahead of time.\nSmaller values lower latency but may crackle.",
.default_value = 2,
.value = 2,
.count = 4,
.values = buffer_multiplier_labels,
.labels = buffer_multiplier_labels,
},
[FE_OPT_COUNT] = {NULL}
}
},
Expand Down Expand Up @@ -3109,6 +3139,16 @@ static void Config_syncFrontend(char* key, int value) {
else if (exactMatch(key,config.frontend.options[FE_OPT_REWIND_COMPRESSION_ACCEL].key)) {
i = FE_OPT_REWIND_COMPRESSION_ACCEL;
}
else if (exactMatch(key, config.frontend.options[FE_OPT_AUDIO_BUFFER].key)) {
int buf_size = atoi(config.frontend.options[FE_OPT_AUDIO_BUFFER].values[value]);
SND_setBufferSize(buf_size);
i = FE_OPT_AUDIO_BUFFER;
}
else if (exactMatch(key, config.frontend.options[FE_OPT_AUDIO_LATENCY].key)) {
int multiplier = atoi(config.frontend.options[FE_OPT_AUDIO_LATENCY].values[value]);
SND_setBufferMultiplier(multiplier);
i = FE_OPT_AUDIO_LATENCY;
}
if (i==-1) return;
Option* option = &config.frontend.options[i];
option->value = value;
Expand Down