mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 09:40:06 +00:00
(Audio mixer) Ability to individually set volume per stream
This commit is contained in:
parent
01e85b321b
commit
5aeab54ab7
@ -45,6 +45,16 @@
|
||||
|
||||
#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024)
|
||||
|
||||
/**
|
||||
* db_to_gain:
|
||||
* @db : Decibels.
|
||||
*
|
||||
* Converts decibels to voltage gain.
|
||||
*
|
||||
* Returns: voltage gain value.
|
||||
**/
|
||||
#define db_to_gain(db) (powf(10.0f, (db) / 20.0f))
|
||||
|
||||
static const audio_driver_t *audio_drivers[] = {
|
||||
#ifdef HAVE_ALSA
|
||||
&audio_alsa,
|
||||
@ -361,6 +371,12 @@ static bool audio_driver_deinit_internal(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void audio_driver_mixer_init(unsigned out_rate)
|
||||
{
|
||||
audio_mixer_init(out_rate);
|
||||
}
|
||||
|
||||
|
||||
static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
{
|
||||
unsigned new_rate = 0;
|
||||
@ -527,7 +543,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
|
||||
audio_driver_free_samples_count = 0;
|
||||
|
||||
audio_mixer_init(settings->uints.audio_out_rate);
|
||||
audio_driver_mixer_init(settings->uints.audio_out_rate);
|
||||
|
||||
/* Threaded driver is initially stopped. */
|
||||
if (
|
||||
@ -665,7 +681,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
if (audio_mixer_active)
|
||||
{
|
||||
bool override = audio_driver_mixer_mute_enable ? true :
|
||||
(audio_driver_mixer_volume_gain != 0.0f) ? true : false;
|
||||
(audio_driver_mixer_volume_gain != 1.0f) ? true : false;
|
||||
float mixer_gain = !audio_driver_mixer_mute_enable ?
|
||||
audio_driver_mixer_volume_gain : 0.0f;
|
||||
audio_mixer_mix(audio_driver_output_samples_buf,
|
||||
@ -1071,7 +1087,7 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
audio_mixer_stop_cb_t stop_cb = audio_mixer_play_stop_cb;
|
||||
bool looped = false;
|
||||
void *buf = NULL;
|
||||
|
||||
|
||||
if (!audio_driver_mixer_get_free_stream_slot(&free_slot))
|
||||
return false;
|
||||
|
||||
@ -1157,7 +1173,7 @@ static void audio_driver_mixer_play_stream_internal(unsigned i, bool looped)
|
||||
switch (audio_mixer_streams[i].state)
|
||||
{
|
||||
case AUDIO_STREAM_STATE_STOPPED:
|
||||
audio_mixer_streams[i].voice = audio_mixer_play(audio_mixer_streams[i].handle, looped, audio_mixer_streams[i].volume, audio_mixer_streams[i].stop_cb);
|
||||
audio_mixer_streams[i].voice = audio_mixer_play(audio_mixer_streams[i].handle, looped, 1.0f, audio_mixer_streams[i].stop_cb);
|
||||
set_state = true;
|
||||
break;
|
||||
case AUDIO_STREAM_STATE_PLAYING:
|
||||
@ -1180,6 +1196,29 @@ void audio_driver_mixer_play_stream_looped(unsigned i)
|
||||
audio_driver_mixer_play_stream_internal(i, true);
|
||||
}
|
||||
|
||||
float audio_driver_mixer_get_stream_volume(unsigned i)
|
||||
{
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
return 0.0f;
|
||||
|
||||
return audio_mixer_streams[i].volume;
|
||||
}
|
||||
|
||||
void audio_driver_mixer_set_stream_volume(unsigned i, float vol)
|
||||
{
|
||||
audio_mixer_voice_t *voice = NULL;
|
||||
|
||||
if (i >= AUDIO_MIXER_MAX_STREAMS)
|
||||
return;
|
||||
|
||||
audio_mixer_streams[i].volume = vol;
|
||||
|
||||
voice = audio_mixer_streams[i].voice;
|
||||
|
||||
if (voice)
|
||||
audio_mixer_voice_set_volume(voice, db_to_gain(vol));
|
||||
}
|
||||
|
||||
void audio_driver_mixer_stop_stream(unsigned i)
|
||||
{
|
||||
bool set_state = false;
|
||||
@ -1205,6 +1244,7 @@ void audio_driver_mixer_stop_stream(unsigned i)
|
||||
if (voice)
|
||||
audio_mixer_stop(voice);
|
||||
audio_mixer_streams[i].state = AUDIO_STREAM_STATE_STOPPED;
|
||||
audio_mixer_streams[i].volume = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1235,8 +1275,8 @@ void audio_driver_mixer_remove_stream(unsigned i)
|
||||
if (handle)
|
||||
audio_mixer_destroy(handle);
|
||||
audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE;
|
||||
audio_mixer_streams[i].volume = 0.0f;
|
||||
audio_mixer_streams[i].stop_cb = NULL;
|
||||
audio_mixer_streams[i].volume = 0.0f;
|
||||
audio_mixer_streams[i].handle = NULL;
|
||||
audio_mixer_streams[i].voice = NULL;
|
||||
}
|
||||
@ -1452,15 +1492,6 @@ void audio_set_bool(enum audio_action action, bool val)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* db_to_gain:
|
||||
* @db : Decibels.
|
||||
*
|
||||
* Converts decibels to voltage gain.
|
||||
*
|
||||
* Returns: voltage gain value.
|
||||
**/
|
||||
#define db_to_gain(db) (powf(10.0f, (db) / 20.0f))
|
||||
|
||||
void audio_set_float(enum audio_action action, float val)
|
||||
{
|
||||
|
@ -296,6 +296,10 @@ void audio_driver_mixer_play_stream_looped(unsigned i);
|
||||
|
||||
void audio_driver_mixer_stop_stream(unsigned i);
|
||||
|
||||
float audio_driver_mixer_get_stream_volume(unsigned i);
|
||||
|
||||
void audio_driver_mixer_set_stream_volume(unsigned i, float vol);
|
||||
|
||||
void audio_driver_mixer_remove_stream(unsigned i);
|
||||
|
||||
enum resampler_quality audio_driver_get_resampler_quality(void);
|
||||
|
@ -1236,3 +1236,19 @@ void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bo
|
||||
*sample = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float audio_mixer_voice_get_volume(audio_mixer_voice_t *voice)
|
||||
{
|
||||
if (!voice)
|
||||
return 0.0f;
|
||||
|
||||
return voice->volume;
|
||||
}
|
||||
|
||||
void audio_mixer_voice_set_volume(audio_mixer_voice_t *voice, float val)
|
||||
{
|
||||
if (!voice)
|
||||
return;
|
||||
|
||||
voice->volume = val;
|
||||
}
|
||||
|
@ -73,6 +73,10 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound,
|
||||
|
||||
void audio_mixer_stop(audio_mixer_voice_t* voice);
|
||||
|
||||
float audio_mixer_voice_get_volume(audio_mixer_voice_t *voice);
|
||||
|
||||
void audio_mixer_voice_set_volume(audio_mixer_voice_t *voice, float val);
|
||||
|
||||
void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bool override);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
#include "../../input/input_driver.h"
|
||||
|
||||
#include "../../audio/audio_driver.h"
|
||||
#include "../../core.h"
|
||||
#include "../../core_info.h"
|
||||
#include "../../configuration.h"
|
||||
@ -56,6 +57,26 @@
|
||||
|
||||
extern struct key_desc key_descriptors[RARCH_MAX_KEYS];
|
||||
|
||||
static void menu_action_setting_audio_mixer_stream_volume(
|
||||
file_list_t* list,
|
||||
unsigned *w, unsigned type, unsigned i,
|
||||
const char *label,
|
||||
char *s, size_t len,
|
||||
const char *entry_label,
|
||||
const char *path,
|
||||
char *s2, size_t len2)
|
||||
{
|
||||
unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN);
|
||||
|
||||
*w = 19;
|
||||
strlcpy(s2, path, len2);
|
||||
|
||||
if (offset >= AUDIO_MIXER_MAX_STREAMS)
|
||||
return;
|
||||
|
||||
snprintf(s, len, "%.2f dB", audio_driver_mixer_get_stream_volume(offset));
|
||||
}
|
||||
|
||||
static void menu_action_setting_disp_set_label_cheat_num_passes(
|
||||
file_list_t* list,
|
||||
unsigned *w, unsigned type, unsigned i,
|
||||
@ -2094,7 +2115,13 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
|
||||
static int menu_cbs_init_bind_get_string_representation_compare_type(
|
||||
menu_file_list_cbs_t *cbs, unsigned type)
|
||||
{
|
||||
if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN
|
||||
if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN
|
||||
&& type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END)
|
||||
{
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
menu_action_setting_audio_mixer_stream_volume);
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_INPUT_DESC_BEGIN
|
||||
&& type <= MENU_SETTINGS_INPUT_DESC_END)
|
||||
{
|
||||
BIND_ACTION_GET_VALUE(cbs,
|
||||
|
@ -333,6 +333,23 @@ static int shader_action_parameter_left(unsigned type, const char *label, bool w
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int audio_mixer_stream_volume_left(unsigned type, const char *label,
|
||||
bool wraparound)
|
||||
{
|
||||
unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN);
|
||||
float orig_volume = 0.0f;
|
||||
|
||||
if (offset >= AUDIO_MIXER_MAX_STREAMS)
|
||||
return 0;
|
||||
|
||||
orig_volume = audio_driver_mixer_get_stream_volume(offset);
|
||||
orig_volume = orig_volume - 1.00f;
|
||||
|
||||
audio_driver_mixer_set_stream_volume(offset, orig_volume);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_left_cheat(unsigned type, const char *label,
|
||||
bool wraparound)
|
||||
{
|
||||
@ -865,6 +882,11 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs,
|
||||
{
|
||||
BIND_ACTION_LEFT(cbs, action_left_cheat);
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN
|
||||
&& type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END)
|
||||
{
|
||||
BIND_ACTION_LEFT(cbs, audio_mixer_stream_volume_left);
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0
|
||||
&& type <= MENU_SETTINGS_SHADER_PARAMETER_LAST)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "../menu_setting.h"
|
||||
#include "../menu_shader.h"
|
||||
|
||||
#include "../../audio/audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../core.h"
|
||||
#include "../../core_info.h"
|
||||
@ -204,6 +205,24 @@ static int action_right_scroll(unsigned type, const char *label,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int audio_mixer_stream_volume_right(unsigned type, const char *label,
|
||||
bool wraparound)
|
||||
{
|
||||
unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN);
|
||||
float orig_volume = 0.0f;
|
||||
|
||||
if (offset >= AUDIO_MIXER_MAX_STREAMS)
|
||||
return 0;
|
||||
|
||||
orig_volume = audio_driver_mixer_get_stream_volume(offset);
|
||||
orig_volume = orig_volume + 1.00f;
|
||||
|
||||
audio_driver_mixer_set_stream_volume(offset, orig_volume);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int action_right_goto_tab(void)
|
||||
{
|
||||
menu_ctx_list_t list_info;
|
||||
@ -483,6 +502,11 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs,
|
||||
{
|
||||
BIND_ACTION_RIGHT(cbs, action_right_cheat);
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN
|
||||
&& type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END)
|
||||
{
|
||||
BIND_ACTION_RIGHT(cbs, audio_mixer_stream_volume_right);
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_SHADER_PARAMETER_0
|
||||
&& type <= MENU_SETTINGS_SHADER_PARAMETER_LAST)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "../menu_setting.h"
|
||||
#include "../menu_shader.h"
|
||||
|
||||
#include "../../audio/audio_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../core.h"
|
||||
#include "../../core_info.h"
|
||||
@ -49,6 +50,18 @@
|
||||
cbs->action_start_ident = #name;
|
||||
#endif
|
||||
|
||||
static int action_start_audio_mixer_stream_volume(unsigned type, const char *label)
|
||||
{
|
||||
unsigned offset = (type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN);
|
||||
|
||||
if (offset >= AUDIO_MIXER_MAX_STREAMS)
|
||||
return 0;
|
||||
|
||||
audio_driver_mixer_set_stream_volume(offset, 1.0f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_start_remap_file_load(unsigned type, const char *label)
|
||||
{
|
||||
input_remapping_set_defaults(true);
|
||||
@ -369,6 +382,13 @@ int menu_cbs_init_bind_start(menu_file_list_cbs_t *cbs,
|
||||
if (!cbs)
|
||||
return -1;
|
||||
|
||||
if (type >= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN
|
||||
&& type <= MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END)
|
||||
{
|
||||
BIND_ACTION_START(cbs, action_start_audio_mixer_stream_volume);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIND_ACTION_START(cbs, action_start_lookup_setting);
|
||||
|
||||
if (menu_cbs_init_bind_start_compare_label(cbs) == 0)
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "menu_cbs.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
#define DEBUG_LOG
|
||||
#endif
|
||||
|
||||
|
@ -4265,10 +4265,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
|
||||
char lbl_play_looped[128];
|
||||
char lbl_remove[128];
|
||||
char lbl_stop[128];
|
||||
char lbl_volume[128];
|
||||
unsigned id = info->type - MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_BEGIN;
|
||||
|
||||
lbl_remove[0] = lbl_stop[0] = lbl_play[0] = lbl_play_looped[0] = '\0';
|
||||
lbl_volume[0] = '\0';
|
||||
|
||||
snprintf(lbl_volume, sizeof(lbl_volume), "mixer_stream_%d_action_volume", id);
|
||||
snprintf(lbl_stop, sizeof(lbl_stop), "mixer_stream_%d_action_stop", id);
|
||||
snprintf(lbl_remove, sizeof(lbl_remove), "mixer_stream_%d_action_remove", id);
|
||||
snprintf(lbl_play, sizeof(lbl_play), "mixer_stream_%d_action_play", id);
|
||||
@ -4298,6 +4301,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
|
||||
MSG_UNKNOWN,
|
||||
(MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_REMOVE_BEGIN + id),
|
||||
0, 0);
|
||||
menu_entries_append_enum(info->list,
|
||||
"Volume",
|
||||
lbl_volume,
|
||||
MSG_UNKNOWN,
|
||||
(MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + id),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
info->need_push = true;
|
||||
|
@ -201,6 +201,8 @@ enum menu_settings_type
|
||||
MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_BEGIN + 7,
|
||||
MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN,
|
||||
MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_PLAY_LOOPED_BEGIN + 7,
|
||||
MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN,
|
||||
MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_END = MENU_SETTINGS_AUDIO_MIXER_STREAM_ACTIONS_VOLUME_BEGIN + 7,
|
||||
MENU_SETTINGS_BIND_BEGIN,
|
||||
MENU_SETTINGS_BIND_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_ANALOG_RIGHT_Y_MINUS,
|
||||
MENU_SETTINGS_BIND_ALL_LAST = MENU_SETTINGS_BIND_BEGIN + RARCH_MENU_TOGGLE,
|
||||
|
@ -89,7 +89,7 @@ static void task_audio_mixer_handle_upload_ogg(void *task_data,
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
params.volume = 0.0f;
|
||||
params.volume = 1.0f;
|
||||
params.type = AUDIO_MIXER_TYPE_OGG;
|
||||
params.state = AUDIO_STREAM_STATE_PLAYING;
|
||||
params.buf = img->buf;
|
||||
@ -111,7 +111,7 @@ static void task_audio_mixer_handle_upload_flac(void *task_data,
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
params.volume = 0.0f;
|
||||
params.volume = 1.0f;
|
||||
params.type = AUDIO_MIXER_TYPE_FLAC;
|
||||
params.state = AUDIO_STREAM_STATE_PLAYING;
|
||||
params.buf = img->buf;
|
||||
@ -133,7 +133,7 @@ static void task_audio_mixer_handle_upload_mp3(void *task_data,
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
params.volume = 0.0f;
|
||||
params.volume = 1.0f;
|
||||
params.type = AUDIO_MIXER_TYPE_MP3;
|
||||
params.state = AUDIO_STREAM_STATE_PLAYING;
|
||||
params.buf = img->buf;
|
||||
@ -155,7 +155,7 @@ static void task_audio_mixer_handle_upload_mod(void *task_data,
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
params.volume = 0.0f;
|
||||
params.volume = 1.0f;
|
||||
params.type = AUDIO_MIXER_TYPE_MOD;
|
||||
params.state = AUDIO_STREAM_STATE_PLAYING;
|
||||
params.buf = img->buf;
|
||||
@ -177,7 +177,7 @@ static void task_audio_mixer_handle_upload_wav(void *task_data,
|
||||
if (!img)
|
||||
return;
|
||||
|
||||
params.volume = 0.0f;
|
||||
params.volume = 1.0f;
|
||||
params.type = AUDIO_MIXER_TYPE_WAV;
|
||||
params.state = AUDIO_STREAM_STATE_PLAYING;
|
||||
params.buf = img->buf;
|
||||
|
Loading…
x
Reference in New Issue
Block a user