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