comparison 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
comparison
equal deleted inserted replaced
2303:c79896ff1a2d 2304:b3832f73444f
4 #include <math.h> 4 #include <math.h>
5 #include "render_audio.h" 5 #include "render_audio.h"
6 #include "util.h" 6 #include "util.h"
7 #include "config.h" 7 #include "config.h"
8 #include "blastem.h" 8 #include "blastem.h"
9 #include "wave.h"
9 10
10 static uint8_t output_channels; 11 static uint8_t output_channels;
11 static uint32_t buffer_samples, sample_rate; 12 static uint32_t buffer_samples, sample_rate;
12 13
13 static audio_source *audio_sources[8]; 14 static audio_source *audio_sources[8];
15 static uint8_t num_audio_sources; 16 static uint8_t num_audio_sources;
16 static uint8_t num_inactive_audio_sources; 17 static uint8_t num_inactive_audio_sources;
17 18
18 static float overall_gain_mult, *mix_buf; 19 static float overall_gain_mult, *mix_buf;
19 static int sample_size; 20 static int sample_size;
21
22 static FILE *wav_file;
23 void render_end_audio(void)
24 {
25 render_lock_audio();
26 if (wav_file) {
27 wave_finalize(wav_file);
28 fclose(wav_file);
29 wav_file = NULL;
30 }
31 render_unlock_audio();
32 }
33
34 void render_save_audio(char *path)
35 {
36 render_end_audio();
37 FILE *f = fopen(path, "wb");
38 if (f) {
39 wave_init(f, sample_rate, 16, 2);
40 render_lock_audio();
41 wav_file = f;
42 render_unlock_audio();
43 printf("Saving audio to %s\n", path);
44 } else {
45 warning("Failed to open %s for writing\n", path);
46 }
47 free(path);
48 }
20 49
21 typedef void (*conv_func)(float *samples, void *vstream, int sample_count); 50 typedef void (*conv_func)(float *samples, void *vstream, int sample_count);
22 51
23 static void convert_null(float *samples, void *vstream, int sample_count) 52 static void convert_null(float *samples, void *vstream, int sample_count)
24 { 53 {
39 } else { 68 } else {
40 out_sample = sample * 0x7FFF; 69 out_sample = sample * 0x7FFF;
41 } 70 }
42 *stream = out_sample; 71 *stream = out_sample;
43 } 72 }
44 } 73 if (wav_file) {
45 74 fwrite(vstream, sizeof(int16_t), sample_count, wav_file);
75 }
76 }
77
78 static int16_t *wave_buffer;
79 static int wave_buffer_samples;
46 static void clamp_f32(float *samples, void *vstream, int sample_count) 80 static void clamp_f32(float *samples, void *vstream, int sample_count)
47 { 81 {
48 for (; sample_count > 0; sample_count--, samples++) 82 float *start = samples;
83 for (int cur_count = sample_count; cur_count > 0; cur_count--, samples++)
49 { 84 {
50 float sample = *samples; 85 float sample = *samples;
51 if (sample > 1.0f) { 86 if (sample > 1.0f) {
52 sample = 1.0f; 87 sample = 1.0f;
53 } else if (sample < -1.0f) { 88 } else if (sample < -1.0f) {
54 sample = -1.0f; 89 sample = -1.0f;
55 } 90 }
56 *samples = sample; 91 *samples = sample;
92 }
93 if (wav_file) {
94 if (!wave_buffer) {
95 wave_buffer = calloc(sample_count, sizeof(int16_t));
96 wave_buffer_samples = sample_count;
97 } else if (sample_count < wave_buffer_samples) {
98 wave_buffer = realloc(wave_buffer, sizeof(int16_t) * sample_count);
99 wave_buffer_samples = sample_count;
100 }
101 convert_s16(start, wave_buffer, sample_count);
57 } 102 }
58 } 103 }
59 104
60 static int32_t mix_f32(audio_source *audio, float *stream, int samples) 105 static int32_t mix_f32(audio_source *audio, float *stream, int samples)
61 { 106 {