Mercurial > repos > blastem
diff render_audio.c @ 2304:b3832f73444f
Save audio to a wave file when saving video to APNG
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 15 Mar 2023 18:50:24 -0700 |
parents | 46ee354f29bd |
children | 35f765c2bc87 |
line wrap: on
line diff
--- a/render_audio.c Wed Mar 15 18:49:47 2023 -0700 +++ b/render_audio.c Wed Mar 15 18:50:24 2023 -0700 @@ -6,6 +6,7 @@ #include "util.h" #include "config.h" #include "blastem.h" +#include "wave.h" static uint8_t output_channels; static uint32_t buffer_samples, sample_rate; @@ -18,6 +19,34 @@ static float overall_gain_mult, *mix_buf; static int sample_size; +static FILE *wav_file; +void render_end_audio(void) +{ + render_lock_audio(); + if (wav_file) { + wave_finalize(wav_file); + fclose(wav_file); + wav_file = NULL; + } + render_unlock_audio(); +} + +void render_save_audio(char *path) +{ + render_end_audio(); + FILE *f = fopen(path, "wb"); + if (f) { + wave_init(f, sample_rate, 16, 2); + render_lock_audio(); + wav_file = f; + render_unlock_audio(); + printf("Saving audio to %s\n", path); + } else { + warning("Failed to open %s for writing\n", path); + } + free(path); +} + typedef void (*conv_func)(float *samples, void *vstream, int sample_count); static void convert_null(float *samples, void *vstream, int sample_count) @@ -41,11 +70,17 @@ } *stream = out_sample; } + if (wav_file) { + fwrite(vstream, sizeof(int16_t), sample_count, wav_file); + } } +static int16_t *wave_buffer; +static int wave_buffer_samples; static void clamp_f32(float *samples, void *vstream, int sample_count) { - for (; sample_count > 0; sample_count--, samples++) + float *start = samples; + for (int cur_count = sample_count; cur_count > 0; cur_count--, samples++) { float sample = *samples; if (sample > 1.0f) { @@ -55,6 +90,16 @@ } *samples = sample; } + if (wav_file) { + if (!wave_buffer) { + wave_buffer = calloc(sample_count, sizeof(int16_t)); + wave_buffer_samples = sample_count; + } else if (sample_count < wave_buffer_samples) { + wave_buffer = realloc(wave_buffer, sizeof(int16_t) * sample_count); + wave_buffer_samples = sample_count; + } + convert_s16(start, wave_buffer, sample_count); + } } static int32_t mix_f32(audio_source *audio, float *stream, int samples)