comparison render_audio.c @ 2081:cfd53c94fffb

Initial stab at RF5C164 emulation
author Michael Pavone <pavone@retrodev.com>
date Thu, 03 Feb 2022 23:15:42 -0800
parents e4671a39d155
children 46ee354f29bd
comparison
equal deleted inserted replaced
2080:bafb757e1cd2 2081:cfd53c94fffb
137 137
138 #define BUFFER_INC_RES 0x40000000UL 138 #define BUFFER_INC_RES 0x40000000UL
139 139
140 void render_audio_adjust_clock(audio_source *src, uint64_t master_clock, uint64_t sample_divider) 140 void render_audio_adjust_clock(audio_source *src, uint64_t master_clock, uint64_t sample_divider)
141 { 141 {
142 src->buffer_inc = ((BUFFER_INC_RES * (uint64_t)sample_rate) / master_clock) * sample_divider; 142 src->buffer_inc = ((BUFFER_INC_RES * sample_divider * (uint64_t)sample_rate) / master_clock);
143 } 143 }
144 144
145 void render_audio_adjust_speed(float adjust_ratio) 145 void render_audio_adjust_speed(float adjust_ratio)
146 { 146 {
147 for (uint8_t i = 0; i < num_audio_sources; i++) 147 for (uint8_t i = 0; i < num_audio_sources; i++)
148 { 148 {
149 audio_sources[i]->buffer_inc = ((double)audio_sources[i]->buffer_inc) + ((double)audio_sources[i]->buffer_inc) * adjust_ratio + 0.5; 149 audio_sources[i]->buffer_inc = ((double)audio_sources[i]->buffer_inc) + ((double)audio_sources[i]->buffer_inc) * adjust_ratio + 0.5;
150 } 150 }
151 } 151 }
152 152
153 audio_source *render_audio_source(uint64_t master_clock, uint64_t sample_divider, uint8_t channels) 153 audio_source *render_audio_source(const char *name, uint64_t master_clock, uint64_t sample_divider, uint8_t channels)
154 { 154 {
155 audio_source *ret = NULL; 155 audio_source *ret = NULL;
156 uint32_t alloc_size = render_is_audio_sync() ? channels * buffer_samples : nearest_pow2(render_min_buffered() * 4 * channels); 156 uint32_t alloc_size = render_is_audio_sync() ? channels * buffer_samples : nearest_pow2(render_min_buffered() * 4 * channels);
157 render_lock_audio(); 157 render_lock_audio();
158 if (num_audio_sources < 8) { 158 if (num_audio_sources < 8) {
159 ret = calloc(1, sizeof(audio_source)); 159 ret = calloc(1, sizeof(audio_source));
160 ret->name = name;
160 ret->back = malloc(alloc_size * sizeof(int16_t)); 161 ret->back = malloc(alloc_size * sizeof(int16_t));
161 ret->front = render_is_audio_sync() ? malloc(alloc_size * sizeof(int16_t)) : ret->back; 162 ret->front = render_is_audio_sync() ? malloc(alloc_size * sizeof(int16_t)) : ret->back;
162 ret->front_populated = 0; 163 ret->front_populated = 0;
163 ret->opaque = render_new_audio_opaque(); 164 ret->opaque = render_new_audio_opaque();
164 ret->num_channels = channels; 165 ret->num_channels = channels;
181 ret->read_end = render_is_audio_sync() ? buffer_samples * channels : 0; 182 ret->read_end = render_is_audio_sync() ? buffer_samples * channels : 0;
182 ret->mask = render_is_audio_sync() ? 0xFFFFFFFF : alloc_size-1; 183 ret->mask = render_is_audio_sync() ? 0xFFFFFFFF : alloc_size-1;
183 ret->gain_mult = 1.0f; 184 ret->gain_mult = 1.0f;
184 } 185 }
185 render_audio_created(ret); 186 render_audio_created(ret);
186 187
187 return ret; 188 return ret;
188 } 189 }
189 190
190 191
191 static float db_to_mult(float gain) 192 static float db_to_mult(float gain)
209 found = 1; 210 found = 1;
210 remaining_sources = num_audio_sources; 211 remaining_sources = num_audio_sources;
211 break; 212 break;
212 } 213 }
213 } 214 }
214 215
215 render_unlock_audio(); 216 render_unlock_audio();
216 if (found) { 217 if (found) {
217 render_source_paused(src, remaining_sources); 218 render_source_paused(src, remaining_sources);
218 } 219 }
219 inactive_audio_sources[num_inactive_audio_sources++] = src; 220 inactive_audio_sources[num_inactive_audio_sources++] = src;
248 } 249 }
249 if (!found) { 250 if (!found) {
250 render_pause_source(src); 251 render_pause_source(src);
251 num_inactive_audio_sources--; 252 num_inactive_audio_sources--;
252 } 253 }
253 254
254 free(src->front); 255 free(src->front);
255 if (render_is_audio_sync()) { 256 if (render_is_audio_sync()) {
256 free(src->back); 257 free(src->back);
257 render_free_audio_opaque(src->opaque); 258 render_free_audio_opaque(src->opaque);
258 } 259 }
281 uint32_t base = render_is_audio_sync() ? 0 : src->read_end; 282 uint32_t base = render_is_audio_sync() ? 0 : src->read_end;
282 while (src->buffer_fraction > BUFFER_INC_RES) 283 while (src->buffer_fraction > BUFFER_INC_RES)
283 { 284 {
284 src->buffer_fraction -= BUFFER_INC_RES; 285 src->buffer_fraction -= BUFFER_INC_RES;
285 interp_sample(src, src->last_left, value); 286 interp_sample(src, src->last_left, value);
286 287
287 if (((src->buffer_pos - base) & src->mask) >= sync_samples) { 288 if (((src->buffer_pos - base) & src->mask) >= sync_samples) {
288 render_do_audio_ready(src); 289 render_do_audio_ready(src);
289 } 290 }
290 src->buffer_pos &= src->mask; 291 src->buffer_pos &= src->mask;
291 } 292 }
299 src->buffer_fraction += src->buffer_inc; 300 src->buffer_fraction += src->buffer_inc;
300 uint32_t base = render_is_audio_sync() ? 0 : src->read_end; 301 uint32_t base = render_is_audio_sync() ? 0 : src->read_end;
301 while (src->buffer_fraction > BUFFER_INC_RES) 302 while (src->buffer_fraction > BUFFER_INC_RES)
302 { 303 {
303 src->buffer_fraction -= BUFFER_INC_RES; 304 src->buffer_fraction -= BUFFER_INC_RES;
304 305
305 interp_sample(src, src->last_left, left); 306 interp_sample(src, src->last_left, left);
306 interp_sample(src, src->last_right, right); 307 interp_sample(src, src->last_right, right);
307 308
308 if (((src->buffer_pos - base) & src->mask)/2 >= sync_samples) { 309 if (((src->buffer_pos - base) & src->mask)/2 >= sync_samples) {
309 render_do_audio_ready(src); 310 render_do_audio_ready(src);
310 } 311 }
311 src->buffer_pos &= src->mask; 312 src->buffer_pos &= src->mask;
312 } 313 }