/*****************************************************************************
- * vlc_aout_mixer.h : audio output mixer interface
+ * vlc_aout_volume.h: audio volume module
*****************************************************************************
* Copyright (C) 2002-2009 VLC authors and VideoLAN
* $Id$
extern "C" {
#endif
-typedef struct audio_mixer audio_mixer_t;
+typedef struct audio_volume audio_volume_t;
-/**
- * audio output mixer
+/**
+ * Audio volume
*/
-struct audio_mixer
+struct audio_volume
{
VLC_COMMON_MEMBERS
- module_t *module; /**< Module handle */
vlc_fourcc_t format; /**< Audio samples format */
- void (*mix)(audio_mixer_t *, block_t *, float); /**< Amplifier */
+ void (*amplify)(audio_volume_t *, block_t *, float); /**< Amplifier */
};
-VLC_API audio_mixer_t *aout_MixerNew(vlc_object_t *, vlc_fourcc_t) VLC_USED;
-VLC_API void aout_MixerDelete(audio_mixer_t *);
-VLC_API void aout_MixerRun(audio_mixer_t *, block_t *, float);
-
#ifdef __cplusplus
}
#endif
#include <vlc_common.h>
#include <vlc_aout.h>
-#include <vlc_aout_mixer.h>
+#include <vlc_aout_volume.h>
#include <vlc_filter.h>
+#include <vlc_modules.h>
#include <vlc_plugin.h>
struct filter_sys_t
{
+ audio_volume_t volume;
float f_gain;
- audio_mixer_t* p_mixer;
+ module_t *module;
};
-
/*****************************************************************************
* Module descriptor
*****************************************************************************/
return VLC_EGENERIC;
}
- p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) );
- if( !p_sys )
+ p_sys = vlc_object_create( p_this, sizeof( *p_sys ) );
+ if( unlikely( p_sys == NULL ) )
return VLC_ENOMEM;
- p_sys->p_mixer = aout_MixerNew( p_this, p_filter->fmt_in.audio.i_format );
- if( !p_sys->p_mixer )
+ p_filter->p_sys = p_sys;
+ p_sys->volume.format = p_filter->fmt_in.audio.i_format;
+ p_sys->module = module_need( &p_sys->volume, "audio volume", NULL, false );
+ if( p_sys->module == NULL )
{
msg_Warn( p_filter, "unsupported format" );
- free( p_sys );
+ vlc_object_release( &p_sys->volume );
return VLC_EGENERIC;
}
{
filter_sys_t *p_sys = p_filter->p_sys;
- aout_MixerRun( p_sys->p_mixer, p_block, p_sys->f_gain );
-
+ p_sys->volume.amplify( &p_sys->volume, p_block, p_sys->f_gain );
return p_block;
}
filter_t *p_filter = (filter_t*)p_this;
filter_sys_t *p_sys = p_filter->p_sys;
- aout_MixerDelete( p_sys->p_mixer );
- free( p_sys );
+ module_unneed( &p_sys->volume, p_sys->module );
+ vlc_object_release( &p_sys->volume );
}
/*****************************************************************************
- * float32.c : precise float32 audio mixer implementation
+ * float32.c : precise float32 audio volume implementation
*****************************************************************************
* Copyright (C) 2002 the VideoLAN team
* $Id$
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
-#include <vlc_aout_mixer.h>
+#include <vlc_aout_volume.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Create( vlc_object_t * );
-static void DoWork( audio_mixer_t *, block_t *, float );
+static void DoWork( audio_volume_t *, block_t *, float );
/*****************************************************************************
* Module descriptor
vlc_module_begin ()
set_category( CAT_AUDIO )
set_subcategory( SUBCAT_AUDIO_MISC )
- set_description( N_("Float32 audio mixer") )
- set_capability( "audio mixer", 10 )
+ set_description( N_("Single precision audio volume") )
+ set_capability( "audio volume", 10 )
set_callbacks( Create, NULL )
vlc_module_end ()
*/
static int Create( vlc_object_t *p_this )
{
- audio_mixer_t *p_mixer = (audio_mixer_t *)p_this;
+ audio_volume_t *p_volume = (audio_volume_t *)p_this;
- if (p_mixer->format != VLC_CODEC_FL32)
+ if (p_volume->format != VLC_CODEC_FL32)
return -1;
- p_mixer->mix = DoWork;
+ p_volume->amplify = DoWork;
return 0;
}
/**
* Mixes a new output buffer
*/
-static void DoWork( audio_mixer_t * p_mixer, block_t *p_buffer,
+static void DoWork( audio_volume_t *p_volume, block_t *p_buffer,
float f_multiplier )
{
if( f_multiplier == 1.0 )
for( size_t i = p_buffer->i_buffer / sizeof(float); i > 0; i-- )
*(p++) *= f_multiplier;
- (void) p_mixer;
+ (void) p_volume;
}
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
-#include <vlc_aout_mixer.h>
+#include <vlc_aout_volume.h>
static int Activate (vlc_object_t *);
vlc_module_begin ()
set_category (CAT_AUDIO)
set_subcategory (SUBCAT_AUDIO_MISC)
- set_description (N_("Integer audio mixer"))
- set_capability ("audio mixer", 9)
+ set_description (N_("Integer audio volume"))
+ set_capability ("audio volume", 9)
set_callbacks (Activate, NULL)
vlc_module_end ()
-static void FilterS16N (audio_mixer_t *, block_t *, float);
+static void FilterS16N (audio_volume_t *, block_t *, float);
static int Activate (vlc_object_t *obj)
{
- audio_mixer_t *mixer = (audio_mixer_t *)obj;
+ audio_volume_t *vol = (audio_volume_t *)obj;
- switch (mixer->format)
+ switch (vol->format)
{
case VLC_CODEC_S16N:
- mixer->mix = FilterS16N;
+ vol->amplify = FilterS16N;
break;
default:
return -1;
return 0;
}
-static void FilterS16N (audio_mixer_t *mixer, block_t *block, float volume)
+static void FilterS16N (audio_volume_t *vol, block_t *block, float volume)
{
int32_t mult = volume * 0x1.p16;
}
}
- (void) mixer;
+ (void) vol;
}
src/audio_output/filters.c
src/audio_output/input.c
src/audio_output/intf.c
-src/audio_output/mixer.c
src/audio_output/output.c
src/config/chain.c
src/config/cmdline.c
../include/vlc_access.h \
../include/vlc_aout.h \
../include/vlc_aout_intf.h \
- ../include/vlc_aout_mixer.h \
+ ../include/vlc_aout_volume.h \
../include/vlc_arrays.h \
../include/vlc_art_finder.h \
../include/vlc_atomic.h \
audio_output/dec.c \
audio_output/filters.c \
audio_output/input.c \
- audio_output/mixer.c \
audio_output/output.c \
+ audio_output/volume.c \
audio_output/intf.c \
osd/osd.c \
osd/osd_text.c \
aout_input_t *p_input;
};
+typedef struct aout_volume aout_volume_t;
+
/** an input stream for the audio output */
struct aout_input_t
{
vlc_mutex_t lock;
module_t *module; /**< Output plugin (or NULL if inactive) */
aout_input_t *input;
+ aout_volume_t *volume;
struct
{
date_t date;
} sync;
- struct
- {
- float amp; /**< Software volume amplification */
- bool mute; /**< Software mute */
- struct audio_mixer *mixer; /**< Software volume plugin */
- } volume;
-
- struct
- {
- vlc_atomic_t multiplier;
- audio_replay_gain_t data;
- } gain;
-
audio_sample_format_t mixer_format;
audio_sample_format_t input_format;
filter_t *filters[AOUT_MAX_FILTERS];
int nb_filters;
+ struct
+ {
+ float volume;
+ bool mute;
+ } soft; /* temporary - TODO: move to output plugins */
+
vlc_atomic_t restart;
} aout_owner_t;
void aout_FiltersPlay( filter_t *const *, unsigned, block_t ** );
/* From mixer.c : */
-#define aout_MixerNew(o, f) aout_MixerNew(VLC_OBJECT(o), f)
-
-float aout_ReplayGainSelect(vlc_object_t *, const char *,
- const audio_replay_gain_t *);
-#define aout_ReplayGainSelect(o, s, g) \
- aout_ReplayGainSelect(VLC_OBJECT(o), s, g)
-
-static inline void aout_ReplayGainInit(audio_replay_gain_t *restrict d,
- const audio_replay_gain_t *restrict s)
-{
- if (s != NULL)
- *d = *s;
- else
- memset (d, 0, sizeof (*d));
-}
+aout_volume_t *aout_volume_New(vlc_object_t *, const audio_replay_gain_t *);
+#define aout_volume_New(o, g) aout_volume_New(VLC_OBJECT(o), g)
+int aout_volume_SetFormat(aout_volume_t *, vlc_fourcc_t);
+void aout_volume_SetVolume(aout_volume_t *, float);
+int aout_volume_Amplify(aout_volume_t *, block_t *);
+void aout_volume_Delete(aout_volume_t *);
/* From output.c : */
vlc_mutex_init (&owner->lock);
owner->module = NULL;
owner->input = NULL;
- owner->volume.amp = 1.f;
- owner->volume.mute = false;
- owner->volume.mixer = NULL;
aout->pf_play = aout_DecDeleteBuffer;
aout->volume_set = NULL;
#include <vlc_common.h>
#include <vlc_aout.h>
-#include <vlc_aout_mixer.h>
#include <vlc_input.h>
#include <vlc_atomic.h>
#include "aout_internal.h"
#include "libvlc.h"
-static int ReplayGainCallback (vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void *);
-
/**
* Creates an audio output
*/
owner->input_format = *p_format;
vlc_atomic_set (&owner->restart, 0);
+ owner->volume = aout_volume_New (p_aout, p_replay_gain);
if( aout_OutputNew( p_aout, p_format ) < 0 )
{
ret = -1;
goto error;
}
-
- /* Allocate a software mixer */
- assert (owner->volume.mixer == NULL);
- owner->volume.mixer = aout_MixerNew (p_aout, owner->mixer_format.i_format);
-
- aout_ReplayGainInit (&owner->gain.data, p_replay_gain);
- var_AddCallback (p_aout, "audio-replay-gain-mode",
- ReplayGainCallback, owner);
- var_TriggerCallback (p_aout, "audio-replay-gain-mode");
+ aout_volume_SetFormat (owner->volume, owner->mixer_format.i_format);
/* Create the audio filtering "input" pipeline */
date_Init (&owner->sync.date, owner->mixer_format.i_rate, 1);
p_request_vout);
if (owner->input == NULL)
{
- struct audio_mixer *mixer = owner->volume.mixer;
-
- owner->volume.mixer = NULL;
aout_OutputDelete (p_aout);
+ aout_volume_Delete (owner->volume);
aout_unlock (p_aout);
- aout_MixerDelete (mixer);
return -1;
}
error:
{
aout_owner_t *owner = aout_owner (p_aout);
aout_input_t *input;
- struct audio_mixer *mixer;
aout_lock( p_aout );
/* Remove the input. */
aout_InputDelete (p_aout, input);
owner->input = NULL;
- mixer = owner->volume.mixer;
- owner->volume.mixer = NULL;
-
- var_DelCallback (p_aout, "audio-replay-gain-mode",
- ReplayGainCallback, owner);
-
aout_OutputDelete( p_aout );
+ aout_volume_Delete (owner->volume);
var_Destroy( p_aout, "audio-device" );
var_Destroy( p_aout, "audio-channels" );
aout_unlock( p_aout );
-
- aout_MixerDelete (mixer);
free (input);
}
/* Reinitializes the output */
if (restart & AOUT_RESTART_OUTPUT)
{
- aout_MixerDelete (owner->volume.mixer);
- owner->volume.mixer = NULL;
aout_OutputDelete (aout);
-
if (aout_OutputNew (aout, &owner->input_format))
+ {
+ aout_volume_Delete (owner->volume);
return; /* we are officially screwed */
- owner->volume.mixer = aout_MixerNew (aout,
- owner->mixer_format.i_format);
+ }
+ aout_volume_SetFormat (owner->volume, owner->mixer_format.i_format);
}
owner->input = aout_InputNew (aout, &owner->input_format,
date_Increment (&owner->sync.date, p_buffer->i_nb_samples);
/* Mixer */
- if (owner->volume.mixer != NULL)
- {
- float amp = 0.f;
- if (!owner->volume.mute)
- amp = owner->volume.amp
- * vlc_atomic_getf (&owner->gain.multiplier);
- aout_MixerRun (owner->volume.mixer, p_buffer, amp);
- }
+ aout_volume_Amplify (owner->volume, p_buffer);
/* Output */
aout_OutputPlay( p_aout, p_buffer );
aout_unlock (aout);
return empty;
}
-
-static int ReplayGainCallback (vlc_object_t *obj, char const *var,
- vlc_value_t oldval, vlc_value_t val, void *data)
-{
- aout_owner_t *owner = data;
- float multiplier = aout_ReplayGainSelect (obj, val.psz_string,
- &owner->gain.data);
- vlc_atomic_setf (&owner->gain.multiplier, multiplier);
- VLC_UNUSED(var); VLC_UNUSED(oldval);
- return VLC_SUCCESS;
-}
+++ /dev/null
-/*****************************************************************************
- * mixer.c : audio output volume operations
- *****************************************************************************
- * Copyright (C) 2002-2004 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Christophe Massiot <massiot@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stddef.h>
-#include <math.h>
-
-#include <vlc_common.h>
-#include <libvlc.h>
-#include <vlc_modules.h>
-#include <vlc_aout.h>
-#include <vlc_aout_mixer.h>
-#include "aout_internal.h"
-
-/* Note: Once upon a time, the audio output volume module was also responsible
- * for mixing multiple audio inputs together. Hence it was called mixer.
- * Nowadays, there is only ever a single input per module instance, so this has
- * become a misnomer. */
-
-typedef struct aout_volume
-{
- audio_mixer_t volume;
-} aout_volume_t;
-
-static inline aout_volume_t *vol_priv(audio_mixer_t *volume)
-{
- return (aout_volume_t *)volume;
-}
-
-#undef aout_MixerNew
-/**
- * Creates a software amplifier.
- */
-audio_mixer_t *aout_MixerNew(vlc_object_t *obj, vlc_fourcc_t format)
-{
- audio_mixer_t *mixer = vlc_custom_create(obj, sizeof (aout_volume_t),
- "volume");
- if (unlikely(mixer == NULL))
- return NULL;
-
- mixer->format = format;
- mixer->mix = NULL;
- mixer->module = module_need(mixer, "audio mixer", NULL, false);
- if (mixer->module == NULL)
- {
- vlc_object_release(mixer);
- mixer = NULL;
- }
- return mixer;
-}
-
-/**
- * Destroys a software amplifier.
- */
-void aout_MixerDelete(audio_mixer_t *mixer)
-{
- if (mixer == NULL)
- return;
-
- module_unneed(mixer, mixer->module);
- vlc_object_release(mixer);
-}
-
-/**
- * Applies replay gain and software volume to an audio buffer.
- */
-void aout_MixerRun(audio_mixer_t *mixer, block_t *block, float amp)
-{
- mixer->mix(mixer, block, amp);
-}
-
-/*** Replay gain ***/
-float (aout_ReplayGainSelect)(vlc_object_t *obj, const char *str,
- const audio_replay_gain_t *replay_gain)
-{
- float gain = 0.;
- unsigned mode = AUDIO_REPLAY_GAIN_MAX;
-
- if (likely(str != NULL))
- { /* Find selectrf mode */
- if (!strcmp (str, "track"))
- mode = AUDIO_REPLAY_GAIN_TRACK;
- else
- if (!strcmp (str, "album"))
- mode = AUDIO_REPLAY_GAIN_ALBUM;
-
- /* If the selectrf mode is not available, prefer the other one */
- if (mode != AUDIO_REPLAY_GAIN_MAX && !replay_gain->pb_gain[mode])
- {
- if (replay_gain->pb_gain[!mode])
- mode = !mode;
- }
- }
-
- /* */
- if (mode == AUDIO_REPLAY_GAIN_MAX)
- return 1.;
-
- if (replay_gain->pb_gain[mode])
- gain = replay_gain->pf_gain[mode]
- + var_InheritFloat (obj, "audio-replay-gain-preamp");
- else
- gain = var_InheritFloat (obj, "audio-replay-gain-default");
-
- float multiplier = pow (10., gain / 20.);
-
- if (replay_gain->pb_peak[mode]
- && var_InheritBool (obj, "audio-replay-gain-peak-protection")
- && replay_gain->pf_peak[mode] * multiplier > 1.0)
- multiplier = 1.0f / replay_gain->pf_peak[mode];
-
- return multiplier;
-}
aout->volume_set = NULL;
aout->mute_set = NULL;
owner->module = NULL;
- owner->volume.amp = 1.f;
- owner->volume.mute = false;
aout_FiltersDestroyPipeline (owner->filters, owner->nb_filters);
}
* This provides a good tradeoff between low and high volume ranges.
*
* This code is only used for the VLC software mixer. If you change this
- * formula, be sure to update the aout_VolumeHardInit()-based plugins also.
+ * formula, be sure to update the volume-capable plugins also.
*/
- owner->volume.amp = volume * volume * volume;
aout_VolumeReport (aout, volume);
+ volume = volume * volume * volume;
+ owner->soft.volume = volume;
+ aout_volume_SetVolume(owner->volume, owner->soft.mute ? 0.f : volume);
return 0;
}
aout_owner_t *owner = aout_owner (aout);
aout_assert_locked (aout);
- owner->volume.mute = mute;
aout_MuteReport (aout, mute);
+ owner->soft.mute = mute;
+ aout_volume_SetVolume(owner->volume, mute ? 0.f : owner->soft.volume);
return 0;
}
*/
void aout_VolumeSoftInit (audio_output_t *aout)
{
+ aout_owner_t *owner = aout_owner (aout);
long volume = var_GetInteger (aout, "volume");
bool mute = var_GetBool (aout, "mute");
aout_assert_locked (aout);
+ /* volume depends on mute and vice versa... bootstrapping mute is easier */
+ owner->soft.mute = mute;
aout->volume_set = aout_SoftVolumeSet;
aout->mute_set = aout_SoftMuteSet;
aout_SoftVolumeSet (aout, volume / (float)AOUT_VOLUME_DEFAULT);
- aout_SoftMuteSet (aout, mute);
+ aout_MuteReport (aout, mute);
}
--- /dev/null
+/*****************************************************************************
+ * volume.c : audio output volume operations
+ *****************************************************************************
+ * Copyright (C) 2002-2004 VLC authors and VideoLAN
+ * Copyright (C) 2011-2012 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stddef.h>
+#include <math.h>
+
+#include <vlc_common.h>
+#include <libvlc.h>
+#include <vlc_modules.h>
+#include <vlc_aout.h>
+#include <vlc_aout_volume.h>
+#include "aout_internal.h"
+
+struct aout_volume
+{
+ audio_volume_t object;
+ audio_replay_gain_t replay_gain;
+ vlc_atomic_t gain_factor;
+ float output_factor;
+ module_t *module;
+};
+
+static int ReplayGainCallback (vlc_object_t *, char const *,
+ vlc_value_t, vlc_value_t, void *);
+
+#undef aout_volume_New
+/**
+ * Creates a software amplifier.
+ */
+aout_volume_t *aout_volume_New(vlc_object_t *parent,
+ const audio_replay_gain_t *gain)
+{
+ aout_volume_t *vol = vlc_custom_create(parent, sizeof (aout_volume_t),
+ "volume");
+ if (unlikely(vol == NULL))
+ return NULL;
+ vol->module = NULL;
+ vol->output_factor = 1.f;
+
+ //audio_volume_t *obj = &vol->object;
+
+ /* Gain */
+ if (gain != NULL)
+ memcpy(&vol->replay_gain, gain, sizeof (vol->replay_gain));
+ else
+ memset(&vol->replay_gain, 0, sizeof (vol->replay_gain));
+
+ var_AddCallback(parent, "audio-replay-gain-mode",
+ ReplayGainCallback, vol);
+ var_TriggerCallback(parent, "audio-replay-gain-mode");
+
+ return vol;
+}
+
+/**
+ * Selects the current sample format for software amplification.
+ */
+int aout_volume_SetFormat(aout_volume_t *vol, vlc_fourcc_t format)
+{
+ if (unlikely(vol == NULL))
+ return -1;
+
+ audio_volume_t *obj = &vol->object;
+ if (vol->module != NULL)
+ {
+ if (obj->format == format)
+ {
+ msg_Dbg (obj, "retaining sample format");
+ return 0;
+ }
+ msg_Dbg (obj, "changing sample format");
+ module_unneed(obj, vol->module);
+ }
+
+ obj->format = format;
+ vol->module = module_need(obj, "audio volume", NULL, false);
+ if (vol->module == NULL)
+ return -1;
+ return 0;
+}
+
+/**
+ * Destroys a software amplifier.
+ */
+void aout_volume_Delete(aout_volume_t *vol)
+{
+ if (vol == NULL)
+ return;
+
+ audio_volume_t *obj = &vol->object;
+
+ if (vol->module != NULL)
+ module_unneed(obj, vol->module);
+ var_DelCallback(obj->p_parent, "audio-replay-gain-mode",
+ ReplayGainCallback, vol);
+ vlc_object_release(obj);
+}
+
+void aout_volume_SetVolume(aout_volume_t *vol, float factor)
+{
+ if (unlikely(vol == NULL))
+ return;
+
+ vol->output_factor = factor;
+}
+
+/**
+ * Applies replay gain and software volume to an audio buffer.
+ */
+int aout_volume_Amplify(aout_volume_t *vol, block_t *block)
+{
+ if (unlikely(vol == NULL) || vol->module == NULL)
+ return -1;
+
+ float amp = vol->output_factor
+ * vlc_atomic_getf (&vol->gain_factor);
+
+ vol->object.amplify(&vol->object, block, amp);
+ return 0;
+}
+
+/*** Replay gain ***/
+static float aout_ReplayGainSelect(vlc_object_t *obj, const char *str,
+ const audio_replay_gain_t *replay_gain)
+{
+ float gain = 0.;
+ unsigned mode = AUDIO_REPLAY_GAIN_MAX;
+
+ if (likely(str != NULL))
+ { /* Find selectrf mode */
+ if (!strcmp (str, "track"))
+ mode = AUDIO_REPLAY_GAIN_TRACK;
+ else
+ if (!strcmp (str, "album"))
+ mode = AUDIO_REPLAY_GAIN_ALBUM;
+
+ /* If the selectrf mode is not available, prefer the other one */
+ if (mode != AUDIO_REPLAY_GAIN_MAX && !replay_gain->pb_gain[mode])
+ {
+ if (replay_gain->pb_gain[!mode])
+ mode = !mode;
+ }
+ }
+
+ /* */
+ if (mode == AUDIO_REPLAY_GAIN_MAX)
+ return 1.;
+
+ if (replay_gain->pb_gain[mode])
+ gain = replay_gain->pf_gain[mode]
+ + var_InheritFloat (obj, "audio-replay-gain-preamp");
+ else
+ gain = var_InheritFloat (obj, "audio-replay-gain-default");
+
+ float multiplier = pow (10., gain / 20.);
+
+ if (replay_gain->pb_peak[mode]
+ && var_InheritBool (obj, "audio-replay-gain-peak-protection")
+ && replay_gain->pf_peak[mode] * multiplier > 1.0)
+ multiplier = 1.0f / replay_gain->pf_peak[mode];
+
+ return multiplier;
+}
+
+static int ReplayGainCallback (vlc_object_t *obj, char const *var,
+ vlc_value_t oldval, vlc_value_t val, void *data)
+{
+ aout_volume_t *vol = data;
+ float multiplier = aout_ReplayGainSelect(obj, val.psz_string,
+ &vol->replay_gain);
+ vlc_atomic_setf (&vol->gain_factor, multiplier);
+ VLC_UNUSED(var); VLC_UNUSED(oldval);
+ return VLC_SUCCESS;
+}
aout_FormatPrepare
aout_FormatPrint
aout_FormatPrintChannels
-aout_MixerDelete
-aout_MixerNew
-aout_MixerRun
aout_VolumeGet
aout_VolumeSet
aout_VolumeUp