diff --git a/audio/audio_mixer.c b/audio/audio_mixer.c index 5e77cf1..28fb847 100644 --- a/audio/audio_mixer.c +++ b/audio/audio_mixer.c @@ -26,6 +26,10 @@ #include #include +#ifdef HAVE_THREADS +#include +#endif + #include #include #include @@ -105,6 +109,10 @@ struct audio_mixer_voice static struct audio_mixer_voice s_voices[AUDIO_MIXER_MAX_VOICES]; 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) { size_t i; @@ -225,12 +233,22 @@ void audio_mixer_init(unsigned rate) for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++) s_voices[i].type = AUDIO_MIXER_TYPE_NONE; + +#ifdef HAVE_THREADS + s_locker = slock_new(); +#endif } void audio_mixer_done(void) { 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++) 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; samples = wav.numsamples * 2; + if (!wav2float(&wav, &pcm, samples)) return NULL; @@ -317,7 +336,7 @@ void audio_mixer_destroy(audio_mixer_sound_t* sound) #ifdef HAVE_STB_VORBIS handle = (void*)sound->types.ogg.data; if (handle) - memalign_free(handle); + free(handle); #endif break; 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) { voice->types.wav.position = 0; - return true; } @@ -390,7 +408,6 @@ static bool audio_mixer_play_ogg( voice->types.ogg.stream = stb_vorbis; voice->types.ogg.position = 0; voice->types.ogg.samples = 0; - voice->type = AUDIO_MIXER_TYPE_OGG; return true; @@ -409,6 +426,10 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat, if (!sound) return NULL; + +#ifdef HAVE_THREADS + slock_lock(s_locker); +#endif 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; } + + 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) - return NULL; - - voice->type = sound->type; - voice->repeat = repeat; - voice->volume = volume; - voice->sound = sound; - voice->stop_cb = stop_cb; +#ifdef HAVE_THREADS + slock_unlock(s_locker); +#endif return voice; } void audio_mixer_stop(audio_mixer_voice_t* voice) { - if (voice && voice->stop_cb) - voice->stop_cb(voice->sound, AUDIO_MIXER_SOUND_STOPPED); + audio_mixer_stop_cb_t stop_cb = NULL; + 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, @@ -573,6 +619,10 @@ void audio_mixer_mix(float* buffer, size_t num_frames) float* sample = NULL; 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++) { 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++) { if (*sample < -1.0f) diff --git a/audio/resampler/drivers/sinc_resampler.c b/audio/resampler/drivers/sinc_resampler.c index 76fd926..ee2e3d0 100644 --- a/audio/resampler/drivers/sinc_resampler.c +++ b/audio/resampler/drivers/sinc_resampler.c @@ -451,11 +451,12 @@ static void resampler_sinc_process_c(void *re_, struct resampler_data *data) output[0] = sum_l; output[1] = sum_r; + + output += 2; + out_frames++; + resamp->time += ratio; } - output += 2; - out_frames++; - resamp->time += ratio; } data->output_frames = out_frames; diff --git a/include/queues/task_queue.h b/include/queues/task_queue.h index 5910c15..28322ad 100644 --- a/include/queues/task_queue.h +++ b/include/queues/task_queue.h @@ -57,6 +57,8 @@ typedef void (*retro_task_queue_msg_t)(const char *msg, typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data); +typedef bool (*retro_task_condition_fn_t)(void *data); + typedef struct { char *source_file; @@ -200,9 +202,12 @@ void task_queue_check(void); * The task will start as soon as possible. */ void task_queue_push(retro_task_t *task); -/* Blocks until all tasks have finished. +/* Blocks until all tasks have finished + * will return early if cond is not NULL + * and cond(data) returns false. * This must only be called from the main thread. */ -void task_queue_wait(void); +void task_queue_wait(retro_task_condition_fn_t cond, void* data); + /* Sends a signal to terminate all the tasks. * diff --git a/include/retro_common_api.h b/include/retro_common_api.h index c325019..38b6773 100644 --- a/include/retro_common_api.h +++ b/include/retro_common_api.h @@ -79,7 +79,7 @@ typedef int ssize_t; #define STRING_REP_INT64 "%I64u" #define STRING_REP_UINT64 "%I64u" #define STRING_REP_ULONG "%Iu" -#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L && !defined(VITA) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L && !defined(VITA) && !defined(WIIU) #define STRING_REP_INT64 "%llu" #define STRING_REP_UINT64 "%llu" #define STRING_REP_ULONG "%zu" diff --git a/queues/task_queue.c b/queues/task_queue.c index b8782e8..bc92e7b 100644 --- a/queues/task_queue.c +++ b/queues/task_queue.c @@ -47,7 +47,7 @@ struct retro_task_impl void (*push_running)(retro_task_t *); void (*cancel)(void *); void (*reset)(void); - void (*wait)(void); + void (*wait)(retro_task_condition_fn_t, void *); void (*gather)(void); bool (*find)(retro_task_finder_t, void*); void (*retrieve)(task_retriever_data_t *data); @@ -189,9 +189,9 @@ static void retro_task_regular_gather(void) retro_task_internal_gather(); } -static void retro_task_regular_wait(void) +static void retro_task_regular_wait(retro_task_condition_fn_t cond, void* data) { - while (tasks_running.front) + while (tasks_running.front && (!cond || cond(data))) retro_task_regular_gather(); } @@ -373,7 +373,7 @@ static void retro_task_threaded_gather(void) slock_unlock(property_lock); } -static void retro_task_threaded_wait(void) +static void retro_task_threaded_wait(retro_task_condition_fn_t cond, void* data) { bool wait = false; @@ -382,7 +382,8 @@ static void retro_task_threaded_wait(void) retro_task_threaded_gather(); slock_lock(running_lock); - wait = (tasks_running.front != NULL); + wait = (tasks_running.front != NULL) && + (!cond || cond(data)); slock_unlock(running_lock); } while (wait); } @@ -637,9 +638,9 @@ void task_queue_push(retro_task_t *task) impl_current->push_running(task); } -void task_queue_wait(void) +void task_queue_wait(retro_task_condition_fn_t cond, void* data) { - impl_current->wait(); + impl_current->wait(cond, data); } void task_queue_reset(void) diff --git a/streams/stdin_stream.c b/streams/stdin_stream.c index 83c5bf4..786aa5e 100644 --- a/streams/stdin_stream.c +++ b/streams/stdin_stream.c @@ -20,6 +20,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include +#include #include #include @@ -34,6 +36,8 @@ #include +#include + #if defined(_WIN32) && defined(_XBOX) size_t read_stdin(char *buf, size_t size) {