You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.4 KiB
166 lines
5.4 KiB
/*****************************************************************************
|
|
* 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
|
|
|