[vlc-commits] demux: ogg: add replay gain support
Francois Cartegnie
git at videolan.org
Thu Sep 12 21:36:05 CEST 2013
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Sep 12 19:00:23 2013 +0200| [256391f7caacf5b47d5f9ba27ff7368dfaf009f1] | committer: Francois Cartegnie
demux: ogg: add replay gain support
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=256391f7caacf5b47d5f9ba27ff7368dfaf009f1
---
modules/demux/flac.c | 2 +-
modules/demux/ogg.c | 47 +++++++++++++++++++++++++++++++----------
modules/demux/xiph_metadata.c | 38 ++++++++++++++++++++++++++++++++-
modules/demux/xiph_metadata.h | 4 +++-
4 files changed, 77 insertions(+), 14 deletions(-)
diff --git a/modules/demux/flac.c b/modules/demux/flac.c
index a2ac4dc..1356835 100644
--- a/modules/demux/flac.c
+++ b/modules/demux/flac.c
@@ -582,7 +582,7 @@ static void ParseComment( demux_t *p_demux, const uint8_t *p_data, int i_data )
vorbis_ParseComment( &p_sys->p_meta, &p_data[4], i_data - 4,
&p_sys->i_attachments, &p_sys->attachments,
- &p_sys->i_cover_score, &p_sys->i_cover_idx, NULL, NULL );
+ &p_sys->i_cover_score, &p_sys->i_cover_idx, NULL, NULL, NULL, NULL );
}
static void ParsePicture( demux_t *p_demux, const uint8_t *p_data, int i_data )
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 57edb99..749c346 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -133,7 +133,7 @@ static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_strea
static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream );
/* */
-static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8_t *p_headers, int i_headers );
+static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
static int64_t Ogg_GetLastPacket( demux_t *p_demux, logical_stream_t *p_stream, double f_rate );
/* Logical bitstream headers */
@@ -848,7 +848,7 @@ static void Ogg_DecodePacket( demux_t *p_demux,
p_stream->p_es, &p_stream->fmt );
if( p_stream->i_headers > 0 )
- Ogg_ExtractMeta( p_demux, p_stream->fmt.i_codec,
+ Ogg_ExtractMeta( p_demux, & p_stream->fmt,
p_stream->p_headers, p_stream->i_headers );
/* we're not at BOS anymore for this logical stream */
@@ -1863,7 +1863,8 @@ static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *
return !b_compatible;
}
-static void Ogg_ExtractXiphMeta( demux_t *p_demux, const void *p_headers, unsigned i_headers, unsigned i_skip )
+static void Ogg_ExtractXiphMeta( demux_t *p_demux, es_format_t *p_fmt,
+ const void *p_headers, unsigned i_headers, unsigned i_skip )
{
demux_sys_t *p_ogg = p_demux->p_sys;
@@ -1878,10 +1879,18 @@ static void Ogg_ExtractXiphMeta( demux_t *p_demux, const void *p_headers, unsign
{
int i_cover_score = 0;
int i_cover_idx = 0;
+ float pf_replay_gain[AUDIO_REPLAY_GAIN_MAX];
+ float pf_replay_peak[AUDIO_REPLAY_GAIN_MAX];
+ for(int i=0; i< AUDIO_REPLAY_GAIN_MAX; i++ )
+ {
+ pf_replay_gain[i] = 0;
+ pf_replay_peak[i] = 0;
+ }
vorbis_ParseComment( &p_ogg->p_meta, (uint8_t*)pp_data[1] + i_skip, pi_size[1] - i_skip,
&p_ogg->i_attachments, &p_ogg->attachments,
&i_cover_score, &i_cover_idx,
- &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints );
+ &p_ogg->i_seekpoints, &p_ogg->pp_seekpoints,
+ &pf_replay_gain, &pf_replay_peak );
if( p_ogg->p_meta != NULL && i_cover_idx < p_ogg->i_attachments )
{
char psz_url[128];
@@ -1889,6 +1898,22 @@ static void Ogg_ExtractXiphMeta( demux_t *p_demux, const void *p_headers, unsign
p_ogg->attachments[i_cover_idx]->psz_name );
vlc_meta_Set( p_ogg->p_meta, vlc_meta_ArtworkURL, psz_url );
}
+
+ for ( int i=0; i<AUDIO_REPLAY_GAIN_MAX;i++ )
+ {
+ if ( pf_replay_gain[i] != 0 )
+ {
+ p_fmt->audio_replay_gain.pb_gain[i] = true;
+ p_fmt->audio_replay_gain.pf_gain[i] = pf_replay_gain[i];
+ msg_Dbg( p_demux, "setting replay gain %d to %f", i, pf_replay_gain[i] );
+ }
+ if ( pf_replay_peak[i] != 0 )
+ {
+ p_fmt->audio_replay_gain.pb_peak[i] = true;
+ p_fmt->audio_replay_gain.pf_peak[i] = pf_replay_peak[i];
+ msg_Dbg( p_demux, "setting replay peak %d to %f", i, pf_replay_gain[i] );
+ }
+ }
}
if( p_ogg->i_seekpoints > 1 )
@@ -1899,33 +1924,33 @@ static void Ogg_ExtractXiphMeta( demux_t *p_demux, const void *p_headers, unsign
for( unsigned i = 0; i < i_count; i++ )
free( pp_data[i] );
}
-static void Ogg_ExtractMeta( demux_t *p_demux, vlc_fourcc_t i_codec, const uint8_t *p_headers, int i_headers )
+static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers )
{
demux_sys_t *p_ogg = p_demux->p_sys;
- switch( i_codec )
+ switch( p_fmt->i_codec )
{
/* 3 headers with the 2° one being the comments */
case VLC_CODEC_VORBIS:
case VLC_CODEC_THEORA:
- Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 1+6 );
+ Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
break;
case VLC_CODEC_OPUS:
- Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 8 );
+ Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 8 );
break;
case VLC_CODEC_SPEEX:
- Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 0 );
+ Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 0 );
break;
/* N headers with the 2° one being the comments */
case VLC_CODEC_KATE:
/* 1 byte for header type, 7 bytes for magic, 1 reserved zero byte */
- Ogg_ExtractXiphMeta( p_demux, p_headers, i_headers, 1+7+1 );
+ Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+7+1 );
break;
/* TODO */
case VLC_CODEC_FLAC:
- msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&i_codec );
+ msg_Warn( p_demux, "Ogg_ExtractMeta does not support %4.4s", (const char*)&p_fmt->i_codec );
break;
/* No meta data */
diff --git a/modules/demux/xiph_metadata.c b/modules/demux/xiph_metadata.c
index 16e060d..bef41e2 100644
--- a/modules/demux/xiph_metadata.c
+++ b/modules/demux/xiph_metadata.c
@@ -148,7 +148,9 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta,
const uint8_t *p_data, int i_data,
int *i_attachments, input_attachment_t ***attachments,
int *i_cover_score, int *i_cover_idx,
- int *i_seekpoint, seekpoint_t ***ppp_seekpoint )
+ int *i_seekpoint, seekpoint_t ***ppp_seekpoint,
+ float (* ppf_replay_gain)[AUDIO_REPLAY_GAIN_MAX],
+ float (* ppf_replay_peak)[AUDIO_REPLAY_GAIN_MAX] )
{
int n;
int i_comment;
@@ -292,6 +294,40 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta,
*i_attachments, *attachments, p_attachment );
}
}
+ else if ( ppf_replay_gain && ppf_replay_peak && !strncmp(psz_comment, "REPLAYGAIN_", 11) )
+ {
+ char *p = strchr( psz_comment, '=' );
+ char *psz_val;
+ if (!p) continue;
+ if ( !strncmp(psz_comment, "REPLAYGAIN_TRACK_GAIN=", 22) )
+ {
+ psz_val = malloc( strlen(p+1) + 1 );
+ if (!psz_val) continue;
+ if( sscanf( ++p, "%s dB", psz_val ) == 1 )
+ {
+ (*ppf_replay_gain)[AUDIO_REPLAY_GAIN_TRACK] = us_atof( psz_val );
+ free( psz_val );
+ }
+ }
+ else if ( !strncmp(psz_comment, "REPLAYGAIN_ALBUM_GAIN=", 22) )
+ {
+ psz_val = malloc( strlen(p+1) + 1 );
+ if (!psz_val) continue;
+ if( sscanf( ++p, "%s dB", psz_val ) == 1 )
+ {
+ (*ppf_replay_gain)[AUDIO_REPLAY_GAIN_ALBUM] = us_atof( psz_val );
+ free( psz_val );
+ }
+ }
+ else if ( !strncmp(psz_comment, "REPLAYGAIN_ALBUM_PEAK=", 22) )
+ {
+ (*ppf_replay_peak)[AUDIO_REPLAY_GAIN_ALBUM] = us_atof( ++p );
+ }
+ else if ( !strncmp(psz_comment, "REPLAYGAIN_TRACK_PEAK=", 22) )
+ {
+ (*ppf_replay_peak)[AUDIO_REPLAY_GAIN_TRACK] = us_atof( ++p );
+ }
+ }
else if( !strncmp(psz_comment, "CHAPTER", 7) )
{
unsigned int i_chapt;
diff --git a/modules/demux/xiph_metadata.h b/modules/demux/xiph_metadata.h
index de97c2b..6e318f5 100644
--- a/modules/demux/xiph_metadata.h
+++ b/modules/demux/xiph_metadata.h
@@ -36,7 +36,9 @@ void vorbis_ParseComment( vlc_meta_t **pp_meta,
const uint8_t *p_data, int i_data,
int *i_attachments, input_attachment_t ***attachments,
int *i_cover_score, int *i_cover_idx,
- int *i_seekpoint, seekpoint_t ***ppp_seekpoint );
+ int *i_seekpoint, seekpoint_t ***ppp_seekpoint,
+ float (* ppf_replay_gain)[AUDIO_REPLAY_GAIN_MAX],
+ float (* ppf_replay_peak)[AUDIO_REPLAY_GAIN_MAX] );
static const struct {
const char *psz_tag;
More information about the vlc-commits
mailing list