mirror of
https://github.com/libretro/RetroArch
synced 2025-01-29 18:32:44 +00:00
Fix menu sounds (audio mixing) when using the 'sinc' resampler with quality lower than 'normal'
This commit is contained in:
parent
9ea6f15c1d
commit
547f04b894
@ -114,7 +114,8 @@ void audio_mix_free_chunk(audio_chunk_t *chunk)
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate)
|
||||
audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate,
|
||||
const char *resampler_ident, enum resampler_quality quality)
|
||||
{
|
||||
#ifdef HAVE_RWAV
|
||||
int sample_size;
|
||||
@ -233,8 +234,8 @@ audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate)
|
||||
|
||||
retro_resampler_realloc(&chunk->resampler_data,
|
||||
&chunk->resampler,
|
||||
NULL,
|
||||
RESAMPLER_QUALITY_DONTCARE,
|
||||
resampler_ident,
|
||||
quality,
|
||||
chunk->ratio);
|
||||
|
||||
if (chunk->resampler && chunk->resampler_data)
|
||||
|
@ -267,15 +267,16 @@ static bool wav_to_float(const rwav_t* wav, float** pcm, size_t samples_out)
|
||||
}
|
||||
|
||||
static bool one_shot_resample(const float* in, size_t samples_in,
|
||||
unsigned rate, float** out, size_t* samples_out)
|
||||
unsigned rate, const char *resampler_ident, enum resampler_quality quality,
|
||||
float** out, size_t* samples_out)
|
||||
{
|
||||
struct resampler_data info;
|
||||
void* data = NULL;
|
||||
const retro_resampler_t* resampler = NULL;
|
||||
float ratio = (double)s_rate / (double)rate;
|
||||
|
||||
if (!retro_resampler_realloc(&data, &resampler, NULL,
|
||||
RESAMPLER_QUALITY_DONTCARE, ratio))
|
||||
if (!retro_resampler_realloc(&data, &resampler,
|
||||
resampler_ident, quality, ratio))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@ -323,7 +324,8 @@ void audio_mixer_done(void)
|
||||
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
|
||||
}
|
||||
|
||||
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
|
||||
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size,
|
||||
const char *resampler_ident, enum resampler_quality quality)
|
||||
{
|
||||
#ifdef HAVE_RWAV
|
||||
/* WAV data */
|
||||
@ -353,8 +355,9 @@ audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
|
||||
{
|
||||
float* resampled = NULL;
|
||||
|
||||
if (!one_shot_resample(pcm, samples,
|
||||
wav.samplerate, &resampled, &samples))
|
||||
if (!one_shot_resample(pcm, samples, wav.samplerate,
|
||||
resampler_ident, quality,
|
||||
&resampled, &samples))
|
||||
return NULL;
|
||||
|
||||
memalign_free((void*)pcm);
|
||||
@ -514,6 +517,8 @@ static bool audio_mixer_play_ogg(
|
||||
audio_mixer_sound_t* sound,
|
||||
audio_mixer_voice_t* voice,
|
||||
bool repeat, float volume,
|
||||
const char *resampler_ident,
|
||||
enum resampler_quality quality,
|
||||
audio_mixer_stop_cb_t stop_cb)
|
||||
{
|
||||
stb_vorbis_info info;
|
||||
@ -537,7 +542,7 @@ static bool audio_mixer_play_ogg(
|
||||
ratio = (double)s_rate / (double)info.sample_rate;
|
||||
|
||||
if (!retro_resampler_realloc(&resampler_data,
|
||||
&resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
|
||||
&resamp, resampler_ident, quality,
|
||||
ratio))
|
||||
goto error;
|
||||
}
|
||||
@ -662,6 +667,8 @@ static bool audio_mixer_play_flac(
|
||||
audio_mixer_sound_t* sound,
|
||||
audio_mixer_voice_t* voice,
|
||||
bool repeat, float volume,
|
||||
const char *resampler_ident,
|
||||
enum resampler_quality quality,
|
||||
audio_mixer_stop_cb_t stop_cb)
|
||||
{
|
||||
float ratio = 1.0f;
|
||||
@ -678,7 +685,7 @@ static bool audio_mixer_play_flac(
|
||||
ratio = (double)s_rate / (double)(dr_flac->sampleRate);
|
||||
|
||||
if (!retro_resampler_realloc(&resampler_data,
|
||||
&resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
|
||||
&resamp, resampler_ident, quality,
|
||||
ratio))
|
||||
goto error;
|
||||
}
|
||||
@ -723,6 +730,8 @@ static bool audio_mixer_play_mp3(
|
||||
audio_mixer_sound_t* sound,
|
||||
audio_mixer_voice_t* voice,
|
||||
bool repeat, float volume,
|
||||
const char *resampler_ident,
|
||||
enum resampler_quality quality,
|
||||
audio_mixer_stop_cb_t stop_cb)
|
||||
{
|
||||
float ratio = 1.0f;
|
||||
@ -748,7 +757,7 @@ static bool audio_mixer_play_mp3(
|
||||
ratio = (double)s_rate / (double)(voice->types.mp3.stream.sampleRate);
|
||||
|
||||
if (!retro_resampler_realloc(&resampler_data,
|
||||
&resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
|
||||
&resamp, resampler_ident, quality,
|
||||
ratio))
|
||||
goto error;
|
||||
}
|
||||
@ -786,8 +795,11 @@ error:
|
||||
}
|
||||
#endif
|
||||
|
||||
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
||||
float volume, audio_mixer_stop_cb_t stop_cb)
|
||||
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound,
|
||||
bool repeat, float volume,
|
||||
const char *resampler_ident,
|
||||
enum resampler_quality quality,
|
||||
audio_mixer_stop_cb_t stop_cb)
|
||||
{
|
||||
unsigned i;
|
||||
bool res = false;
|
||||
@ -808,7 +820,8 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_OGG:
|
||||
#ifdef HAVE_STB_VORBIS
|
||||
res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
|
||||
res = audio_mixer_play_ogg(sound, voice, repeat, volume,
|
||||
resampler_ident, quality, stop_cb);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_MOD:
|
||||
@ -818,12 +831,14 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_FLAC:
|
||||
#ifdef HAVE_DR_FLAC
|
||||
res = audio_mixer_play_flac(sound, voice, repeat, volume, stop_cb);
|
||||
res = audio_mixer_play_flac(sound, voice, repeat, volume,
|
||||
resampler_ident, quality, stop_cb);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_MP3:
|
||||
#ifdef HAVE_DR_MP3
|
||||
res = audio_mixer_play_mp3(sound, voice, repeat, volume, stop_cb);
|
||||
res = audio_mixer_play_mp3(sound, voice, repeat, volume,
|
||||
resampler_ident, quality, stop_cb);
|
||||
#endif
|
||||
break;
|
||||
case AUDIO_MIXER_TYPE_NONE:
|
||||
|
@ -68,7 +68,8 @@ void audio_mix_volume_C(float *dst, const float *src, float vol, size_t samples)
|
||||
|
||||
void audio_mix_free_chunk(audio_chunk_t *chunk);
|
||||
|
||||
audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate);
|
||||
audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate,
|
||||
const char *resampler_ident, enum resampler_quality quality);
|
||||
|
||||
size_t audio_mix_get_chunk_num_samples(audio_chunk_t *chunk);
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <audio/audio_resampler.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
enum audio_mixer_type
|
||||
@ -60,7 +62,8 @@ void audio_mixer_init(unsigned rate);
|
||||
|
||||
void audio_mixer_done(void);
|
||||
|
||||
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size);
|
||||
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size,
|
||||
const char *resampler_ident, enum resampler_quality quality);
|
||||
audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size);
|
||||
audio_mixer_sound_t* audio_mixer_load_mod(void *buffer, int32_t size);
|
||||
audio_mixer_sound_t* audio_mixer_load_flac(void *buffer, int32_t size);
|
||||
@ -69,7 +72,10 @@ audio_mixer_sound_t* audio_mixer_load_mp3(void *buffer, int32_t size);
|
||||
void audio_mixer_destroy(audio_mixer_sound_t* sound);
|
||||
|
||||
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound,
|
||||
bool repeat, float volume, audio_mixer_stop_cb_t stop_cb);
|
||||
bool repeat, float volume,
|
||||
const char *resampler_ident,
|
||||
enum resampler_quality quality,
|
||||
audio_mixer_stop_cb_t stop_cb);
|
||||
|
||||
void audio_mixer_stop(audio_mixer_voice_t* voice);
|
||||
|
||||
|
49
retroarch.c
49
retroarch.c
@ -24937,8 +24937,10 @@ static void audio_driver_deinit_resampler(struct rarch_state *p_rarch)
|
||||
{
|
||||
if (p_rarch->audio_driver_resampler && p_rarch->audio_driver_resampler_data)
|
||||
p_rarch->audio_driver_resampler->free(p_rarch->audio_driver_resampler_data);
|
||||
p_rarch->audio_driver_resampler = NULL;
|
||||
p_rarch->audio_driver_resampler_data = NULL;
|
||||
p_rarch->audio_driver_resampler = NULL;
|
||||
p_rarch->audio_driver_resampler_data = NULL;
|
||||
p_rarch->audio_driver_resampler_ident[0] = '\0';
|
||||
p_rarch->audio_driver_resampler_quality = RESAMPLER_QUALITY_DONTCARE;
|
||||
}
|
||||
|
||||
|
||||
@ -25195,15 +25197,25 @@ static bool audio_driver_init_internal(
|
||||
p_rarch->audio_source_ratio_current =
|
||||
(double)settings->uints.audio_output_sample_rate / p_rarch->audio_driver_input;
|
||||
|
||||
if (!string_is_empty(settings->arrays.audio_resampler))
|
||||
strlcpy(p_rarch->audio_driver_resampler_ident,
|
||||
settings->arrays.audio_resampler,
|
||||
sizeof(p_rarch->audio_driver_resampler_ident));
|
||||
else
|
||||
p_rarch->audio_driver_resampler_ident[0] = '\0';
|
||||
|
||||
p_rarch->audio_driver_resampler_quality =
|
||||
audio_driver_get_resampler_quality(settings);
|
||||
|
||||
if (!retro_resampler_realloc(
|
||||
&p_rarch->audio_driver_resampler_data,
|
||||
&p_rarch->audio_driver_resampler,
|
||||
settings->arrays.audio_resampler,
|
||||
audio_driver_get_resampler_quality(settings),
|
||||
p_rarch->audio_driver_resampler_ident,
|
||||
p_rarch->audio_driver_resampler_quality,
|
||||
p_rarch->audio_source_ratio_original))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize resampler \"%s\".\n",
|
||||
settings->arrays.audio_resampler);
|
||||
p_rarch->audio_driver_resampler_ident);
|
||||
p_rarch->audio_driver_active = false;
|
||||
}
|
||||
|
||||
@ -25932,6 +25944,13 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
{
|
||||
case AUDIO_MIXER_SLOT_SELECTION_MANUAL:
|
||||
free_slot = params->slot_selection_idx;
|
||||
|
||||
/* If we are using a manually specified
|
||||
* slot, must free any existing stream
|
||||
* before assigning the new one */
|
||||
audio_driver_mixer_stop_stream(free_slot);
|
||||
audio_driver_mixer_remove_stream(free_slot);
|
||||
|
||||
break;
|
||||
case AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC:
|
||||
default:
|
||||
@ -25954,7 +25973,9 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
switch (params->type)
|
||||
{
|
||||
case AUDIO_MIXER_TYPE_WAV:
|
||||
handle = audio_mixer_load_wav(buf, (int32_t)params->bufsize);
|
||||
handle = audio_mixer_load_wav(buf, (int32_t)params->bufsize,
|
||||
p_rarch->audio_driver_resampler_ident,
|
||||
p_rarch->audio_driver_resampler_quality);
|
||||
/* WAV is a special case - input buffer is not
|
||||
* free()'d when sound playback is complete (it is
|
||||
* converted to a PCM buffer, which is free()'d instead),
|
||||
@ -25992,14 +26013,20 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
{
|
||||
case AUDIO_STREAM_STATE_PLAYING_LOOPED:
|
||||
looped = true;
|
||||
voice = audio_mixer_play(handle, looped, params->volume, stop_cb);
|
||||
voice = audio_mixer_play(handle, looped, params->volume,
|
||||
p_rarch->audio_driver_resampler_ident,
|
||||
p_rarch->audio_driver_resampler_quality, stop_cb);
|
||||
break;
|
||||
case AUDIO_STREAM_STATE_PLAYING:
|
||||
voice = audio_mixer_play(handle, looped, params->volume, stop_cb);
|
||||
voice = audio_mixer_play(handle, looped, params->volume,
|
||||
p_rarch->audio_driver_resampler_ident,
|
||||
p_rarch->audio_driver_resampler_quality, stop_cb);
|
||||
break;
|
||||
case AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL:
|
||||
stop_cb = audio_mixer_play_stop_sequential_cb;
|
||||
voice = audio_mixer_play(handle, looped, params->volume, stop_cb);
|
||||
voice = audio_mixer_play(handle, looped, params->volume,
|
||||
p_rarch->audio_driver_resampler_ident,
|
||||
p_rarch->audio_driver_resampler_quality, stop_cb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -26043,7 +26070,9 @@ static void audio_driver_mixer_play_stream_internal(
|
||||
p_rarch->audio_mixer_streams[i].voice =
|
||||
audio_mixer_play(p_rarch->audio_mixer_streams[i].handle,
|
||||
(type == AUDIO_STREAM_STATE_PLAYING_LOOPED) ? true : false,
|
||||
1.0f, p_rarch->audio_mixer_streams[i].stop_cb);
|
||||
1.0f, p_rarch->audio_driver_resampler_ident,
|
||||
p_rarch->audio_driver_resampler_quality,
|
||||
p_rarch->audio_mixer_streams[i].stop_cb);
|
||||
p_rarch->audio_mixer_streams[i].state = (enum audio_mixer_state)type;
|
||||
break;
|
||||
case AUDIO_STREAM_STATE_PLAYING:
|
||||
|
@ -1713,6 +1713,7 @@ struct rarch_state
|
||||
#ifdef HAVE_OVERLAY
|
||||
enum overlay_visibility *overlay_visibility;
|
||||
#endif
|
||||
enum resampler_quality audio_driver_resampler_quality;
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
menu_input_pointer_hw_state_t menu_input_pointer_hw_state;
|
||||
@ -1775,6 +1776,7 @@ struct rarch_state
|
||||
char current_savefile_dir[PATH_MAX_LENGTH];
|
||||
char current_savestate_dir[PATH_MAX_LENGTH];
|
||||
char dir_savestate[PATH_MAX_LENGTH];
|
||||
char audio_driver_resampler_ident[64];
|
||||
|
||||
#ifdef HAVE_GFX_WIDGETS
|
||||
bool widgets_active;
|
||||
|
Loading…
x
Reference in New Issue
Block a user