annotate render_audio.c @ 1971:80920c21bb52

Add an event log soft flush and call it twice per frame in between hard flushes to netplay latency when there are insufficient hardware updates to flush packets in the middle of a frame
author Michael Pavone <pavone@retrodev.com>
date Fri, 08 May 2020 11:40:30 -0700
parents e4671a39d155
children cfd53c94fffb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1865
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include <limits.h>
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include <string.h>
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 #include <stdlib.h>
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #include <math.h>
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5 #include "render_audio.h"
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 #include "util.h"
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 #include "config.h"
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 #include "blastem.h"
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 static uint8_t output_channels;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 static uint32_t buffer_samples, sample_rate;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13 static audio_source *audio_sources[8];
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 static audio_source *inactive_audio_sources[8];
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 static uint8_t num_audio_sources;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 static uint8_t num_inactive_audio_sources;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 static float overall_gain_mult, *mix_buf;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 static int sample_size;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 typedef void (*conv_func)(float *samples, void *vstream, int sample_count);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 static void convert_null(float *samples, void *vstream, int sample_count)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 memset(vstream, 0, sample_count * sample_size);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 static void convert_s16(float *samples, void *vstream, int sample_count)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 int16_t *stream = vstream;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 for (int16_t *end = stream + sample_count; stream < end; stream++, samples++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 float sample = *samples;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 int16_t out_sample;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 if (sample >= 1.0f) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 out_sample = 0x7FFF;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 } else if (sample <= -1.0f) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 out_sample = -0x8000;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 } else {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 out_sample = sample * 0x7FFF;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 *stream = out_sample;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 static void clamp_f32(float *samples, void *vstream, int sample_count)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 for (; sample_count > 0; sample_count--, samples++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 float sample = *samples;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 if (sample > 1.0f) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 sample = 1.0f;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 } else if (sample < -1.0f) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 sample = -1.0f;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 *samples = sample;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 static int32_t mix_f32(audio_source *audio, float *stream, int samples)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 float *end = stream + samples;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 int16_t *src = audio->front;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 uint32_t i = audio->read_start;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 uint32_t i_end = audio->read_end;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 float *cur = stream;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 float gain_mult = audio->gain_mult * overall_gain_mult;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 size_t first_add = output_channels > 1 ? 1 : 0, second_add = output_channels > 1 ? output_channels - 1 : 1;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 if (audio->num_channels == 1) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 while (cur < end && i != i_end)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 *cur += gain_mult * ((float)src[i]) / 0x7FFF;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 cur += first_add;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 *cur += gain_mult * ((float)src[i++]) / 0x7FFF;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 cur += second_add;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 i &= audio->mask;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 } else {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79 while(cur < end && i != i_end)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
81 *cur += gain_mult * ((float)src[i++]) / 0x7FFF;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 cur += first_add;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 *cur += gain_mult * ((float)src[i++]) / 0x7FFF;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 cur += second_add;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
85 i &= audio->mask;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
88 if (!render_is_audio_sync()) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89 audio->read_start = i;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 if (cur != end) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 debug_message("Underflow of %d samples, read_start: %d, read_end: %d, mask: %X\n", (int)(end-cur)/2, audio->read_start, audio->read_end, audio->mask);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93 return (cur-end)/2;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 } else {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 return ((i_end - i) & audio->mask) / audio->num_channels;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99 static conv_func convert;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 int mix_and_convert(unsigned char *byte_stream, int len, int *min_remaining_out)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 int samples = len / sample_size;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 float *mix_dest = mix_buf ? mix_buf : (float *)byte_stream;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 memset(mix_dest, 0, samples * sizeof(float));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 int min_buffered = INT_MAX;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 int min_remaining_buffer = INT_MAX;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109 for (uint8_t i = 0; i < num_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 int buffered = mix_f32(audio_sources[i], mix_dest, samples);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 int remaining = (audio_sources[i]->mask + 1) / audio_sources[i]->num_channels - buffered;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 min_buffered = buffered < min_buffered ? buffered : min_buffered;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 min_remaining_buffer = remaining < min_remaining_buffer ? remaining : min_remaining_buffer;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115 audio_sources[i]->front_populated = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 render_buffer_consumed(audio_sources[i]);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
118 convert(mix_dest, byte_stream, samples);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119 if (min_remaining_out) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
120 *min_remaining_out = min_remaining_buffer;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
121 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
122 return min_buffered;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
123 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
124
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
125 uint8_t all_sources_ready(void)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127 uint8_t num_populated = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 num_populated = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129 for (uint8_t i = 0; i < num_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 if (audio_sources[i]->front_populated) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 num_populated++;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
133 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
135 return num_populated == num_audio_sources;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 #define BUFFER_INC_RES 0x40000000UL
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
140 void render_audio_adjust_clock(audio_source *src, uint64_t master_clock, uint64_t sample_divider)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 src->buffer_inc = ((BUFFER_INC_RES * (uint64_t)sample_rate) / master_clock) * sample_divider;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
144
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
145 void render_audio_adjust_speed(float adjust_ratio)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
146 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 for (uint8_t i = 0; i < num_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 audio_sources[i]->buffer_inc = ((double)audio_sources[i]->buffer_inc) + ((double)audio_sources[i]->buffer_inc) * adjust_ratio + 0.5;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
150 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
152
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
153 audio_source *render_audio_source(uint64_t master_clock, uint64_t sample_divider, uint8_t channels)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
154 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 audio_source *ret = NULL;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
156 uint32_t alloc_size = render_is_audio_sync() ? channels * buffer_samples : nearest_pow2(render_min_buffered() * 4 * channels);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
157 render_lock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 if (num_audio_sources < 8) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 ret = calloc(1, sizeof(audio_source));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 ret->back = malloc(alloc_size * sizeof(int16_t));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 ret->front = render_is_audio_sync() ? malloc(alloc_size * sizeof(int16_t)) : ret->back;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162 ret->front_populated = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
163 ret->opaque = render_new_audio_opaque();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
164 ret->num_channels = channels;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 audio_sources[num_audio_sources++] = ret;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
166 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
167 render_unlock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
168 if (!ret) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
169 fatal_error("Too many audio sources!");
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
170 } else {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 render_audio_adjust_clock(ret, master_clock, sample_divider);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 double lowpass_cutoff = get_lowpass_cutoff(config);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173 double rc = (1.0 / lowpass_cutoff) / (2.0 * M_PI);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 ret->dt = 1.0 / ((double)master_clock / (double)(sample_divider));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175 double alpha = ret->dt / (ret->dt + rc);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 ret->lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
177 ret->buffer_pos = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 ret->buffer_fraction = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
179 ret->last_left = ret->last_right = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
180 ret->read_start = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
181 ret->read_end = render_is_audio_sync() ? buffer_samples * channels : 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
182 ret->mask = render_is_audio_sync() ? 0xFFFFFFFF : alloc_size-1;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
183 ret->gain_mult = 1.0f;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
184 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
185 render_audio_created(ret);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 return ret;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
188 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
189
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
191 static float db_to_mult(float gain)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
192 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
193 return powf(10.0f, gain/20.0f);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
194 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
195
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
196 void render_audio_source_gaindb(audio_source *src, float gain)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
197 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
198 src->gain_mult = db_to_mult(gain);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
199 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
200
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
201 void render_pause_source(audio_source *src)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
202 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
203 uint8_t found = 0, remaining_sources;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
204 render_lock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
205 for (uint8_t i = 0; i < num_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
206 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
207 if (audio_sources[i] == src) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
208 audio_sources[i] = audio_sources[--num_audio_sources];
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
209 found = 1;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
210 remaining_sources = num_audio_sources;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
211 break;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
212 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
213 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
214
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
215 render_unlock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
216 if (found) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
217 render_source_paused(src, remaining_sources);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
218 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
219 inactive_audio_sources[num_inactive_audio_sources++] = src;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
220 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
221
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
222 void render_resume_source(audio_source *src)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
223 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
224 render_lock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
225 if (num_audio_sources < 8) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
226 audio_sources[num_audio_sources++] = src;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
227 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
228 render_unlock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
229 for (uint8_t i = 0; i < num_inactive_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
230 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
231 if (inactive_audio_sources[i] == src) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
232 inactive_audio_sources[i] = inactive_audio_sources[--num_inactive_audio_sources];
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
233 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
234 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
235 render_source_resumed(src);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
236 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
237
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
238 void render_free_source(audio_source *src)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
239 {
1870
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
240 uint8_t found = 0;
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
241 for (uint8_t i = 0; i < num_inactive_audio_sources; i++)
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
242 {
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
243 if (inactive_audio_sources[i] == src) {
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
244 inactive_audio_sources[i] = inactive_audio_sources[--num_inactive_audio_sources];
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
245 found = 1;
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
246 break;
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
247 }
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
248 }
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
249 if (!found) {
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
250 render_pause_source(src);
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
251 num_inactive_audio_sources--;
e4671a39d155 Properly handle freeing a paused audio source. Fixes crash when repeatedly reloading a ROM or loading a sequence of different ROMs
Michael Pavone <pavone@retrodev.com>
parents: 1865
diff changeset
252 }
1865
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
253
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
254 free(src->front);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
255 if (render_is_audio_sync()) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
256 free(src->back);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
257 render_free_audio_opaque(src->opaque);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
258 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
259 free(src);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
260 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
261
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
262 static int16_t lowpass_sample(audio_source *src, int16_t last, int16_t current)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
263 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
264 int32_t tmp = current * src->lowpass_alpha + last * (0x10000 - src->lowpass_alpha);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
265 current = tmp >> 16;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
266 return current;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
267 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
268
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
269 static void interp_sample(audio_source *src, int16_t last, int16_t current)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
270 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
271 int64_t tmp = last * ((src->buffer_fraction << 16) / src->buffer_inc);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
272 tmp += current * (0x10000 - ((src->buffer_fraction << 16) / src->buffer_inc));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
273 src->back[src->buffer_pos++] = tmp >> 16;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
274 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
275
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
276 static uint32_t sync_samples;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
277 void render_put_mono_sample(audio_source *src, int16_t value)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
278 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
279 value = lowpass_sample(src, src->last_left, value);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
280 src->buffer_fraction += src->buffer_inc;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
281 uint32_t base = render_is_audio_sync() ? 0 : src->read_end;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
282 while (src->buffer_fraction > BUFFER_INC_RES)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
283 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
284 src->buffer_fraction -= BUFFER_INC_RES;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
285 interp_sample(src, src->last_left, value);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
286
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
287 if (((src->buffer_pos - base) & src->mask) >= sync_samples) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
288 render_do_audio_ready(src);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
289 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
290 src->buffer_pos &= src->mask;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
291 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
292 src->last_left = value;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
293 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
294
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
295 void render_put_stereo_sample(audio_source *src, int16_t left, int16_t right)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
296 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
297 left = lowpass_sample(src, src->last_left, left);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
298 right = lowpass_sample(src, src->last_right, right);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
299 src->buffer_fraction += src->buffer_inc;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
300 uint32_t base = render_is_audio_sync() ? 0 : src->read_end;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
301 while (src->buffer_fraction > BUFFER_INC_RES)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
302 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
303 src->buffer_fraction -= BUFFER_INC_RES;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
304
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
305 interp_sample(src, src->last_left, left);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
306 interp_sample(src, src->last_right, right);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
307
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
308 if (((src->buffer_pos - base) & src->mask)/2 >= sync_samples) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
309 render_do_audio_ready(src);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
310 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
311 src->buffer_pos &= src->mask;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
312 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
313 src->last_left = left;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
314 src->last_right = right;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
315 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
316
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
317 static void update_source(audio_source *src, double rc, uint8_t sync_changed)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
318 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
319 double alpha = src->dt / (src->dt + rc);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
320 int32_t lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
321 src->lowpass_alpha = lowpass_alpha;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
322 if (sync_changed) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
323 uint32_t alloc_size = render_is_audio_sync() ? src->num_channels * buffer_samples : nearest_pow2(render_min_buffered() * 4 * src->num_channels);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
324 src->back = realloc(src->back, alloc_size * sizeof(int16_t));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
325 if (render_is_audio_sync()) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
326 src->front = malloc(alloc_size * sizeof(int16_t));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
327 } else {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
328 free(src->front);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
329 src->front = src->back;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
330 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
331 src->mask = render_is_audio_sync() ? 0xFFFFFFFF : alloc_size-1;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
332 src->read_start = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
333 src->read_end = render_is_audio_sync() ? buffer_samples * src->num_channels : 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
334 src->buffer_pos = 0;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
335 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
336 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
337
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
338 uint8_t old_audio_sync;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
339 void render_audio_initialized(render_audio_format format, uint32_t rate, uint8_t channels, uint32_t buffer_size, int sample_size_in)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
340 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
341 sample_rate = rate;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
342 output_channels = channels;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
343 buffer_samples = buffer_size;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
344 sample_size = sample_size_in;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
345 if (mix_buf) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
346 free(mix_buf);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
347 mix_buf = NULL;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
348 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
349 switch(format)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
350 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
351 case RENDER_AUDIO_S16:
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
352 convert = convert_s16;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
353 mix_buf = calloc(output_channels * buffer_samples, sizeof(float));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
354 break;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
355 case RENDER_AUDIO_FLOAT:
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
356 convert = clamp_f32;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
357 break;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
358 case RENDER_AUDIO_UNKNOWN:
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
359 convert = convert_null;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
360 mix_buf = calloc(output_channels * buffer_samples, sizeof(float));
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
361 break;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
362 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
363 uint32_t syncs = render_audio_syncs_per_sec();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
364 if (syncs) {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
365 sync_samples = rate / syncs;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
366 } else {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
367 sync_samples = buffer_samples;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
368 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
369 char * gain_str = tern_find_path(config, "audio\0gain\0", TVAL_PTR).ptrval;
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
370 overall_gain_mult = db_to_mult(gain_str ? atof(gain_str) : 0.0f);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
371 uint8_t sync_changed = old_audio_sync != render_is_audio_sync();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
372 old_audio_sync = render_is_audio_sync();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
373 double lowpass_cutoff = get_lowpass_cutoff(config);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
374 double rc = (1.0 / lowpass_cutoff) / (2.0 * M_PI);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
375 render_lock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
376 for (uint8_t i = 0; i < num_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
377 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
378 update_source(audio_sources[i], rc, sync_changed);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
379 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
380 render_unlock_audio();
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
381 for (uint8_t i = 0; i < num_inactive_audio_sources; i++)
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
382 {
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
383 update_source(inactive_audio_sources[i], rc, sync_changed);
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
384 }
4c322abd9fa5 Split generic part of audio code into a separate file so it can be used in other targets besides SDL
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
385 }