1 /* Copyright (C) 2010-2018 The RetroArch team
2 *
3 * ---------------------------------------------------------------------------------------
4 * The following license statement only applies to this file (audio_mixer.c).
5 * ---------------------------------------------------------------------------------------
6 *
7 * Permission is hereby granted, free of charge,
8 * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <audio/audio_mixer.h>
24 #include <audio/audio_resampler.h>
25
26 #include <formats/rwav.h>
27 #include <memalign.h>
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33
34 #ifdef HAVE_CONFIG_H
35 #include "../../config.h"
36 #endif
37
38 #ifdef HAVE_STB_VORBIS
39 #define STB_VORBIS_NO_PUSHDATA_API
40 #define STB_VORBIS_NO_STDIO
41 #define STB_VORBIS_NO_CRT
42
43 #include <stb/stb_vorbis.h>
44 #endif
45
46 #ifdef HAVE_DR_FLAC
47 #define DR_FLAC_IMPLEMENTATION
48 #include <dr/dr_flac.h>
49 #endif
50
51 #ifdef HAVE_DR_MP3
52 #define DR_MP3_IMPLEMENTATION
53 #include <retro_assert.h>
54 #define DRMP3_ASSERT(expression) retro_assert(expression)
55 #include <dr/dr_mp3.h>
56 #endif
57
58 #ifdef HAVE_IBXM
59 #include <ibxm/ibxm.h>
60 #endif
61
62 #define AUDIO_MIXER_MAX_VOICES 8
63 #define AUDIO_MIXER_TEMP_BUFFER 8192
64
65 struct audio_mixer_sound
66 {
67 enum audio_mixer_type type;
68
69 union
70 {
71 struct
72 {
73 /* wav */
74 unsigned frames;
75 const float* pcm;
76 } wav;
77
78 #ifdef HAVE_STB_VORBIS
79 struct
80 {
81 /* ogg */
82 unsigned size;
83 const void* data;
84 } ogg;
85 #endif
86
87 #ifdef HAVE_DR_FLAC
88 struct
89 {
90 /* flac */
91 unsigned size;
92 const void* data;
93 } flac;
94 #endif
95
96 #ifdef HAVE_DR_MP3
97 struct
98 {
99 /* mp */
100 unsigned size;
101 const void* data;
102 } mp3;
103 #endif
104
105 #ifdef HAVE_IBXM
106 struct
107 {
108 /* mod/s3m/xm */
109 unsigned size;
110 const void* data;
111 } mod;
112 #endif
113 } types;
114 };
115
116 struct audio_mixer_voice
117 {
118 bool repeat;
119 unsigned type;
120 float volume;
121 audio_mixer_sound_t *sound;
122 audio_mixer_stop_cb_t stop_cb;
123
124 union
125 {
126 struct
127 {
128 unsigned position;
129 } wav;
130
131 #ifdef HAVE_STB_VORBIS
132 struct
133 {
134 unsigned position;
135 unsigned samples;
136 unsigned buf_samples;
137 float* buffer;
138 float ratio;
139 stb_vorbis *stream;
140 void *resampler_data;
141 const retro_resampler_t *resampler;
142 } ogg;
143 #endif
144
145 #ifdef HAVE_DR_FLAC
146 struct
147 {
148 unsigned position;
149 unsigned samples;
150 unsigned buf_samples;
151 float* buffer;
152 float ratio;
153 drflac *stream;
154 void *resampler_data;
155 const retro_resampler_t *resampler;
156 } flac;
157 #endif
158
159 #ifdef HAVE_DR_MP3
160 struct
161 {
162 unsigned position;
163 unsigned samples;
164 unsigned buf_samples;
165 float* buffer;
166 float ratio;
167 drmp3 stream;
168 void *resampler_data;
169 const retro_resampler_t *resampler;
170 } mp3;
171 #endif
172
173 #ifdef HAVE_IBXM
174 struct
175 {
176 unsigned position;
177 unsigned samples;
178 unsigned buf_samples;
179 int* buffer;
180 struct replay* stream;
181 struct module* module;
182 } mod;
183 #endif
184 } types;
185 };
186
187 static struct audio_mixer_voice s_voices[AUDIO_MIXER_MAX_VOICES] = {{0}};
188 static unsigned s_rate = 0;
189
wav2float(const rwav_t * wav,float ** pcm,size_t samples_out)190 static bool wav2float(const rwav_t* wav, float** pcm, size_t samples_out)
191 {
192 size_t i;
193 /* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes */
194 float *f = (float*)memalign_alloc(16,
195 ((samples_out + 15) & ~15) * sizeof(float));
196
197 if (!f)
198 return false;
199
200 *pcm = f;
201
202 if (wav->bitspersample == 8)
203 {
204 float sample = 0.0f;
205 const uint8_t *u8 = (const uint8_t*)wav->samples;
206
207 if (wav->numchannels == 1)
208 {
209 for (i = wav->numsamples; i != 0; i--)
210 {
211 sample = (float)*u8++ / 255.0f;
212 sample = sample * 2.0f - 1.0f;
213 *f++ = sample;
214 *f++ = sample;
215 }
216 }
217 else if (wav->numchannels == 2)
218 {
219 for (i = wav->numsamples; i != 0; i--)
220 {
221 sample = (float)*u8++ / 255.0f;
222 sample = sample * 2.0f - 1.0f;
223 *f++ = sample;
224 sample = (float)*u8++ / 255.0f;
225 sample = sample * 2.0f - 1.0f;
226 *f++ = sample;
227 }
228 }
229 }
230 else
231 {
232 /* TODO/FIXME note to leiradel - can we use audio/conversion/s16_to_float
233 * functions here? */
234
235 float sample = 0.0f;
236 const int16_t *s16 = (const int16_t*)wav->samples;
237
238 if (wav->numchannels == 1)
239 {
240 for (i = wav->numsamples; i != 0; i--)
241 {
242 sample = (float)((int)*s16++ + 32768) / 65535.0f;
243 sample = sample * 2.0f - 1.0f;
244 *f++ = sample;
245 *f++ = sample;
246 }
247 }
248 else if (wav->numchannels == 2)
249 {
250 for (i = wav->numsamples; i != 0; i--)
251 {
252 sample = (float)((int)*s16++ + 32768) / 65535.0f;
253 sample = sample * 2.0f - 1.0f;
254 *f++ = sample;
255 sample = (float)((int)*s16++ + 32768) / 65535.0f;
256 sample = sample * 2.0f - 1.0f;
257 *f++ = sample;
258 }
259 }
260 }
261
262 return true;
263 }
264
one_shot_resample(const float * in,size_t samples_in,unsigned rate,float ** out,size_t * samples_out)265 static bool one_shot_resample(const float* in, size_t samples_in,
266 unsigned rate, float** out, size_t* samples_out)
267 {
268 struct resampler_data info;
269 void* data = NULL;
270 const retro_resampler_t* resampler = NULL;
271 float ratio = (double)s_rate / (double)rate;
272
273 if (!retro_resampler_realloc(&data, &resampler, NULL,
274 RESAMPLER_QUALITY_DONTCARE, ratio))
275 return false;
276
277 /*
278 * Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
279 * add four more samples in the formula below just as safeguard, because
280 * resampler->process sometimes reports more output samples than the
281 * formula below calculates. Ideally, audio resamplers should have a
282 * function to return the number of samples they will output given a
283 * count of input samples.
284 */
285 *samples_out = samples_in * ratio + 4;
286 *out = (float*)memalign_alloc(16,
287 ((*samples_out + 15) & ~15) * sizeof(float));
288
289 if (*out == NULL)
290 return false;
291
292 info.data_in = in;
293 info.data_out = *out;
294 info.input_frames = samples_in / 2;
295 info.output_frames = 0;
296 info.ratio = ratio;
297
298 resampler->process(data, &info);
299 resampler->free(data);
300 return true;
301 }
302
audio_mixer_init(unsigned rate)303 void audio_mixer_init(unsigned rate)
304 {
305 unsigned i;
306
307 s_rate = rate;
308
309 for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
310 s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
311 }
312
audio_mixer_done(void)313 void audio_mixer_done(void)
314 {
315 unsigned i;
316
317 for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
318 s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
319 }
320
audio_mixer_load_wav(void * buffer,int32_t size)321 audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
322 {
323 /* WAV data */
324 rwav_t wav;
325 /* WAV samples converted to float */
326 float* pcm = NULL;
327 size_t samples = 0;
328 /* Result */
329 audio_mixer_sound_t* sound = NULL;
330 enum rwav_state rwav_ret = rwav_load(&wav, buffer, size);
331
332 if (rwav_ret != RWAV_ITERATE_DONE)
333 return NULL;
334
335 samples = wav.numsamples * 2;
336
337 if (!wav2float(&wav, &pcm, samples))
338 return NULL;
339
340 if (wav.samplerate != s_rate)
341 {
342 float* resampled = NULL;
343
344 if (!one_shot_resample(pcm, samples,
345 wav.samplerate, &resampled, &samples))
346 return NULL;
347
348 memalign_free((void*)pcm);
349 pcm = resampled;
350 }
351
352 sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
353
354 if (!sound)
355 {
356 memalign_free((void*)pcm);
357 return NULL;
358 }
359
360 sound->type = AUDIO_MIXER_TYPE_WAV;
361 sound->types.wav.frames = (unsigned)(samples / 2);
362 sound->types.wav.pcm = pcm;
363
364 rwav_free(&wav);
365
366 return sound;
367 }
368
audio_mixer_load_ogg(void * buffer,int32_t size)369 audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size)
370 {
371 #ifdef HAVE_STB_VORBIS
372 audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
373
374 if (!sound)
375 return NULL;
376
377 sound->type = AUDIO_MIXER_TYPE_OGG;
378 sound->types.ogg.size = size;
379 sound->types.ogg.data = buffer;
380
381 return sound;
382 #else
383 return NULL;
384 #endif
385 }
386
audio_mixer_load_flac(void * buffer,int32_t size)387 audio_mixer_sound_t* audio_mixer_load_flac(void *buffer, int32_t size)
388 {
389 #ifdef HAVE_DR_FLAC
390 audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
391
392 if (!sound)
393 return NULL;
394
395 sound->type = AUDIO_MIXER_TYPE_FLAC;
396 sound->types.flac.size = size;
397 sound->types.flac.data = buffer;
398
399 return sound;
400 #else
401 return NULL;
402 #endif
403 }
404
audio_mixer_load_mp3(void * buffer,int32_t size)405 audio_mixer_sound_t* audio_mixer_load_mp3(void *buffer, int32_t size)
406 {
407 #ifdef HAVE_DR_MP3
408 audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
409
410 if (!sound)
411 return NULL;
412
413 sound->type = AUDIO_MIXER_TYPE_MP3;
414 sound->types.mp3.size = size;
415 sound->types.mp3.data = buffer;
416
417 return sound;
418 #else
419 return NULL;
420 #endif
421 }
422
audio_mixer_load_mod(void * buffer,int32_t size)423 audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size)
424 {
425 #ifdef HAVE_IBXM
426 audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
427
428 if (!sound)
429 return NULL;
430
431 sound->type = AUDIO_MIXER_TYPE_MOD;
432 sound->types.mod.size = size;
433 sound->types.mod.data = buffer;
434
435 return sound;
436 #else
437 return NULL;
438 #endif
439 }
440
audio_mixer_destroy(audio_mixer_sound_t * sound)441 void audio_mixer_destroy(audio_mixer_sound_t* sound)
442 {
443 void *handle = NULL;
444 if (!sound)
445 return;
446
447 switch (sound->type)
448 {
449 case AUDIO_MIXER_TYPE_WAV:
450 handle = (void*)sound->types.wav.pcm;
451 if (handle)
452 memalign_free(handle);
453 break;
454 case AUDIO_MIXER_TYPE_OGG:
455 #ifdef HAVE_STB_VORBIS
456 handle = (void*)sound->types.ogg.data;
457 if (handle)
458 free(handle);
459 #endif
460 break;
461 case AUDIO_MIXER_TYPE_MOD:
462 #ifdef HAVE_IBXM
463 handle = (void*)sound->types.mod.data;
464 if (handle)
465 free(handle);
466 #endif
467 break;
468 case AUDIO_MIXER_TYPE_FLAC:
469 #ifdef HAVE_DR_FLAC
470 handle = (void*)sound->types.flac.data;
471 if (handle)
472 free(handle);
473 #endif
474 break;
475 case AUDIO_MIXER_TYPE_MP3:
476 #ifdef HAVE_DR_MP3
477 handle = (void*)sound->types.mp3.data;
478 if (handle)
479 free(handle);
480 #endif
481 break;
482 case AUDIO_MIXER_TYPE_NONE:
483 break;
484 }
485
486 free(sound);
487 }
488
audio_mixer_play_wav(audio_mixer_sound_t * sound,audio_mixer_voice_t * voice,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)489 static bool audio_mixer_play_wav(audio_mixer_sound_t* sound,
490 audio_mixer_voice_t* voice, bool repeat, float volume,
491 audio_mixer_stop_cb_t stop_cb)
492 {
493 voice->types.wav.position = 0;
494 return true;
495 }
496
497 #ifdef HAVE_STB_VORBIS
audio_mixer_play_ogg(audio_mixer_sound_t * sound,audio_mixer_voice_t * voice,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)498 static bool audio_mixer_play_ogg(
499 audio_mixer_sound_t* sound,
500 audio_mixer_voice_t* voice,
501 bool repeat, float volume,
502 audio_mixer_stop_cb_t stop_cb)
503 {
504 stb_vorbis_info info;
505 int res = 0;
506 float ratio = 1.0f;
507 unsigned samples = 0;
508 void *ogg_buffer = NULL;
509 void *resampler_data = NULL;
510 const retro_resampler_t* resamp = NULL;
511 stb_vorbis *stb_vorbis = stb_vorbis_open_memory(
512 (const unsigned char*)sound->types.ogg.data,
513 sound->types.ogg.size, &res, NULL);
514
515 if (!stb_vorbis)
516 return false;
517
518 info = stb_vorbis_get_info(stb_vorbis);
519
520 if (info.sample_rate != s_rate)
521 {
522 ratio = (double)s_rate / (double)info.sample_rate;
523
524 if (!retro_resampler_realloc(&resampler_data,
525 &resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
526 ratio))
527 goto error;
528 }
529
530 samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
531 ogg_buffer = (float*)memalign_alloc(16,
532 ((samples + 15) & ~15) * sizeof(float));
533
534 if (!ogg_buffer)
535 {
536 if (resamp && resampler_data)
537 resamp->free(resampler_data);
538 goto error;
539 }
540
541 /* "system" menu sounds may reuse the same voice without freeing anything first, so do that here if needed */
542 if (voice->types.ogg.stream)
543 stb_vorbis_close(voice->types.ogg.stream);
544 if (voice->types.ogg.resampler && voice->types.ogg.resampler_data)
545 voice->types.ogg.resampler->free(voice->types.ogg.resampler_data);
546 if (voice->types.ogg.buffer)
547 memalign_free(voice->types.ogg.buffer);
548
549 voice->types.ogg.resampler = resamp;
550 voice->types.ogg.resampler_data = resampler_data;
551 voice->types.ogg.buffer = (float*)ogg_buffer;
552 voice->types.ogg.buf_samples = samples;
553 voice->types.ogg.ratio = ratio;
554 voice->types.ogg.stream = stb_vorbis;
555 voice->types.ogg.position = 0;
556 voice->types.ogg.samples = 0;
557
558 return true;
559
560 error:
561 stb_vorbis_close(stb_vorbis);
562 return false;
563 }
564 #endif
565
566 #ifdef HAVE_IBXM
audio_mixer_play_mod(audio_mixer_sound_t * sound,audio_mixer_voice_t * voice,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)567 static bool audio_mixer_play_mod(
568 audio_mixer_sound_t* sound,
569 audio_mixer_voice_t* voice,
570 bool repeat, float volume,
571 audio_mixer_stop_cb_t stop_cb)
572 {
573 struct data data;
574 char message[64];
575 int buf_samples = 0;
576 int samples = 0;
577 void *mod_buffer = NULL;
578 struct module* module = NULL;
579 struct replay* replay = NULL;
580
581 data.buffer = (char*)sound->types.mod.data;
582 data.length = sound->types.mod.size;
583 module = module_load(&data, message);
584
585 if (!module)
586 {
587 printf("audio_mixer_play_mod module_load() failed with error: %s\n", message);
588 goto error;
589 }
590
591 if (voice->types.mod.module)
592 dispose_module(voice->types.mod.module);
593
594 voice->types.mod.module = module;
595
596 replay = new_replay(module, s_rate, 1);
597
598 if (!replay)
599 {
600 printf("audio_mixer_play_mod new_replay() failed\n");
601 goto error;
602 }
603
604 buf_samples = calculate_mix_buf_len(s_rate);
605 mod_buffer = memalign_alloc(16, ((buf_samples + 15) & ~15) * sizeof(int));
606
607 if (!mod_buffer)
608 {
609 printf("audio_mixer_play_mod cannot allocate mod_buffer !\n");
610 goto error;
611 }
612
613 samples = replay_calculate_duration(replay);
614
615 if (!samples)
616 {
617 printf("audio_mixer_play_mod cannot retrieve duration !\n");
618 goto error;
619 }
620
621 /* FIXME: stopping and then starting a mod stream will crash here in dispose_replay (ASAN says struct replay is misaligned?) */
622 if (voice->types.mod.stream)
623 dispose_replay(voice->types.mod.stream);
624 if (voice->types.mod.buffer)
625 memalign_free(voice->types.mod.buffer);
626
627 voice->types.mod.buffer = (int*)mod_buffer;
628 voice->types.mod.buf_samples = buf_samples;
629 voice->types.mod.stream = replay;
630 voice->types.mod.position = 0;
631 voice->types.mod.samples = 0; /* samples; */
632
633 return true;
634
635 error:
636 if (mod_buffer)
637 memalign_free(mod_buffer);
638 if (module)
639 dispose_module(module);
640 return false;
641
642 }
643 #endif
644
645 #ifdef HAVE_DR_FLAC
audio_mixer_play_flac(audio_mixer_sound_t * sound,audio_mixer_voice_t * voice,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)646 static bool audio_mixer_play_flac(
647 audio_mixer_sound_t* sound,
648 audio_mixer_voice_t* voice,
649 bool repeat, float volume,
650 audio_mixer_stop_cb_t stop_cb)
651 {
652 float ratio = 1.0f;
653 unsigned samples = 0;
654 void *flac_buffer = NULL;
655 void *resampler_data = NULL;
656 const retro_resampler_t* resamp = NULL;
657 drflac *dr_flac = drflac_open_memory((const unsigned char*)sound->types.flac.data,sound->types.flac.size);
658
659 if (!dr_flac)
660 return false;
661 if (dr_flac->sampleRate != s_rate)
662 {
663 ratio = (double)s_rate / (double)(dr_flac->sampleRate);
664
665 if (!retro_resampler_realloc(&resampler_data,
666 &resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
667 ratio))
668 goto error;
669 }
670
671 samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
672 flac_buffer = (float*)memalign_alloc(16,
673 ((samples + 15) & ~15) * sizeof(float));
674
675 if (!flac_buffer)
676 {
677 if (resamp && resamp->free)
678 resamp->free(resampler_data);
679 goto error;
680 }
681
682 if (voice->types.flac.stream)
683 drflac_close(voice->types.flac.stream);
684 if (voice->types.flac.resampler && voice->types.flac.resampler_data)
685 voice->types.flac.resampler->free(voice->types.flac.resampler_data);
686 if (voice->types.flac.buffer)
687 memalign_free(voice->types.flac.buffer);
688
689 voice->types.flac.resampler = resamp;
690 voice->types.flac.resampler_data = resampler_data;
691 voice->types.flac.buffer = (float*)flac_buffer;
692 voice->types.flac.buf_samples = samples;
693 voice->types.flac.ratio = ratio;
694 voice->types.flac.stream = dr_flac;
695 voice->types.flac.position = 0;
696 voice->types.flac.samples = 0;
697
698 return true;
699
700 error:
701 drflac_close(dr_flac);
702 return false;
703 }
704 #endif
705
706 #ifdef HAVE_DR_MP3
audio_mixer_play_mp3(audio_mixer_sound_t * sound,audio_mixer_voice_t * voice,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)707 static bool audio_mixer_play_mp3(
708 audio_mixer_sound_t* sound,
709 audio_mixer_voice_t* voice,
710 bool repeat, float volume,
711 audio_mixer_stop_cb_t stop_cb)
712 {
713 float ratio = 1.0f;
714 unsigned samples = 0;
715 void *mp3_buffer = NULL;
716 void *resampler_data = NULL;
717 const retro_resampler_t* resamp = NULL;
718 bool res;
719
720 if (voice->types.mp3.stream.pData)
721 {
722 drmp3_uninit(&voice->types.mp3.stream);
723 memset(&voice->types.mp3.stream, 0, sizeof(voice->types.mp3.stream));
724 }
725
726 res = drmp3_init_memory(&voice->types.mp3.stream, (const unsigned char*)sound->types.mp3.data, sound->types.mp3.size, NULL);
727
728 if (!res)
729 return false;
730
731 if (voice->types.mp3.stream.sampleRate != s_rate)
732 {
733 ratio = (double)s_rate / (double)(voice->types.mp3.stream.sampleRate);
734
735 if (!retro_resampler_realloc(&resampler_data,
736 &resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
737 ratio))
738 goto error;
739 }
740
741 samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
742 mp3_buffer = (float*)memalign_alloc(16,
743 ((samples + 15) & ~15) * sizeof(float));
744
745 if (!mp3_buffer)
746 {
747 if (resamp && resampler_data)
748 resamp->free(resampler_data);
749 goto error;
750 }
751
752 /* "system" menu sounds may reuse the same voice without freeing anything first, so do that here if needed */
753 if (voice->types.mp3.resampler && voice->types.mp3.resampler_data)
754 voice->types.mp3.resampler->free(voice->types.mp3.resampler_data);
755 if (voice->types.mp3.buffer)
756 memalign_free(voice->types.mp3.buffer);
757
758 voice->types.mp3.resampler = resamp;
759 voice->types.mp3.resampler_data = resampler_data;
760 voice->types.mp3.buffer = (float*)mp3_buffer;
761 voice->types.mp3.buf_samples = samples;
762 voice->types.mp3.ratio = ratio;
763 voice->types.mp3.position = 0;
764 voice->types.mp3.samples = 0;
765
766 return true;
767
768 error:
769 drmp3_uninit(&voice->types.mp3.stream);
770 return false;
771 }
772 #endif
773
audio_mixer_play(audio_mixer_sound_t * sound,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)774 audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
775 float volume, audio_mixer_stop_cb_t stop_cb)
776 {
777 unsigned i;
778 bool res = false;
779 audio_mixer_voice_t* voice = s_voices;
780
781 if (!sound)
782 return NULL;
783
784 for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
785 {
786 if (voice->type != AUDIO_MIXER_TYPE_NONE)
787 continue;
788
789 switch (sound->type)
790 {
791 case AUDIO_MIXER_TYPE_WAV:
792 res = audio_mixer_play_wav(sound, voice, repeat, volume, stop_cb);
793 break;
794 case AUDIO_MIXER_TYPE_OGG:
795 #ifdef HAVE_STB_VORBIS
796 res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
797 #endif
798 break;
799 case AUDIO_MIXER_TYPE_MOD:
800 #ifdef HAVE_IBXM
801 res = audio_mixer_play_mod(sound, voice, repeat, volume, stop_cb);
802 #endif
803 break;
804 case AUDIO_MIXER_TYPE_FLAC:
805 #ifdef HAVE_DR_FLAC
806 res = audio_mixer_play_flac(sound, voice, repeat, volume, stop_cb);
807 #endif
808 break;
809 case AUDIO_MIXER_TYPE_MP3:
810 #ifdef HAVE_DR_MP3
811 res = audio_mixer_play_mp3(sound, voice, repeat, volume, stop_cb);
812 #endif
813 break;
814 case AUDIO_MIXER_TYPE_NONE:
815 break;
816 }
817
818 break;
819 }
820
821 if (res)
822 {
823 voice->type = sound->type;
824 voice->repeat = repeat;
825 voice->volume = volume;
826 voice->sound = sound;
827 voice->stop_cb = stop_cb;
828 }
829 else
830 voice = NULL;
831
832 return voice;
833 }
834
audio_mixer_stop(audio_mixer_voice_t * voice)835 void audio_mixer_stop(audio_mixer_voice_t* voice)
836 {
837 audio_mixer_stop_cb_t stop_cb = NULL;
838 audio_mixer_sound_t* sound = NULL;
839
840 if (voice)
841 {
842 stop_cb = voice->stop_cb;
843 sound = voice->sound;
844
845 voice->type = AUDIO_MIXER_TYPE_NONE;
846
847 if (stop_cb)
848 stop_cb(sound, AUDIO_MIXER_SOUND_STOPPED);
849 }
850 }
851
audio_mixer_mix_wav(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)852 static void audio_mixer_mix_wav(float* buffer, size_t num_frames,
853 audio_mixer_voice_t* voice,
854 float volume)
855 {
856 int i;
857 unsigned buf_free = (unsigned)(num_frames * 2);
858 const audio_mixer_sound_t* sound = voice->sound;
859 unsigned pcm_available = sound->types.wav.frames
860 * 2 - voice->types.wav.position;
861 const float* pcm = sound->types.wav.pcm +
862 voice->types.wav.position;
863
864 again:
865 if (pcm_available < buf_free)
866 {
867 for (i = pcm_available; i != 0; i--)
868 *buffer++ += *pcm++ * volume;
869
870 if (voice->repeat)
871 {
872 if (voice->stop_cb)
873 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
874
875 buf_free -= pcm_available;
876 pcm_available = sound->types.wav.frames * 2;
877 pcm = sound->types.wav.pcm;
878 voice->types.wav.position = 0;
879 goto again;
880 }
881
882 if (voice->stop_cb)
883 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
884
885 voice->type = AUDIO_MIXER_TYPE_NONE;
886 }
887 else
888 {
889 for (i = buf_free; i != 0; i--)
890 *buffer++ += *pcm++ * volume;
891
892 voice->types.wav.position += buf_free;
893 }
894 }
895
896 #ifdef HAVE_STB_VORBIS
audio_mixer_mix_ogg(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)897 static void audio_mixer_mix_ogg(float* buffer, size_t num_frames,
898 audio_mixer_voice_t* voice,
899 float volume)
900 {
901 int i;
902 struct resampler_data info = { 0 };
903 float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 };
904 unsigned buf_free = (unsigned)(num_frames * 2);
905 unsigned temp_samples = 0;
906 float* pcm = NULL;
907
908 if (voice->types.ogg.position == voice->types.ogg.samples)
909 {
910 again:
911 temp_samples = stb_vorbis_get_samples_float_interleaved(
912 voice->types.ogg.stream, 2, temp_buffer,
913 AUDIO_MIXER_TEMP_BUFFER) * 2;
914
915 if (temp_samples == 0)
916 {
917 if (voice->repeat)
918 {
919 if (voice->stop_cb)
920 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
921
922 stb_vorbis_seek_start(voice->types.ogg.stream);
923 goto again;
924 }
925 else
926 {
927 if (voice->stop_cb)
928 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
929
930 voice->type = AUDIO_MIXER_TYPE_NONE;
931 return;
932 }
933 }
934
935 info.data_in = temp_buffer;
936 info.data_out = voice->types.ogg.buffer;
937 info.input_frames = temp_samples / 2;
938 info.output_frames = 0;
939 info.ratio = voice->types.ogg.ratio;
940
941 if (voice->types.ogg.resampler)
942 {
943 voice->types.ogg.resampler->process(voice->types.ogg.resampler_data, &info);
944 }
945 else
946 memcpy(voice->types.ogg.buffer, temp_buffer, temp_samples * sizeof(float));
947 voice->types.ogg.position = 0;
948 voice->types.ogg.samples = voice->types.ogg.buf_samples;
949 }
950
951 pcm = voice->types.ogg.buffer + voice->types.ogg.position;
952
953 if (voice->types.ogg.samples < buf_free)
954 {
955 for (i = voice->types.ogg.samples; i != 0; i--)
956 *buffer++ += *pcm++ * volume;
957
958 buf_free -= voice->types.ogg.samples;
959 goto again;
960 }
961 else
962 {
963 int i;
964 for (i = buf_free; i != 0; --i )
965 *buffer++ += *pcm++ * volume;
966
967 voice->types.ogg.position += buf_free;
968 voice->types.ogg.samples -= buf_free;
969 }
970 }
971 #endif
972
973 #ifdef HAVE_IBXM
audio_mixer_mix_mod(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)974 static void audio_mixer_mix_mod(float* buffer, size_t num_frames,
975 audio_mixer_voice_t* voice,
976 float volume)
977 {
978 int i;
979 float samplef = 0.0f;
980 int samplei = 0;
981 unsigned temp_samples = 0;
982 unsigned buf_free = (unsigned)(num_frames * 2);
983 int* pcm = NULL;
984
985 if (voice->types.mod.position == voice->types.mod.samples)
986 {
987 again:
988 temp_samples = replay_get_audio(
989 voice->types.mod.stream, voice->types.mod.buffer );
990
991 temp_samples *= 2; /* stereo */
992
993 if (temp_samples == 0)
994 {
995 if (voice->repeat)
996 {
997 if (voice->stop_cb)
998 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
999
1000 replay_seek( voice->types.mod.stream, 0);
1001 goto again;
1002 }
1003 else
1004 {
1005 if (voice->stop_cb)
1006 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
1007
1008 voice->type = AUDIO_MIXER_TYPE_NONE;
1009 return;
1010 }
1011 }
1012
1013 voice->types.mod.position = 0;
1014 voice->types.mod.samples = temp_samples;
1015 }
1016 pcm = voice->types.mod.buffer + voice->types.mod.position;
1017
1018 if (voice->types.mod.samples < buf_free)
1019 {
1020 for (i = voice->types.mod.samples; i != 0; i--)
1021 {
1022 samplei = *pcm++ * volume;
1023 samplef = (float)((int)samplei + 32768) / 65535.0f;
1024 samplef = samplef * 2.0f - 1.0f;
1025 *buffer++ += samplef;
1026 }
1027
1028 buf_free -= voice->types.mod.samples;
1029 goto again;
1030 }
1031 else
1032 {
1033 int i;
1034 for (i = buf_free; i != 0; --i )
1035 {
1036 samplei = *pcm++ * volume;
1037 samplef = (float)((int)samplei + 32768) / 65535.0f;
1038 samplef = samplef * 2.0f - 1.0f;
1039 *buffer++ += samplef;
1040 }
1041
1042 voice->types.mod.position += buf_free;
1043 voice->types.mod.samples -= buf_free;
1044 }
1045 }
1046 #endif
1047
1048 #ifdef HAVE_DR_FLAC
audio_mixer_mix_flac(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)1049 static void audio_mixer_mix_flac(float* buffer, size_t num_frames,
1050 audio_mixer_voice_t* voice,
1051 float volume)
1052 {
1053 int i;
1054 struct resampler_data info = { 0 };
1055 float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 };
1056 unsigned buf_free = (unsigned)(num_frames * 2);
1057 unsigned temp_samples = 0;
1058 float* pcm = NULL;
1059
1060 if (voice->types.flac.position == voice->types.flac.samples)
1061 {
1062 again:
1063 temp_samples = (unsigned)drflac_read_f32( voice->types.flac.stream, AUDIO_MIXER_TEMP_BUFFER, temp_buffer);
1064 if (temp_samples == 0)
1065 {
1066 if (voice->repeat)
1067 {
1068 if (voice->stop_cb)
1069 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
1070
1071 drflac_seek_to_sample(voice->types.flac.stream,0);
1072 goto again;
1073 }
1074 else
1075 {
1076 if (voice->stop_cb)
1077 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
1078
1079 voice->type = AUDIO_MIXER_TYPE_NONE;
1080 return;
1081 }
1082 }
1083
1084 info.data_in = temp_buffer;
1085 info.data_out = voice->types.flac.buffer;
1086 info.input_frames = temp_samples / 2;
1087 info.output_frames = 0;
1088 info.ratio = voice->types.flac.ratio;
1089
1090 if (voice->types.flac.resampler)
1091 {
1092 voice->types.flac.resampler->process(voice->types.flac.resampler_data, &info);
1093 }
1094 else
1095 memcpy(voice->types.flac.buffer, temp_buffer, temp_samples * sizeof(float));
1096 voice->types.flac.position = 0;
1097 voice->types.flac.samples = voice->types.flac.buf_samples;
1098 }
1099
1100 pcm = voice->types.flac.buffer + voice->types.flac.position;
1101
1102 if (voice->types.flac.samples < buf_free)
1103 {
1104 for (i = voice->types.flac.samples; i != 0; i--)
1105 *buffer++ += *pcm++ * volume;
1106
1107 buf_free -= voice->types.flac.samples;
1108 goto again;
1109 }
1110 else
1111 {
1112 int i;
1113 for (i = buf_free; i != 0; --i )
1114 *buffer++ += *pcm++ * volume;
1115
1116 voice->types.flac.position += buf_free;
1117 voice->types.flac.samples -= buf_free;
1118 }
1119 }
1120 #endif
1121
1122 #ifdef HAVE_DR_MP3
audio_mixer_mix_mp3(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)1123 static void audio_mixer_mix_mp3(float* buffer, size_t num_frames,
1124 audio_mixer_voice_t* voice,
1125 float volume)
1126 {
1127 int i;
1128 struct resampler_data info = { 0 };
1129 float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 };
1130 unsigned buf_free = (unsigned)(num_frames * 2);
1131 unsigned temp_samples = 0;
1132 float* pcm = NULL;
1133
1134 if (voice->types.mp3.position == voice->types.mp3.samples)
1135 {
1136 again:
1137 temp_samples = (unsigned)drmp3_read_f32(&voice->types.mp3.stream, AUDIO_MIXER_TEMP_BUFFER/2, temp_buffer) * 2;
1138
1139 if (temp_samples == 0)
1140 {
1141 if (voice->repeat)
1142 {
1143 if (voice->stop_cb)
1144 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
1145
1146 drmp3_seek_to_frame(&voice->types.mp3.stream,0);
1147 goto again;
1148 }
1149 else
1150 {
1151 if (voice->stop_cb)
1152 voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
1153
1154 voice->type = AUDIO_MIXER_TYPE_NONE;
1155 return;
1156 }
1157 }
1158
1159 info.data_in = temp_buffer;
1160 info.data_out = voice->types.mp3.buffer;
1161 info.input_frames = temp_samples / 2;
1162 info.output_frames = 0;
1163 info.ratio = voice->types.mp3.ratio;
1164
1165 if (voice->types.mp3.resampler)
1166 voice->types.mp3.resampler->process(voice->types.mp3.resampler_data, &info);
1167 else
1168 memcpy(voice->types.mp3.buffer, temp_buffer, temp_samples * sizeof(float));
1169 voice->types.mp3.position = 0;
1170 voice->types.mp3.samples = voice->types.mp3.buf_samples;
1171 }
1172
1173 pcm = voice->types.mp3.buffer + voice->types.mp3.position;
1174
1175 if (voice->types.mp3.samples < buf_free)
1176 {
1177 for (i = voice->types.mp3.samples; i != 0; i--)
1178 *buffer++ += *pcm++ * volume;
1179
1180 buf_free -= voice->types.mp3.samples;
1181 goto again;
1182 }
1183 else
1184 {
1185 int i;
1186 for (i = buf_free; i != 0; --i )
1187 *buffer++ += *pcm++ * volume;
1188
1189 voice->types.mp3.position += buf_free;
1190 voice->types.mp3.samples -= buf_free;
1191 }
1192 }
1193 #endif
1194
audio_mixer_mix(float * buffer,size_t num_frames,float volume_override,bool override)1195 void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bool override)
1196 {
1197 unsigned i;
1198 size_t j = 0;
1199 float* sample = NULL;
1200 audio_mixer_voice_t* voice = s_voices;
1201
1202 for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
1203 {
1204 float volume = (override) ? volume_override : voice->volume;
1205
1206 switch (voice->type)
1207 {
1208 case AUDIO_MIXER_TYPE_WAV:
1209 audio_mixer_mix_wav(buffer, num_frames, voice, volume);
1210 break;
1211 case AUDIO_MIXER_TYPE_OGG:
1212 #ifdef HAVE_STB_VORBIS
1213 audio_mixer_mix_ogg(buffer, num_frames, voice, volume);
1214 #endif
1215 break;
1216 case AUDIO_MIXER_TYPE_MOD:
1217 #ifdef HAVE_IBXM
1218 audio_mixer_mix_mod(buffer, num_frames, voice, volume);
1219 #endif
1220 break;
1221 case AUDIO_MIXER_TYPE_FLAC:
1222 #ifdef HAVE_DR_FLAC
1223 audio_mixer_mix_flac(buffer, num_frames, voice, volume);
1224 #endif
1225 break;
1226 case AUDIO_MIXER_TYPE_MP3:
1227 #ifdef HAVE_DR_MP3
1228 audio_mixer_mix_mp3(buffer, num_frames, voice, volume);
1229 #endif
1230 break;
1231 case AUDIO_MIXER_TYPE_NONE:
1232 break;
1233 }
1234 }
1235
1236 for (j = 0, sample = buffer; j < num_frames; j++, sample++)
1237 {
1238 if (*sample < -1.0f)
1239 *sample = -1.0f;
1240 else if (*sample > 1.0f)
1241 *sample = 1.0f;
1242 }
1243 }
1244
audio_mixer_voice_get_volume(audio_mixer_voice_t * voice)1245 float audio_mixer_voice_get_volume(audio_mixer_voice_t *voice)
1246 {
1247 if (!voice)
1248 return 0.0f;
1249
1250 return voice->volume;
1251 }
1252
audio_mixer_voice_set_volume(audio_mixer_voice_t * voice,float val)1253 void audio_mixer_voice_set_volume(audio_mixer_voice_t *voice, float val)
1254 {
1255 if (!voice)
1256 return;
1257
1258 voice->volume = val;
1259 }
1260