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    /* WAV samples converted to float */
332    float* pcm                 = NULL;
333    size_t samples             = 0;
334    /* Result */
335    audio_mixer_sound_t* sound = NULL;
336    enum rwav_state rwav_ret   = rwav_load(&wav, buffer, size);
337 
338    if (rwav_ret != RWAV_ITERATE_DONE)
339       return NULL;
340 
341    samples       = wav.numsamples * 2;
342 
343    if (!wav_to_float(&wav, &pcm, samples))
344       return NULL;
345 
346    if (wav.samplerate != s_rate)
347    {
348       float* resampled           = NULL;
349 
350       if (!one_shot_resample(pcm, samples,
351                wav.samplerate, &resampled, &samples))
352          return NULL;
353 
354       memalign_free((void*)pcm);
355       pcm = resampled;
356    }
357 
358    sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
359 
360    if (!sound)
361    {
362       memalign_free((void*)pcm);
363       return NULL;
364    }
365 
366    sound->type             = AUDIO_MIXER_TYPE_WAV;
367    sound->types.wav.frames = (unsigned)(samples / 2);
368    sound->types.wav.pcm    = pcm;
369 
370    rwav_free(&wav);
371 
372    return sound;
373 #else
374    return NULL;
375 #endif
376 }
377 
audio_mixer_load_ogg(void * buffer,int32_t size)378 audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size)
379 {
380 #ifdef HAVE_STB_VORBIS
381    audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
382 
383    if (!sound)
384       return NULL;
385 
386    sound->type           = AUDIO_MIXER_TYPE_OGG;
387    sound->types.ogg.size = size;
388    sound->types.ogg.data = buffer;
389 
390    return sound;
391 #else
392    return NULL;
393 #endif
394 }
395 
audio_mixer_load_flac(void * buffer,int32_t size)396 audio_mixer_sound_t* audio_mixer_load_flac(void *buffer, int32_t size)
397 {
398 #ifdef HAVE_DR_FLAC
399    audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
400 
401    if (!sound)
402       return NULL;
403 
404    sound->type           = AUDIO_MIXER_TYPE_FLAC;
405    sound->types.flac.size = size;
406    sound->types.flac.data = buffer;
407 
408    return sound;
409 #else
410    return NULL;
411 #endif
412 }
413 
audio_mixer_load_mp3(void * buffer,int32_t size)414 audio_mixer_sound_t* audio_mixer_load_mp3(void *buffer, int32_t size)
415 {
416 #ifdef HAVE_DR_MP3
417    audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
418 
419    if (!sound)
420       return NULL;
421 
422    sound->type           = AUDIO_MIXER_TYPE_MP3;
423    sound->types.mp3.size = size;
424    sound->types.mp3.data = buffer;
425 
426    return sound;
427 #else
428    return NULL;
429 #endif
430 }
431 
audio_mixer_load_mod(void * buffer,int32_t size)432 audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size)
433 {
434 #ifdef HAVE_IBXM
435    audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound));
436 
437    if (!sound)
438       return NULL;
439 
440    sound->type           = AUDIO_MIXER_TYPE_MOD;
441    sound->types.mod.size = size;
442    sound->types.mod.data = buffer;
443 
444    return sound;
445 #else
446    return NULL;
447 #endif
448 }
449 
audio_mixer_destroy(audio_mixer_sound_t * sound)450 void audio_mixer_destroy(audio_mixer_sound_t* sound)
451 {
452    void *handle = NULL;
453    if (!sound)
454       return;
455 
456    switch (sound->type)
457    {
458       case AUDIO_MIXER_TYPE_WAV:
459          handle = (void*)sound->types.wav.pcm;
460          if (handle)
461             memalign_free(handle);
462          break;
463       case AUDIO_MIXER_TYPE_OGG:
464 #ifdef HAVE_STB_VORBIS
465          handle = (void*)sound->types.ogg.data;
466          if (handle)
467             free(handle);
468 #endif
469          break;
470       case AUDIO_MIXER_TYPE_MOD:
471 #ifdef HAVE_IBXM
472          handle = (void*)sound->types.mod.data;
473          if (handle)
474             free(handle);
475 #endif
476          break;
477       case AUDIO_MIXER_TYPE_FLAC:
478 #ifdef HAVE_DR_FLAC
479          handle = (void*)sound->types.flac.data;
480          if (handle)
481             free(handle);
482 #endif
483          break;
484       case AUDIO_MIXER_TYPE_MP3:
485 #ifdef HAVE_DR_MP3
486          handle = (void*)sound->types.mp3.data;
487          if (handle)
488             free(handle);
489 #endif
490          break;
491       case AUDIO_MIXER_TYPE_NONE:
492          break;
493    }
494 
495    free(sound);
496 }
497 
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)498 static bool audio_mixer_play_wav(audio_mixer_sound_t* sound,
499       audio_mixer_voice_t* voice, bool repeat, float volume,
500       audio_mixer_stop_cb_t stop_cb)
501 {
502    voice->types.wav.position = 0;
503    return true;
504 }
505 
506 #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)507 static bool audio_mixer_play_ogg(
508       audio_mixer_sound_t* sound,
509       audio_mixer_voice_t* voice,
510       bool repeat, float volume,
511       audio_mixer_stop_cb_t stop_cb)
512 {
513    stb_vorbis_info info;
514    int res                         = 0;
515    float ratio                     = 1.0f;
516    unsigned samples                = 0;
517    void *ogg_buffer                = NULL;
518    void *resampler_data            = NULL;
519    const retro_resampler_t* resamp = NULL;
520    stb_vorbis *stb_vorbis          = stb_vorbis_open_memory(
521          (const unsigned char*)sound->types.ogg.data,
522          sound->types.ogg.size, &res, NULL);
523 
524    if (!stb_vorbis)
525       return false;
526 
527    info                    = stb_vorbis_get_info(stb_vorbis);
528 
529    if (info.sample_rate != s_rate)
530    {
531       ratio = (double)s_rate / (double)info.sample_rate;
532 
533       if (!retro_resampler_realloc(&resampler_data,
534                &resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
535                ratio))
536          goto error;
537    }
538 
539    samples                         = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
540    ogg_buffer                      = (float*)memalign_alloc(16,
541          ((samples + 15) & ~15) * sizeof(float));
542 
543    if (!ogg_buffer)
544    {
545       if (resamp && resampler_data)
546          resamp->free(resampler_data);
547       goto error;
548    }
549 
550    /* "system" menu sounds may reuse the same voice without freeing anything first, so do that here if needed */
551    if (voice->types.ogg.stream)
552       stb_vorbis_close(voice->types.ogg.stream);
553    if (voice->types.ogg.resampler && voice->types.ogg.resampler_data)
554       voice->types.ogg.resampler->free(voice->types.ogg.resampler_data);
555    if (voice->types.ogg.buffer)
556       memalign_free(voice->types.ogg.buffer);
557 
558    voice->types.ogg.resampler      = resamp;
559    voice->types.ogg.resampler_data = resampler_data;
560    voice->types.ogg.buffer         = (float*)ogg_buffer;
561    voice->types.ogg.buf_samples    = samples;
562    voice->types.ogg.ratio          = ratio;
563    voice->types.ogg.stream         = stb_vorbis;
564    voice->types.ogg.position       = 0;
565    voice->types.ogg.samples        = 0;
566 
567    return true;
568 
569 error:
570    stb_vorbis_close(stb_vorbis);
571    return false;
572 }
573 #endif
574 
575 #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)576 static bool audio_mixer_play_mod(
577       audio_mixer_sound_t* sound,
578       audio_mixer_voice_t* voice,
579       bool repeat, float volume,
580       audio_mixer_stop_cb_t stop_cb)
581 {
582    struct data data;
583    char message[64];
584    int buf_samples               = 0;
585    int samples                   = 0;
586    void *mod_buffer              = NULL;
587    struct module* module         = NULL;
588    struct replay* replay         = NULL;
589 
590    data.buffer                   = (char*)sound->types.mod.data;
591    data.length                   = sound->types.mod.size;
592    module                        = module_load(&data, message);
593 
594    if (!module)
595    {
596       printf("audio_mixer_play_mod module_load() failed with error: %s\n", message);
597       goto error;
598    }
599 
600    if (voice->types.mod.module)
601       dispose_module(voice->types.mod.module);
602 
603    voice->types.mod.module = module;
604 
605    replay = new_replay(module, s_rate, 1);
606 
607    if (!replay)
608    {
609       printf("audio_mixer_play_mod new_replay() failed\n");
610       goto error;
611    }
612 
613    buf_samples = calculate_mix_buf_len(s_rate);
614    mod_buffer  = memalign_alloc(16, ((buf_samples + 15) & ~15) * sizeof(int));
615 
616    if (!mod_buffer)
617    {
618       printf("audio_mixer_play_mod cannot allocate mod_buffer !\n");
619       goto error;
620    }
621 
622    samples = replay_calculate_duration(replay);
623 
624    if (!samples)
625    {
626       printf("audio_mixer_play_mod cannot retrieve duration !\n");
627       goto error;
628    }
629 
630    /* FIXME: stopping and then starting a mod stream will crash here in dispose_replay (ASAN says struct replay is misaligned?) */
631    if (voice->types.mod.stream)
632       dispose_replay(voice->types.mod.stream);
633    if (voice->types.mod.buffer)
634       memalign_free(voice->types.mod.buffer);
635 
636    voice->types.mod.buffer         = (int*)mod_buffer;
637    voice->types.mod.buf_samples    = buf_samples;
638    voice->types.mod.stream         = replay;
639    voice->types.mod.position       = 0;
640    voice->types.mod.samples        = 0; /* samples; */
641 
642    return true;
643 
644 error:
645    if (mod_buffer)
646       memalign_free(mod_buffer);
647    if (module)
648       dispose_module(module);
649    return false;
650 
651 }
652 #endif
653 
654 #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)655 static bool audio_mixer_play_flac(
656       audio_mixer_sound_t* sound,
657       audio_mixer_voice_t* voice,
658       bool repeat, float volume,
659       audio_mixer_stop_cb_t stop_cb)
660 {
661    float ratio                     = 1.0f;
662    unsigned samples                = 0;
663    void *flac_buffer                = NULL;
664    void *resampler_data            = NULL;
665    const retro_resampler_t* resamp = NULL;
666    drflac *dr_flac          = drflac_open_memory((const unsigned char*)sound->types.flac.data,sound->types.flac.size);
667 
668    if (!dr_flac)
669       return false;
670    if (dr_flac->sampleRate != s_rate)
671    {
672       ratio = (double)s_rate / (double)(dr_flac->sampleRate);
673 
674       if (!retro_resampler_realloc(&resampler_data,
675                &resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
676                ratio))
677          goto error;
678    }
679 
680    samples                         = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
681    flac_buffer                      = (float*)memalign_alloc(16,
682          ((samples + 15) & ~15) * sizeof(float));
683 
684    if (!flac_buffer)
685    {
686       if (resamp && resamp->free)
687          resamp->free(resampler_data);
688       goto error;
689    }
690 
691    if (voice->types.flac.stream)
692       drflac_close(voice->types.flac.stream);
693    if (voice->types.flac.resampler && voice->types.flac.resampler_data)
694       voice->types.flac.resampler->free(voice->types.flac.resampler_data);
695    if (voice->types.flac.buffer)
696       memalign_free(voice->types.flac.buffer);
697 
698    voice->types.flac.resampler      = resamp;
699    voice->types.flac.resampler_data = resampler_data;
700    voice->types.flac.buffer         = (float*)flac_buffer;
701    voice->types.flac.buf_samples    = samples;
702    voice->types.flac.ratio          = ratio;
703    voice->types.flac.stream         = dr_flac;
704    voice->types.flac.position       = 0;
705    voice->types.flac.samples        = 0;
706 
707    return true;
708 
709 error:
710    drflac_close(dr_flac);
711    return false;
712 }
713 #endif
714 
715 #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)716 static bool audio_mixer_play_mp3(
717       audio_mixer_sound_t* sound,
718       audio_mixer_voice_t* voice,
719       bool repeat, float volume,
720       audio_mixer_stop_cb_t stop_cb)
721 {
722    float ratio                     = 1.0f;
723    unsigned samples                = 0;
724    void *mp3_buffer                = NULL;
725    void *resampler_data            = NULL;
726    const retro_resampler_t* resamp = NULL;
727    bool res;
728 
729    if (voice->types.mp3.stream.pData)
730    {
731       drmp3_uninit(&voice->types.mp3.stream);
732       memset(&voice->types.mp3.stream, 0, sizeof(voice->types.mp3.stream));
733    }
734 
735    res = drmp3_init_memory(&voice->types.mp3.stream, (const unsigned char*)sound->types.mp3.data, sound->types.mp3.size, NULL);
736 
737    if (!res)
738       return false;
739 
740    if (voice->types.mp3.stream.sampleRate != s_rate)
741    {
742       ratio = (double)s_rate / (double)(voice->types.mp3.stream.sampleRate);
743 
744       if (!retro_resampler_realloc(&resampler_data,
745                &resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
746                ratio))
747          goto error;
748    }
749 
750    samples                         = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
751    mp3_buffer                      = (float*)memalign_alloc(16,
752          ((samples + 15) & ~15) * sizeof(float));
753 
754    if (!mp3_buffer)
755    {
756       if (resamp && resampler_data)
757          resamp->free(resampler_data);
758       goto error;
759    }
760 
761    /* "system" menu sounds may reuse the same voice without freeing anything first, so do that here if needed */
762    if (voice->types.mp3.resampler && voice->types.mp3.resampler_data)
763       voice->types.mp3.resampler->free(voice->types.mp3.resampler_data);
764    if (voice->types.mp3.buffer)
765       memalign_free(voice->types.mp3.buffer);
766 
767    voice->types.mp3.resampler      = resamp;
768    voice->types.mp3.resampler_data = resampler_data;
769    voice->types.mp3.buffer         = (float*)mp3_buffer;
770    voice->types.mp3.buf_samples    = samples;
771    voice->types.mp3.ratio          = ratio;
772    voice->types.mp3.position       = 0;
773    voice->types.mp3.samples        = 0;
774 
775    return true;
776 
777 error:
778    drmp3_uninit(&voice->types.mp3.stream);
779    return false;
780 }
781 #endif
782 
audio_mixer_play(audio_mixer_sound_t * sound,bool repeat,float volume,audio_mixer_stop_cb_t stop_cb)783 audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
784       float volume, audio_mixer_stop_cb_t stop_cb)
785 {
786    unsigned i;
787    bool res                   = false;
788    audio_mixer_voice_t* voice = s_voices;
789 
790    if (!sound)
791       return NULL;
792 
793    for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
794    {
795       if (voice->type != AUDIO_MIXER_TYPE_NONE)
796          continue;
797 
798       switch (sound->type)
799       {
800          case AUDIO_MIXER_TYPE_WAV:
801             res = audio_mixer_play_wav(sound, voice, repeat, volume, stop_cb);
802             break;
803          case AUDIO_MIXER_TYPE_OGG:
804 #ifdef HAVE_STB_VORBIS
805             res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
806 #endif
807             break;
808          case AUDIO_MIXER_TYPE_MOD:
809 #ifdef HAVE_IBXM
810             res = audio_mixer_play_mod(sound, voice, repeat, volume, stop_cb);
811 #endif
812             break;
813          case AUDIO_MIXER_TYPE_FLAC:
814 #ifdef HAVE_DR_FLAC
815             res = audio_mixer_play_flac(sound, voice, repeat, volume, stop_cb);
816 #endif
817             break;
818          case AUDIO_MIXER_TYPE_MP3:
819 #ifdef HAVE_DR_MP3
820             res = audio_mixer_play_mp3(sound, voice, repeat, volume, stop_cb);
821 #endif
822             break;
823          case AUDIO_MIXER_TYPE_NONE:
824             break;
825       }
826 
827       break;
828    }
829 
830    if (res)
831    {
832       voice->type     = sound->type;
833       voice->repeat   = repeat;
834       voice->volume   = volume;
835       voice->sound    = sound;
836       voice->stop_cb  = stop_cb;
837    }
838    else
839       voice = NULL;
840 
841    return voice;
842 }
843 
audio_mixer_stop(audio_mixer_voice_t * voice)844 void audio_mixer_stop(audio_mixer_voice_t* voice)
845 {
846    audio_mixer_stop_cb_t stop_cb = NULL;
847    audio_mixer_sound_t* sound    = NULL;
848 
849    if (voice)
850    {
851       stop_cb     = voice->stop_cb;
852       sound       = voice->sound;
853 
854       voice->type = AUDIO_MIXER_TYPE_NONE;
855 
856       if (stop_cb)
857          stop_cb(sound, AUDIO_MIXER_SOUND_STOPPED);
858    }
859 }
860 
audio_mixer_mix_wav(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)861 static void audio_mixer_mix_wav(float* buffer, size_t num_frames,
862       audio_mixer_voice_t* voice,
863       float volume)
864 {
865    int i;
866    unsigned buf_free                = (unsigned)(num_frames * 2);
867    const audio_mixer_sound_t* sound = voice->sound;
868    unsigned pcm_available           = sound->types.wav.frames
869       * 2 - voice->types.wav.position;
870    const float* pcm                 = sound->types.wav.pcm +
871       voice->types.wav.position;
872 
873 again:
874    if (pcm_available < buf_free)
875    {
876       for (i = pcm_available; i != 0; i--)
877          *buffer++ += *pcm++ * volume;
878 
879       if (voice->repeat)
880       {
881          if (voice->stop_cb)
882             voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
883 
884          buf_free                  -= pcm_available;
885          pcm_available              = sound->types.wav.frames * 2;
886          pcm                        = sound->types.wav.pcm;
887          voice->types.wav.position  = 0;
888          goto again;
889       }
890 
891       if (voice->stop_cb)
892          voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
893 
894       voice->type = AUDIO_MIXER_TYPE_NONE;
895    }
896    else
897    {
898       for (i = buf_free; i != 0; i--)
899          *buffer++ += *pcm++ * volume;
900 
901       voice->types.wav.position += buf_free;
902    }
903 }
904 
905 #ifdef HAVE_STB_VORBIS
audio_mixer_mix_ogg(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)906 static void audio_mixer_mix_ogg(float* buffer, size_t num_frames,
907       audio_mixer_voice_t* voice,
908       float volume)
909 {
910    int i;
911    float* temp_buffer = NULL;
912    unsigned buf_free                = (unsigned)(num_frames * 2);
913    unsigned temp_samples            = 0;
914    float* pcm                       = NULL;
915 
916    if (voice->types.ogg.position == voice->types.ogg.samples)
917    {
918 again:
919       if (temp_buffer == NULL)
920          temp_buffer = (float*)malloc(AUDIO_MIXER_TEMP_BUFFER * sizeof(float));
921 
922       temp_samples = stb_vorbis_get_samples_float_interleaved(
923             voice->types.ogg.stream, 2, temp_buffer,
924             AUDIO_MIXER_TEMP_BUFFER) * 2;
925 
926       if (temp_samples == 0)
927       {
928          if (voice->repeat)
929          {
930             if (voice->stop_cb)
931                voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
932 
933             stb_vorbis_seek_start(voice->types.ogg.stream);
934             goto again;
935          }
936 
937          if (voice->stop_cb)
938             voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
939 
940          voice->type = AUDIO_MIXER_TYPE_NONE;
941          goto cleanup;
942       }
943 
944       if (voice->types.ogg.resampler)
945       {
946          struct resampler_data info;
947          info.data_in = temp_buffer;
948          info.data_out = voice->types.ogg.buffer;
949          info.input_frames = temp_samples / 2;
950          info.output_frames = 0;
951          info.ratio = voice->types.ogg.ratio;
952 
953          voice->types.ogg.resampler->process(
954                voice->types.ogg.resampler_data, &info);
955       }
956       else
957          memcpy(voice->types.ogg.buffer, temp_buffer,
958                temp_samples * sizeof(float));
959 
960       voice->types.ogg.position = 0;
961       voice->types.ogg.samples  = voice->types.ogg.buf_samples;
962    }
963 
964    pcm = voice->types.ogg.buffer + voice->types.ogg.position;
965 
966    if (voice->types.ogg.samples < buf_free)
967    {
968       for (i = voice->types.ogg.samples; i != 0; i--)
969          *buffer++ += *pcm++ * volume;
970 
971       buf_free -= voice->types.ogg.samples;
972       goto again;
973    }
974 
975    for (i = buf_free; i != 0; --i )
976       *buffer++ += *pcm++ * volume;
977 
978    voice->types.ogg.position += buf_free;
979    voice->types.ogg.samples  -= buf_free;
980 
981 cleanup:
982    if (temp_buffer != NULL)
983       free(temp_buffer);
984 }
985 #endif
986 
987 #ifdef HAVE_IBXM
audio_mixer_mix_mod(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)988 static void audio_mixer_mix_mod(float* buffer, size_t num_frames,
989       audio_mixer_voice_t* voice,
990       float volume)
991 {
992    int i;
993    float samplef                    = 0.0f;
994    int samplei                      = 0;
995    unsigned temp_samples            = 0;
996    unsigned buf_free                = (unsigned)(num_frames * 2);
997    int* pcm                         = NULL;
998 
999    if (voice->types.mod.position == voice->types.mod.samples)
1000    {
1001 again:
1002       temp_samples = replay_get_audio(
1003             voice->types.mod.stream, voice->types.mod.buffer );
1004 
1005       temp_samples *= 2; /* stereo */
1006 
1007       if (temp_samples == 0)
1008       {
1009          if (voice->repeat)
1010          {
1011             if (voice->stop_cb)
1012                voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
1013 
1014             replay_seek( voice->types.mod.stream, 0);
1015             goto again;
1016          }
1017 
1018          if (voice->stop_cb)
1019             voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
1020 
1021          voice->type = AUDIO_MIXER_TYPE_NONE;
1022          return;
1023       }
1024 
1025       voice->types.mod.position = 0;
1026       voice->types.mod.samples  = temp_samples;
1027    }
1028    pcm = voice->types.mod.buffer + voice->types.mod.position;
1029 
1030    if (voice->types.mod.samples < buf_free)
1031    {
1032       for (i = voice->types.mod.samples; i != 0; i--)
1033       {
1034          samplei     = *pcm++ * volume;
1035          samplef     = (float)((int)samplei + 32768) / 65535.0f;
1036          samplef     = samplef * 2.0f - 1.0f;
1037          *buffer++  += samplef;
1038       }
1039 
1040       buf_free -= voice->types.mod.samples;
1041       goto again;
1042    }
1043 
1044    for (i = buf_free; i != 0; --i )
1045    {
1046       samplei     = *pcm++ * volume;
1047       samplef     = (float)((int)samplei + 32768) / 65535.0f;
1048       samplef     = samplef * 2.0f - 1.0f;
1049       *buffer++  += samplef;
1050    }
1051 
1052    voice->types.mod.position += buf_free;
1053    voice->types.mod.samples  -= buf_free;
1054 }
1055 #endif
1056 
1057 #ifdef HAVE_DR_FLAC
audio_mixer_mix_flac(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)1058 static void audio_mixer_mix_flac(float* buffer, size_t num_frames,
1059       audio_mixer_voice_t* voice,
1060       float volume)
1061 {
1062    int i;
1063    struct resampler_data info;
1064    float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 };
1065    unsigned buf_free                = (unsigned)(num_frames * 2);
1066    unsigned temp_samples            = 0;
1067    float *pcm                       = NULL;
1068 
1069    if (voice->types.flac.position == voice->types.flac.samples)
1070    {
1071 again:
1072       temp_samples = (unsigned)drflac_read_f32( voice->types.flac.stream, AUDIO_MIXER_TEMP_BUFFER, temp_buffer);
1073       if (temp_samples == 0)
1074       {
1075          if (voice->repeat)
1076          {
1077             if (voice->stop_cb)
1078                voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
1079 
1080             drflac_seek_to_sample(voice->types.flac.stream,0);
1081             goto again;
1082          }
1083 
1084          if (voice->stop_cb)
1085             voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
1086 
1087          voice->type = AUDIO_MIXER_TYPE_NONE;
1088          return;
1089       }
1090 
1091       info.data_in              = temp_buffer;
1092       info.data_out             = voice->types.flac.buffer;
1093       info.input_frames         = temp_samples / 2;
1094       info.output_frames        = 0;
1095       info.ratio                = voice->types.flac.ratio;
1096 
1097       if (voice->types.flac.resampler)
1098          voice->types.flac.resampler->process(
1099                voice->types.flac.resampler_data, &info);
1100       else
1101          memcpy(voice->types.flac.buffer, temp_buffer, temp_samples * sizeof(float));
1102       voice->types.flac.position = 0;
1103       voice->types.flac.samples  = voice->types.flac.buf_samples;
1104    }
1105 
1106    pcm = voice->types.flac.buffer + voice->types.flac.position;
1107 
1108    if (voice->types.flac.samples < buf_free)
1109    {
1110       for (i = voice->types.flac.samples; i != 0; i--)
1111          *buffer++ += *pcm++ * volume;
1112 
1113       buf_free -= voice->types.flac.samples;
1114       goto again;
1115    }
1116 
1117    for (i = buf_free; i != 0; --i )
1118       *buffer++ += *pcm++ * volume;
1119 
1120    voice->types.flac.position += buf_free;
1121    voice->types.flac.samples  -= buf_free;
1122 }
1123 #endif
1124 
1125 #ifdef HAVE_DR_MP3
audio_mixer_mix_mp3(float * buffer,size_t num_frames,audio_mixer_voice_t * voice,float volume)1126 static void audio_mixer_mix_mp3(float* buffer, size_t num_frames,
1127       audio_mixer_voice_t* voice,
1128       float volume)
1129 {
1130    int i;
1131    struct resampler_data info;
1132    float temp_buffer[AUDIO_MIXER_TEMP_BUFFER] = { 0 };
1133    unsigned buf_free                = (unsigned)(num_frames * 2);
1134    unsigned temp_samples            = 0;
1135    float* pcm                       = NULL;
1136 
1137    if (voice->types.mp3.position == voice->types.mp3.samples)
1138    {
1139 again:
1140       temp_samples = (unsigned)drmp3_read_f32(
1141             &voice->types.mp3.stream,
1142             AUDIO_MIXER_TEMP_BUFFER / 2, temp_buffer) * 2;
1143 
1144       if (temp_samples == 0)
1145       {
1146          if (voice->repeat)
1147          {
1148             if (voice->stop_cb)
1149                voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_REPEATED);
1150 
1151             drmp3_seek_to_frame(&voice->types.mp3.stream,0);
1152             goto again;
1153          }
1154 
1155          if (voice->stop_cb)
1156             voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_FINISHED);
1157 
1158          voice->type = AUDIO_MIXER_TYPE_NONE;
1159          return;
1160       }
1161 
1162       info.data_in              = temp_buffer;
1163       info.data_out             = voice->types.mp3.buffer;
1164       info.input_frames         = temp_samples / 2;
1165       info.output_frames        = 0;
1166       info.ratio                = voice->types.mp3.ratio;
1167 
1168       if (voice->types.mp3.resampler)
1169          voice->types.mp3.resampler->process(
1170                voice->types.mp3.resampler_data, &info);
1171       else
1172          memcpy(voice->types.mp3.buffer, temp_buffer,
1173                temp_samples * sizeof(float));
1174       voice->types.mp3.position = 0;
1175       voice->types.mp3.samples  = voice->types.mp3.buf_samples;
1176    }
1177 
1178    pcm = voice->types.mp3.buffer + voice->types.mp3.position;
1179 
1180    if (voice->types.mp3.samples < buf_free)
1181    {
1182       for (i = voice->types.mp3.samples; i != 0; i--)
1183          *buffer++ += *pcm++ * volume;
1184 
1185       buf_free -= voice->types.mp3.samples;
1186       goto again;
1187    }
1188 
1189    for (i = buf_free; i != 0; --i )
1190       *buffer++ += *pcm++ * volume;
1191 
1192    voice->types.mp3.position += buf_free;
1193    voice->types.mp3.samples  -= buf_free;
1194 }
1195 #endif
1196 
audio_mixer_mix(float * buffer,size_t num_frames,float volume_override,bool override)1197 void audio_mixer_mix(float* buffer, size_t num_frames,
1198       float volume_override, bool override)
1199 {
1200    unsigned i;
1201    size_t j                   = 0;
1202    float* sample              = NULL;
1203    audio_mixer_voice_t* voice = s_voices;
1204 
1205    for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
1206    {
1207       float volume = (override) ? volume_override : voice->volume;
1208 
1209       switch (voice->type)
1210       {
1211          case AUDIO_MIXER_TYPE_WAV:
1212             audio_mixer_mix_wav(buffer, num_frames, voice, volume);
1213             break;
1214          case AUDIO_MIXER_TYPE_OGG:
1215 #ifdef HAVE_STB_VORBIS
1216             audio_mixer_mix_ogg(buffer, num_frames, voice, volume);
1217 #endif
1218             break;
1219          case AUDIO_MIXER_TYPE_MOD:
1220 #ifdef HAVE_IBXM
1221             audio_mixer_mix_mod(buffer, num_frames, voice, volume);
1222 #endif
1223             break;
1224          case AUDIO_MIXER_TYPE_FLAC:
1225 #ifdef HAVE_DR_FLAC
1226             audio_mixer_mix_flac(buffer, num_frames, voice, volume);
1227 #endif
1228             break;
1229             case AUDIO_MIXER_TYPE_MP3:
1230 #ifdef HAVE_DR_MP3
1231             audio_mixer_mix_mp3(buffer, num_frames, voice, volume);
1232 #endif
1233             break;
1234          case AUDIO_MIXER_TYPE_NONE:
1235             break;
1236       }
1237    }
1238 
1239    for (j = 0, sample = buffer; j < num_frames * 2; j++, sample++)
1240    {
1241       if (*sample < -1.0f)
1242          *sample = -1.0f;
1243       else if (*sample > 1.0f)
1244          *sample = 1.0f;
1245    }
1246 }
1247 
audio_mixer_voice_get_volume(audio_mixer_voice_t * voice)1248 float audio_mixer_voice_get_volume(audio_mixer_voice_t *voice)
1249 {
1250    if (!voice)
1251       return 0.0f;
1252 
1253    return voice->volume;
1254 }
1255 
audio_mixer_voice_set_volume(audio_mixer_voice_t * voice,float val)1256 void audio_mixer_voice_set_volume(audio_mixer_voice_t *voice, float val)
1257 {
1258    if (!voice)
1259       return;
1260 
1261    voice->volume = val;
1262 }
1263