(audio_mixer.c) Some refactors

This commit is contained in:
twinaphex 2017-05-08 20:27:13 +02:00
parent 48c4e1227a
commit bd36b0a968

View File

@ -46,13 +46,16 @@
#define AUDIO_MIXER_MAX_VOICES 8 #define AUDIO_MIXER_MAX_VOICES 8
#define AUDIO_MIXER_TEMP_OGG_BUFFER 8192 #define AUDIO_MIXER_TEMP_OGG_BUFFER 8192
#define AUDIO_MIXER_TYPE_NONE 0 enum audio_mixer_type
#define AUDIO_MIXER_TYPE_WAV 1 {
#define AUDIO_MIXER_TYPE_OGG 2 AUDIO_MIXER_TYPE_NONE = 0,
AUDIO_MIXER_TYPE_WAV,
AUDIO_MIXER_TYPE_OGG
};
struct audio_mixer_sound struct audio_mixer_sound
{ {
unsigned type; enum audio_mixer_type type;
union union
{ {
@ -342,6 +345,8 @@ void audio_mixer_destroy(audio_mixer_sound_t* sound)
memalign_free((void*)sound->types.ogg.data); memalign_free((void*)sound->types.ogg.data);
#endif #endif
break; break;
case AUDIO_MIXER_TYPE_NONE:
break;
} }
free(sound); free(sound);
@ -351,11 +356,6 @@ static bool audio_mixer_play_wav(audio_mixer_sound_t* sound,
audio_mixer_voice_t* voice, bool repeat, float volume, audio_mixer_voice_t* voice, bool repeat, float volume,
audio_mixer_stop_cb_t stop_cb) audio_mixer_stop_cb_t stop_cb)
{ {
voice->type = AUDIO_MIXER_TYPE_WAV;
voice->repeat = repeat;
voice->volume = volume;
voice->sound = sound;
voice->stop_cb = stop_cb;
voice->types.wav.position = 0; voice->types.wav.position = 0;
return true; return true;
@ -369,58 +369,59 @@ static bool audio_mixer_play_ogg(
audio_mixer_stop_cb_t stop_cb) audio_mixer_stop_cb_t stop_cb)
{ {
stb_vorbis_info info; stb_vorbis_info info;
int res = 0; int res = 0;
float ratio = 0.0f; float ratio = 0.0f;
unsigned samples = 0; unsigned samples = 0;
void *ogg_buffer = NULL;
voice->repeat = repeat; void *resampler_data = NULL;
voice->volume = volume; const retro_resampler_t* resamp = NULL;
voice->sound = sound; stb_vorbis *stb_vorbis = stb_vorbis_open_memory(
voice->stop_cb = stop_cb;
voice->types.ogg.stream = stb_vorbis_open_memory(
(const unsigned char*)sound->types.ogg.data, (const unsigned char*)sound->types.ogg.data,
sound->types.ogg.size, &res, NULL); sound->types.ogg.size, &res, NULL);
if (!voice->types.ogg.stream) if (!stb_vorbis)
return false; return false;
info = stb_vorbis_get_info(voice->types.ogg.stream); info = stb_vorbis_get_info(stb_vorbis);
/* Only stereo supported for now */ /* Only stereo supported for now */
if (info.channels != 2) if (info.channels != 2)
{ goto error;
stb_vorbis_close(voice->types.ogg.stream);
return false;
}
if (info.sample_rate != s_rate) if (info.sample_rate != s_rate)
{ {
voice->types.ogg.ratio = ratio = (double)s_rate / (double)info.sample_rate; ratio = (double)s_rate / (double)info.sample_rate;
if (!retro_resampler_realloc(&voice->types.ogg.resampler_data, if (!retro_resampler_realloc(&resampler_data,
&voice->types.ogg.resampler, NULL, ratio)) &resamp, NULL, ratio))
{ goto error;
stb_vorbis_close(voice->types.ogg.stream);
return false;
}
} }
samples = samples = (unsigned)(AUDIO_MIXER_TEMP_OGG_BUFFER * ratio);
voice->types.ogg.buf_samples = (unsigned)(AUDIO_MIXER_TEMP_OGG_BUFFER * ratio); ogg_buffer = (float*)memalign_alloc(16,
voice->types.ogg.buffer = (float*)memalign_alloc(16,
((samples + 15) & ~15) * sizeof(float)); ((samples + 15) & ~15) * sizeof(float));
if (!voice->types.ogg.buffer) if (!ogg_buffer)
{ {
voice->types.ogg.resampler->free(voice->types.ogg.resampler_data); resamp->free(resampler_data);
stb_vorbis_close(voice->types.ogg.stream); goto error;
return false;
} }
voice->type = AUDIO_MIXER_TYPE_OGG; voice->types.ogg.resampler = resamp;
voice->types.ogg.position = voice->types.ogg.samples = 0; voice->types.ogg.resampler_data = resampler_data;
voice->types.ogg.buffer = ogg_buffer;
voice->types.ogg.buf_samples = samples;
voice->types.ogg.ratio = ratio;
voice->types.ogg.stream = stb_vorbis;
voice->types.ogg.position = 0;
voice->types.ogg.samples = 0;
voice->type = AUDIO_MIXER_TYPE_OGG;
return true; return true;
error:
stb_vorbis_close(stb_vorbis);
return false;
} }
#endif #endif
@ -430,9 +431,15 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
unsigned i; unsigned i;
bool res = false; bool res = false;
audio_mixer_voice_t* voice = s_voices; audio_mixer_voice_t* voice = s_voices;
if (!sound)
return NULL;
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++) for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
{ {
if (!voice)
continue;
if (voice->type == AUDIO_MIXER_TYPE_NONE) if (voice->type == AUDIO_MIXER_TYPE_NONE)
{ {
switch (sound->type) switch (sound->type)
@ -445,15 +452,24 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb); res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
#endif #endif
break; break;
case AUDIO_MIXER_TYPE_NONE:
break;
} }
break; break;
} }
} }
if (res) if (!res)
return voice; return NULL;
return NULL;
voice->type = sound->type;
voice->repeat = repeat;
voice->volume = volume;
voice->sound = sound;
voice->stop_cb = stop_cb;
return voice;
} }
void audio_mixer_stop(audio_mixer_voice_t* voice) void audio_mixer_stop(audio_mixer_voice_t* voice)