Browse Source

meta: case-insensitive replay gain tag parsing

pull/177/head
Robert Stone 1 year ago
committed by Steve Lhomme
parent
commit
14247db3e6
  1. 1
      include/meson.build
  2. 21
      include/vlc_es.h
  3. 166
      include/vlc_replay_gain.h
  4. 2
      src/Makefile.am
  5. 56
      src/audio_output/volume.c
  6. 33
      src/input/decoder.c
  7. 17
      src/input/es_out.c
  8. 4
      src/input/input_internal.h
  9. 36
      src/input/meta.c
  10. 199
      src/input/replay_gain.c
  11. 6
      src/input/test/es_out.c
  12. 1
      src/libvlccore.sym
  13. 1
      src/meson.build

1
include/meson.build

@ -92,6 +92,7 @@ install_headers(
'vlc_probe.h',
'vlc_rand.h',
'vlc_renderer_discovery.h',
'vlc_replay_gain.h',
'vlc_services_discovery.h',
'vlc_sort.h',
'vlc_sout.h',

21
include/vlc_es.h

@ -26,6 +26,7 @@
#include <vlc_common.h>
#include <vlc_fourcc.h>
#include <vlc_viewpoint.h>
#include <vlc_replay_gain.h>
/**
* \file
@ -46,26 +47,6 @@ struct video_palette_t
uint8_t palette[VIDEO_PALETTE_COLORS_MAX][4]; /**< 4-byte RGBA/YUVA palette */
};
/**
* audio replay gain description
*/
#define AUDIO_REPLAY_GAIN_MAX (2)
#define AUDIO_REPLAY_GAIN_TRACK (0)
#define AUDIO_REPLAY_GAIN_ALBUM (1)
typedef struct
{
/* true if we have the peak value */
bool pb_peak[AUDIO_REPLAY_GAIN_MAX];
/* peak value where 1.0 means full sample value */
float pf_peak[AUDIO_REPLAY_GAIN_MAX];
/* true if we have the gain value */
bool pb_gain[AUDIO_REPLAY_GAIN_MAX];
/* gain value in dB */
float pf_gain[AUDIO_REPLAY_GAIN_MAX];
} audio_replay_gain_t;
/**
* Audio channel type
*/

166
include/vlc_replay_gain.h

@ -0,0 +1,166 @@
/*****************************************************************************
* vlc_replay_gain.h : common replay gain code
*****************************************************************************
* Copyright © 2002-2004 VLC authors and VideoLAN
* Copyright © 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.
*****************************************************************************/
#ifndef VLC_REPLAY_GAIN_H
#define VLC_REPLAY_GAIN_H 1
#include <vlc_common.h>
/**
* \file vlc_replay_gain.h
* \defgroup replay_gain Replay Gain
* \ingroup input
* Functions to read replay gain tags.
*
* @{
*/
/** Index for track values */
#define AUDIO_REPLAY_GAIN_TRACK (0)
/** Index for album values */
#define AUDIO_REPLAY_GAIN_ALBUM (1)
/** Number of replay gain types */
#define AUDIO_REPLAY_GAIN_MAX (2)
/**
* Audio replay gain
*/
typedef struct
{
bool pb_reference_loudness; /**< true if we have the reference loudness */
float pf_reference_loudness; /**< reference loudness in LUFS */
bool pb_gain[AUDIO_REPLAY_GAIN_MAX]; /**< true if we have the gain value */
float pf_gain[AUDIO_REPLAY_GAIN_MAX]; /**< gain value in dB */
bool pb_peak[AUDIO_REPLAY_GAIN_MAX]; /**< true if we have the peak value */
float pf_peak[AUDIO_REPLAY_GAIN_MAX]; /**< peak value where 1.0 means full sample value */
} audio_replay_gain_t;
/**
* Extracts replay gain info from metadata and copies it into a replay gain structure.
* Supports both capitalized and lowercase metadata tags.
*
* \param p_dst Destination replay gain structure to fill
* \param p_meta Metadata structure to extract values from
* \return VLC_SUCCESS if either an album or track gain was found,
* VLC_EGENERIC if no gain was found,
* VLC_EINVAL if either argument is null
*/
VLC_API int vlc_replay_gain_CopyFromMeta( audio_replay_gain_t *p_dst, const vlc_meta_t *p_meta );
/**
* Calculates the replay gain multiplier according to the Replay Gain 2.0 Specification.
* User preferences control mode, pre-amp, default gain, and peak protection.
*
* \param obj calling vlc object
* \param p_rg replay gain structure
* \return linear gain multiplier
*/
float replay_gain_CalcMultiplier( vlc_object_t *obj, const audio_replay_gain_t *p_rg );
/**
* Merges replay gain structures
*
* Only copies gain/peak/reference loudness values that are:
* - Set in the source
* - Not set in the destination
*
* \param p_dst Destination replay gain structure
* \param p_src Source replay gain structure
*/
static inline void replay_gain_Merge( audio_replay_gain_t *p_dst, const audio_replay_gain_t *p_src )
{
if( !p_dst || !p_src )
return;
if( !p_dst->pb_reference_loudness && p_src->pb_reference_loudness )
{
p_dst->pb_reference_loudness = p_src->pb_reference_loudness;
p_dst->pf_reference_loudness = p_src->pf_reference_loudness;
}
for( size_t i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
{
if( !p_dst->pb_gain[i] && p_src->pb_gain[i] )
{
p_dst->pb_gain[i] = p_src->pb_gain[i];
p_dst->pf_gain[i] = p_src->pf_gain[i];
}
if( !p_dst->pb_peak[i] && p_src->pb_peak[i] )
{
p_dst->pb_peak[i] = p_src->pb_peak[i];
p_dst->pf_peak[i] = p_src->pf_peak[i];
}
}
}
/**
* Compares two replay gain structures
*
* \param p_a First replay gain structure
* \param p_b Second replay gain structure
* \return true if any gain/peak/reference loudness values or their validity flags differ
*/
static inline bool replay_gain_Compare( const audio_replay_gain_t *p_a, const audio_replay_gain_t *p_b )
{
if( !p_a || !p_b )
return true;
if( p_a->pb_reference_loudness != p_b->pb_reference_loudness ||
p_a->pf_reference_loudness != p_b->pf_reference_loudness )
return true;
for( size_t i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
{
if( p_a->pb_gain[i] != p_b->pb_gain[i] ||
p_a->pb_peak[i] != p_b->pb_peak[i] )
return true;
if( ( p_a->pb_gain[i] && p_a->pf_gain[i] != p_b->pf_gain[i] ) ||
( p_a->pb_peak[i] && p_a->pf_peak[i] != p_b->pf_peak[i] ) )
return true;
}
return false;
}
/**
* Reset replay gain structure values
*
* \param p_dst Replay gain structure
*/
static inline void replay_gain_Reset( audio_replay_gain_t *p_rg )
{
if( !p_rg )
return;
p_rg->pb_reference_loudness = false;
p_rg->pf_reference_loudness = 0.f;
for( size_t i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
{
p_rg->pb_gain[i] = false;
p_rg->pf_gain[i] = 0.f;
p_rg->pb_peak[i] = false;
p_rg->pf_peak[i] = 0.f;
}
}
/** @} */
#endif

2
src/Makefile.am

@ -97,6 +97,7 @@ pluginsinclude_HEADERS.h = \
../include/vlc_queue.h \
../include/vlc_rand.h \
../include/vlc_renderer_discovery.h \
../include/vlc_replay_gain.h \
../include/vlc_services_discovery.h \
../include/vlc_sort.h \
../include/vlc_sout.h \
@ -290,6 +291,7 @@ libvlccore_la_SOURCES = \
input/meta.c \
input/attachment.c \
input/parse.c \
input/replay_gain.c \
player/player.c \
player/player.h \
player/input.c \

56
src/audio_output/volume.c

@ -32,6 +32,7 @@
#include <vlc_modules.h>
#include <vlc_aout.h>
#include <vlc_aout_volume.h>
#include <vlc_replay_gain.h>
#include "aout_internal.h"
struct aout_volume
@ -134,63 +135,12 @@ int aout_volume_Amplify(aout_volume_t *vol, block_t *block)
return 0;
}
/*** Replay gain ***/
static float aout_ReplayGainSelect(vlc_object_t *obj, const char *str,
const audio_replay_gain_t *replay_gain)
{
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;
}
/* */
float multiplier;
if (mode == AUDIO_REPLAY_GAIN_MAX)
{
multiplier = 1.f;
}
else
{
float gain;
/* If the selectrf mode is not available, prefer the other one */
if (!replay_gain->pb_gain[mode] && replay_gain->pb_gain[!mode])
mode = !mode;
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");
multiplier = powf (10.f, gain / 20.f);
if (var_InheritBool (obj, "audio-replay-gain-peak-protection"))
multiplier = fminf (multiplier, replay_gain->pb_peak[mode]
? 1.f / replay_gain->pf_peak[mode]
: 1.f);
}
/* Command line / configuration gain */
multiplier *= var_InheritFloat (obj, "gain");
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);
float multiplier = replay_gain_CalcMultiplier(obj, &vol->replay_gain);
atomic_store_explicit(&vol->gain_factor, multiplier, memory_order_relaxed);
VLC_UNUSED(var); VLC_UNUSED(oldval);
VLC_UNUSED(var); VLC_UNUSED(oldval); VLC_UNUSED(val);
return VLC_SUCCESS;
}

33
src/input/decoder.c

@ -45,6 +45,7 @@
#include <vlc_picture_pool.h>
#include <vlc_tracer.h>
#include <vlc_list.h>
#include <vlc_replay_gain.h>
#include "audio_output/aout_internal.h"
#include "stream_output/stream_output.h"
@ -495,20 +496,6 @@ static void MouseEvent( const vlc_mouse_t *newmouse, void *user_data )
/*****************************************************************************
* Buffers allocation callbacks for the decoders
*****************************************************************************/
static bool aout_replaygain_changed( const audio_replay_gain_t *a,
const audio_replay_gain_t *b )
{
for( size_t i=0; i<AUDIO_REPLAY_GAIN_MAX; i++ )
{
if( a->pb_gain[i] != b->pb_gain[i] ||
a->pb_peak[i] != b->pb_peak[i] ||
(a->pb_gain[i] && a->pf_gain[i] != b->pf_gain[i]) ||
(a->pb_peak[i] && a->pf_peak[i] != b->pf_peak[i]) )
return true;
}
return false;
}
static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
{
vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
@ -532,8 +519,8 @@ static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
}
/* Check if only replay gain has changed */
if( aout_replaygain_changed( &p_dec->fmt_in->audio_replay_gain,
&p_owner->fmt.audio_replay_gain ) )
if( replay_gain_Compare( &p_dec->fmt_in->audio_replay_gain,
&p_owner->fmt.audio_replay_gain ) )
{
p_dec->fmt_out.audio_replay_gain = p_dec->fmt_in->audio_replay_gain;
if( p_owner->p_aout )
@ -2065,19 +2052,7 @@ CreateDecoder( vlc_object_t *p_parent, const struct vlc_input_decoder_cfg *cfg )
/* Copy ourself the input replay gain */
if( fmt->i_cat == AUDIO_ES )
{
for( unsigned i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
{
if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
{
p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
}
if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
{
p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
}
}
replay_gain_Merge( &p_dec->fmt_out.audio_replay_gain, &fmt->audio_replay_gain );
}
/* */

17
src/input/es_out.c

@ -44,6 +44,7 @@
#include <vlc_decoder.h>
#include <vlc_memstream.h>
#include <vlc_tracer.h>
#include <vlc_replay_gain.h>
#include "input_internal.h"
#include "./source.h"
@ -2037,22 +2038,10 @@ static void EsOutFillEsFmt(es_out_sys_t *p_sys, es_format_t *fmt)
audio_replay_gain_t rg;
memset( &rg, 0, sizeof(rg) );
vlc_mutex_lock( &input_priv(p_input)->p_item->lock );
vlc_audio_replay_gain_MergeFromMeta( &rg, input_priv(p_input)->p_item->p_meta );
vlc_replay_gain_CopyFromMeta( &rg, input_priv(p_input)->p_item->p_meta );
vlc_mutex_unlock( &input_priv(p_input)->p_item->lock );
replay_gain_Merge( &fmt->audio_replay_gain, &rg );
for( int i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
{
if( !fmt->audio_replay_gain.pb_peak[i] )
{
fmt->audio_replay_gain.pb_peak[i] = rg.pb_peak[i];
fmt->audio_replay_gain.pf_peak[i] = rg.pf_peak[i];
}
if( !fmt->audio_replay_gain.pb_gain[i] )
{
fmt->audio_replay_gain.pb_gain[i] = rg.pb_gain[i];
fmt->audio_replay_gain.pf_gain[i] = rg.pf_gain[i];
}
}
break;
}

4
src/input/input_internal.h

@ -707,10 +707,6 @@ void vlc_object_InitInputConfig(vlc_object_t *obj,
int subtitles_Detect( input_thread_t *, char *, const char *, input_item_slave_t ***, int * );
int subtitles_Filter( const char *);
/* meta.c */
void vlc_audio_replay_gain_MergeFromMeta( audio_replay_gain_t *p_dst,
const vlc_meta_t *p_meta );
/* stats.c */
typedef struct input_rate_t
{

36
src/input/meta.c

@ -320,39 +320,3 @@ error:
vlc_object_delete(p_export);
return VLC_EGENERIC;
}
void vlc_audio_replay_gain_MergeFromMeta( audio_replay_gain_t *p_dst,
const vlc_meta_t *p_meta )
{
const char * psz_value;
if( !p_meta )
return;
if( (psz_value = vlc_meta_GetExtra(p_meta, "REPLAYGAIN_TRACK_GAIN")) ||
(psz_value = vlc_meta_GetExtra(p_meta, "RG_RADIO")) )
{
p_dst->pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
p_dst->pf_gain[AUDIO_REPLAY_GAIN_TRACK] = vlc_atof_c( psz_value );
}
if( (psz_value = vlc_meta_GetExtra(p_meta, "REPLAYGAIN_TRACK_PEAK" )) ||
(psz_value = vlc_meta_GetExtra(p_meta, "RG_PEAK" )) )
{
p_dst->pb_peak[AUDIO_REPLAY_GAIN_TRACK] = true;
p_dst->pf_peak[AUDIO_REPLAY_GAIN_TRACK] = vlc_atof_c( psz_value );
}
if( (psz_value = vlc_meta_GetExtra(p_meta, "REPLAYGAIN_ALBUM_GAIN" )) ||
(psz_value = vlc_meta_GetExtra(p_meta, "RG_AUDIOPHILE" )) )
{
p_dst->pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
p_dst->pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = vlc_atof_c( psz_value );
}
if( (psz_value = vlc_meta_GetExtra(p_meta, "REPLAYGAIN_ALBUM_PEAK" )) )
{
p_dst->pb_peak[AUDIO_REPLAY_GAIN_ALBUM] = true;
p_dst->pf_peak[AUDIO_REPLAY_GAIN_ALBUM] = vlc_atof_c( psz_value );
}
}

199
src/input/replay_gain.c

@ -0,0 +1,199 @@
/*****************************************************************************
* replay_gain.c : common replay gain code
*****************************************************************************
* Copyright © 2002-2004 VLC authors and VideoLAN
* Copyright © 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 <math.h>
#include <vlc_replay_gain.h>
#include <vlc_meta.h>
#include <vlc_charset.h>
#include <vlc_variables.h>
int vlc_replay_gain_CopyFromMeta( audio_replay_gain_t *p_dst, const vlc_meta_t *p_meta )
{
if( !p_dst || !p_meta )
return VLC_EINVAL;
/* replay gain presence flags */
enum audio_replay_gain_flags {
TRACK_GAIN = 0x01,
TRACK_PEAK = 0x02,
ALBUM_GAIN = 0x04,
ALBUM_PEAK = 0x08,
FLAGS_MASK = 0x0F,
GAINS_MASK = TRACK_GAIN | ALBUM_GAIN,
};
static const struct {
int mode;
enum audio_replay_gain_flags flag;
const char *tags[2];
} rg_meta[4] = {
{ AUDIO_REPLAY_GAIN_TRACK, TRACK_GAIN,
{ "REPLAYGAIN_TRACK_GAIN", "replaygain_track_gain" }
},
{ AUDIO_REPLAY_GAIN_TRACK, TRACK_PEAK,
{ "REPLAYGAIN_TRACK_PEAK", "replaygain_track_peak" }
},
{ AUDIO_REPLAY_GAIN_ALBUM, ALBUM_GAIN,
{ "REPLAYGAIN_ALBUM_GAIN", "replaygain_album_gain" }
},
{ AUDIO_REPLAY_GAIN_ALBUM, ALBUM_PEAK,
{ "REPLAYGAIN_ALBUM_PEAK", "replaygain_album_peak" }
}
};
enum audio_replay_gain_flags found = 0;
for( size_t i = 0; i < ARRAY_SIZE( rg_meta ) && found != FLAGS_MASK; i++ )
{
if( found & rg_meta[i].flag )
continue;
for( size_t j = 0; j < ARRAY_SIZE( rg_meta[i].tags ); j++ )
{
const char *psz_meta = vlc_meta_GetExtra( p_meta, rg_meta[i].tags[j] );
if( psz_meta )
{
float f_value = vlc_strtof_c( psz_meta, NULL );
if( rg_meta[i].flag & GAINS_MASK )
{
p_dst->pb_gain[rg_meta[i].mode] = true;
p_dst->pf_gain[rg_meta[i].mode] = f_value;
}
else
{
p_dst->pb_peak[rg_meta[i].mode] = true;
p_dst->pf_peak[rg_meta[i].mode] = f_value;
}
found |= rg_meta[i].flag;
break;
}
}
}
static const char *rg_loudness[2] = {
"REPLAYGAIN_REFERENCE_LOUDNESS",
"replaygain_reference_loudness"
};
/* Only look for reference loudness if a track or album gain was found */
for( size_t i = 0; i < ARRAY_SIZE( rg_loudness ) && ( found & GAINS_MASK ); i++ )
{
const char *psz_meta = vlc_meta_GetExtra( p_meta, rg_loudness[i] );
if( psz_meta )
{
p_dst->pb_reference_loudness = true;
p_dst->pf_reference_loudness = vlc_strtof_c( psz_meta, NULL );
break;
}
}
/* Success if either a track or album gain was found. Peak defaults to 1.0 when absent */
return ( found & GAINS_MASK ) ? VLC_SUCCESS : VLC_EGENERIC;
}
float replay_gain_CalcMultiplier( vlc_object_t *p_obj, const audio_replay_gain_t *p_rg )
{
unsigned mode = AUDIO_REPLAY_GAIN_MAX;
char *psz_mode = var_InheritString( p_obj, "audio-replay-gain-mode" );
if( likely(psz_mode != NULL) )
{ /* Find selected mode */
if (!strcmp (psz_mode, "track"))
mode = AUDIO_REPLAY_GAIN_TRACK;
else if( !strcmp( psz_mode, "album" ) )
mode = AUDIO_REPLAY_GAIN_ALBUM;
free( psz_mode );
}
/* Command line / configuration gain */
const float config_gain = var_InheritFloat( p_obj, "gain" );
if( mode == AUDIO_REPLAY_GAIN_MAX )
return config_gain;
const float preamp_gain = var_InheritFloat( p_obj, "audio-replay-gain-preamp" );
const float default_gain = var_InheritFloat( p_obj, "audio-replay-gain-default" );
const bool peak_protection = var_InheritBool( p_obj, "audio-replay-gain-peak-protection" );
/* If the selected mode is not available, prefer the other one */
if( !p_rg->pb_gain[mode] && p_rg->pb_gain[!mode] )
mode = !mode;
float gain;
if( p_rg->pb_gain[mode] )
{
/* replay gain uses -18 LUFS as the reference level */
const float rg_ref_lufs = -18.f;
float rg_ref_lufs_delta = 0.f;
if( p_rg->pb_reference_loudness )
rg_ref_lufs_delta = rg_ref_lufs - p_rg->pf_reference_loudness;
gain = p_rg->pf_gain[mode] + preamp_gain + rg_ref_lufs_delta;
msg_Dbg( p_obj, "replay gain: mode %s, gain %.2f dB, pre-amp %.2f dB, reference loudness %.2f LUFS",
mode ? "album" : "track",
p_rg->pf_gain[mode],
preamp_gain,
rg_ref_lufs - rg_ref_lufs_delta );
}
else
{
gain = default_gain;
msg_Dbg( p_obj, "replay gain: mode default, gain %.2f dB", gain );
}
float multiplier = powf( 10.f, gain / 20.f );
/* Skip peak protection for default gain case, as the default peak value of 1.0 would limit gains greater than 0 dB */
if( p_rg->pb_gain[mode] && peak_protection )
{
/* Use peak of 1.0 if peak value is missing or invalid */
float peak = p_rg->pb_peak[mode] && p_rg->pf_peak[mode] > 0.f ? p_rg->pf_peak[mode] : 1.f;
float peak_limit = 1.f / peak;
/* To avoid clipping, max gain multiplier must be <= 1.0 / peak
* e.g.: peak of 0.5 -> max gain +6.02 dB (can double)
* e.g.: peak of 1.0 -> max gain 0 dB (unity gain)
* e.g.: peak of 1.5 -> max gain -3.52 dB (reduce by third)
* e.g.: peak of 2.0 -> max gain -6.02 dB (reduce by half)
*/
if( multiplier > peak_limit )
{
multiplier = peak_limit;
msg_Dbg( p_obj, "replay gain: peak protection reducing gain from %.2f dB to %.2f dB (peak %.6f)",
gain,
20.f * log10f( multiplier ),
peak );
}
}
/* apply configuration gain */
multiplier *= config_gain;
msg_Dbg( p_obj, "replay gain: applying %.2f dB", 20.f * log10f( multiplier ) );
return multiplier;
}

6
src/input/test/es_out.c

@ -299,12 +299,6 @@ sout_stream_t *sout_NewInstance(vlc_object_t *p_parent, const char *psz_dest)
return NULL;
}
void vlc_audio_replay_gain_MergeFromMeta(audio_replay_gain_t *p_dst,
const struct vlc_meta_t *p_meta)
{
(void)p_dst; (void)p_meta;
}
static input_source_t *InputSourceNew(void)
{
input_source_t *in = calloc(1, sizeof(*in));

1
src/libvlccore.sym

@ -1004,6 +1004,7 @@ vlc_playlist_Pause
vlc_playlist_Resume
vlc_playlist_Export
vlc_playlist_SetMediaStoppedAction
vlc_replay_gain_CopyFromMeta
vlc_intf_GetMainPlaylist
vlc_media_source_Hold
vlc_media_source_Release

1
src/meson.build

@ -168,6 +168,7 @@ libvlccore_sources_base = files(
'input/input_interface.h',
'input/vlm_internal.h',
'input/vlm_event.h',
'input/replay_gain.c',
'input/resource.h',
'input/resource.c',
'input/services_discovery.c',

Loading…
Cancel
Save