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