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