mirror of
https://github.com/libretro/RetroArch
synced 2025-04-11 00:44:20 +00:00
Merge pull request #4951 from leiradel/master
* Add a mutex to prevent issues if audio_mixer_mix is used in a diffe…
This commit is contained in:
commit
450ab7de40
@ -26,6 +26,10 @@
|
|||||||
#include <formats/rwav.h>
|
#include <formats/rwav.h>
|
||||||
#include <memalign.h>
|
#include <memalign.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
#include <rthreads/rthreads.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -105,6 +109,10 @@ struct audio_mixer_voice
|
|||||||
static struct audio_mixer_voice s_voices[AUDIO_MIXER_MAX_VOICES];
|
static struct audio_mixer_voice s_voices[AUDIO_MIXER_MAX_VOICES];
|
||||||
static unsigned s_rate = 0;
|
static unsigned s_rate = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
static slock_t* s_locker = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool wav2float(const rwav_t* wav, float** pcm, size_t samples_out)
|
static bool wav2float(const rwav_t* wav, float** pcm, size_t samples_out)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -225,12 +233,22 @@ void audio_mixer_init(unsigned rate)
|
|||||||
|
|
||||||
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
|
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
|
||||||
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
|
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
s_locker = slock_new();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_mixer_done(void)
|
void audio_mixer_done(void)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
/* Dont call audio mixer functions after this point */
|
||||||
|
slock_free(s_locker);
|
||||||
|
s_locker = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
|
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
|
||||||
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
|
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
|
||||||
}
|
}
|
||||||
@ -250,6 +268,7 @@ audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
samples = wav.numsamples * 2;
|
samples = wav.numsamples * 2;
|
||||||
|
|
||||||
if (!wav2float(&wav, &pcm, samples))
|
if (!wav2float(&wav, &pcm, samples))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -317,7 +336,7 @@ void audio_mixer_destroy(audio_mixer_sound_t* sound)
|
|||||||
#ifdef HAVE_STB_VORBIS
|
#ifdef HAVE_STB_VORBIS
|
||||||
handle = (void*)sound->types.ogg.data;
|
handle = (void*)sound->types.ogg.data;
|
||||||
if (handle)
|
if (handle)
|
||||||
memalign_free(handle);
|
free(handle);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case AUDIO_MIXER_TYPE_NONE:
|
case AUDIO_MIXER_TYPE_NONE:
|
||||||
@ -332,7 +351,6 @@ static bool audio_mixer_play_wav(audio_mixer_sound_t* sound,
|
|||||||
audio_mixer_stop_cb_t stop_cb)
|
audio_mixer_stop_cb_t stop_cb)
|
||||||
{
|
{
|
||||||
voice->types.wav.position = 0;
|
voice->types.wav.position = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +408,6 @@ static bool audio_mixer_play_ogg(
|
|||||||
voice->types.ogg.stream = stb_vorbis;
|
voice->types.ogg.stream = stb_vorbis;
|
||||||
voice->types.ogg.position = 0;
|
voice->types.ogg.position = 0;
|
||||||
voice->types.ogg.samples = 0;
|
voice->types.ogg.samples = 0;
|
||||||
voice->type = AUDIO_MIXER_TYPE_OGG;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -409,6 +426,10 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
|||||||
|
|
||||||
if (!sound)
|
if (!sound)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
slock_lock(s_locker);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
|
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
|
||||||
{
|
{
|
||||||
@ -431,23 +452,48 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
voice->type = sound->type;
|
||||||
|
voice->repeat = repeat;
|
||||||
|
voice->volume = volume;
|
||||||
|
voice->sound = sound;
|
||||||
|
voice->stop_cb = stop_cb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
voice = NULL;
|
||||||
|
|
||||||
if (!res)
|
#ifdef HAVE_THREADS
|
||||||
return NULL;
|
slock_unlock(s_locker);
|
||||||
|
#endif
|
||||||
voice->type = sound->type;
|
|
||||||
voice->repeat = repeat;
|
|
||||||
voice->volume = volume;
|
|
||||||
voice->sound = sound;
|
|
||||||
voice->stop_cb = stop_cb;
|
|
||||||
|
|
||||||
return voice;
|
return voice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_mixer_stop(audio_mixer_voice_t* voice)
|
void audio_mixer_stop(audio_mixer_voice_t* voice)
|
||||||
{
|
{
|
||||||
if (voice && voice->stop_cb)
|
audio_mixer_stop_cb_t stop_cb = NULL;
|
||||||
voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_STOPPED);
|
audio_mixer_sound_t* sound = NULL;
|
||||||
|
|
||||||
|
if (voice)
|
||||||
|
{
|
||||||
|
stop_cb = voice->stop_cb;
|
||||||
|
sound = voice->sound;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
slock_lock(s_locker);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
voice->type = AUDIO_MIXER_TYPE_NONE;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
slock_unlock(s_locker);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (stop_cb)
|
||||||
|
stop_cb(sound, AUDIO_MIXER_SOUND_STOPPED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void audio_mixer_mix_wav(float* buffer, size_t num_frames,
|
static void audio_mixer_mix_wav(float* buffer, size_t num_frames,
|
||||||
@ -573,6 +619,10 @@ void audio_mixer_mix(float* buffer, size_t num_frames)
|
|||||||
float* sample = NULL;
|
float* sample = NULL;
|
||||||
audio_mixer_voice_t* voice = s_voices;
|
audio_mixer_voice_t* voice = s_voices;
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
slock_lock(s_locker);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
|
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
|
||||||
{
|
{
|
||||||
float volume = voice->volume;
|
float volume = voice->volume;
|
||||||
@ -592,6 +642,10 @@ void audio_mixer_mix(float* buffer, size_t num_frames)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
slock_unlock(s_locker);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (j = 0, sample = buffer; j < num_frames; j++, sample++)
|
for (j = 0, sample = buffer; j < num_frames; j++, sample++)
|
||||||
{
|
{
|
||||||
if (*sample < -1.0f)
|
if (*sample < -1.0f)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user