diff options
-rw-r--r-- | ext/taglib/gstid3v2mux.cc | 72 | ||||
-rw-r--r-- | tests/check/elements/id3v2mux.c | 42 |
2 files changed, 106 insertions, 8 deletions
diff --git a/ext/taglib/gstid3v2mux.cc b/ext/taglib/gstid3v2mux.cc index fd15836e..ac84a537 100644 --- a/ext/taglib/gstid3v2mux.cc +++ b/ext/taglib/gstid3v2mux.cc @@ -55,6 +55,7 @@ #include <textidentificationframe.h> #include <uniquefileidentifierframe.h> #include <attachedpictureframe.h> +#include <relativevolumeframe.h> #include <commentsframe.h> #include <unknownframe.h> #include <id3v2synchdata.h> @@ -560,6 +561,71 @@ add_uri_tag (ID3v2::Tag * id3v2tag, const GstTagList * list, } } +static void +add_relative_volume_tag (ID3v2::Tag * id3v2tag, const GstTagList * list, + const gchar * tag, guint num_tags, const gchar * frame_id) +{ + const char *gain_tag_name; + const char *peak_tag_name; + gdouble peak_val; + gdouble gain_val; + ID3v2::RelativeVolumeFrame * frame; + + frame = new ID3v2::RelativeVolumeFrame (); + + /* figure out tag names and the identification string to use */ + if (strcmp (tag, GST_TAG_TRACK_PEAK) == 0 || + strcmp (tag, GST_TAG_TRACK_GAIN) == 0) { + gain_tag_name = GST_TAG_TRACK_GAIN; + peak_tag_name = GST_TAG_TRACK_PEAK; + frame->setIdentification ("track"); + GST_DEBUG ("adding track relative-volume frame"); + } else { + gain_tag_name = GST_TAG_ALBUM_GAIN; + peak_tag_name = GST_TAG_ALBUM_PEAK; + frame->setIdentification ("album"); + GST_DEBUG ("adding album relative-volume frame"); + } + + /* find the value for the paired tag (gain, if this is peak, and + * vice versa). if both tags exist, only write the frame when + * we're processing the peak tag. + */ + if (strcmp (tag, GST_TAG_TRACK_PEAK) == 0 || + strcmp (tag, GST_TAG_ALBUM_PEAK) == 0) { + ID3v2::RelativeVolumeFrame::PeakVolume encoded_peak; + short peak_int; + + gst_tag_list_get_double (list, tag, &peak_val); + + if (gst_tag_list_get_tag_size (list, gain_tag_name) > 0) { + gst_tag_list_get_double (list, gain_tag_name, &gain_val); + GST_DEBUG ("setting volume adjustment %g", gain_val); + frame->setVolumeAdjustment (gain_val); + } + + /* copying mutagen: always write as 16 bits for sanity. */ + peak_int = (short)(peak_val * G_MAXSHORT); + encoded_peak.bitsRepresentingPeak = 16; + encoded_peak.peakVolume = ByteVector::fromShort(peak_int, true); + GST_DEBUG ("setting peak value %g", peak_val); + frame->setPeakVolume(encoded_peak); + + } else { + gst_tag_list_get_double (list, tag, &gain_val); + GST_DEBUG ("setting volume adjustment %g", gain_val); + frame->setVolumeAdjustment (gain_val); + + if (gst_tag_list_get_tag_size (list, peak_tag_name) != 0) { + GST_DEBUG ("both gain and peak tags exist, not adding frame this time around"); + delete frame; + return; + } + } + + id3v2tag->addFrame (frame); +} + /* id3demux produces these for frames it cannot parse */ #define GST_ID3_DEMUX_TAG_ID3V2_FRAME "private-id3v2-frame" @@ -599,7 +665,11 @@ static const struct GST_TAG_ENCODER, add_encoder_tag, ""}, { GST_TAG_ENCODER_VERSION, add_encoder_tag, ""}, { GST_TAG_COPYRIGHT_URI, add_uri_tag, "WCOP"}, { - GST_TAG_LICENSE_URI, add_uri_tag, "WCOP"} + GST_TAG_LICENSE_URI, add_uri_tag, "WCOP"}, { + GST_TAG_TRACK_PEAK, add_relative_volume_tag, ""}, { + GST_TAG_TRACK_GAIN, add_relative_volume_tag, ""}, { + GST_TAG_ALBUM_PEAK, add_relative_volume_tag, ""}, { + GST_TAG_ALBUM_GAIN, add_relative_volume_tag, ""} }; diff --git a/tests/check/elements/id3v2mux.c b/tests/check/elements/id3v2mux.c index d824361c..6b863f56 100644 --- a/tests/check/elements/id3v2mux.c +++ b/tests/check/elements/id3v2mux.c @@ -33,9 +33,10 @@ #define TEST_TRACK_COUNT 19 #define TEST_VOLUME_NUMBER 2 #define TEST_VOLUME_COUNT 3 - -/* #define TEST_TRACK_GAIN 1.45 (not implemented yet) */ -/* #define TEST_ALBUM_GAIN 0.78 (not implemented yet) */ +#define TEST_TRACK_GAIN 1.45 +#define TEST_ALBUM_GAIN 0.78 +#define TEST_TRACK_PEAK 0.83 +#define TEST_ALBUM_PEAK 0.18 /* for dummy mp3 frame sized MP3_FRAME_SIZE bytes, * start: ff fb b0 44 00 00 08 00 00 4b 00 00 00 00 00 00 */ @@ -45,6 +46,18 @@ static const guint8 mp3_dummyhdr[] = { 0xff, 0xfb, 0xb0, 0x44, 0x00, 0x00, #define MP3_FRAME_SIZE 626 +/* the peak and gain values are stored pretty roughly, so check that they're + * within 2% of the expected value. + */ +#define fail_unless_sorta_equals_float(a, b) \ +G_STMT_START { \ + double first = a; \ + double second = b; \ + fail_unless(fabs (first - second) < (0.02 * fabs (first)), \ + "'" #a "' (%g) is not equal to '" #b "' (%g)", first, second); \ +} G_STMT_END; + + static GstTagList * test_taglib_id3mux_create_tags (guint32 mask) { @@ -88,12 +101,20 @@ test_taglib_id3mux_create_tags (guint32 mask) GST_TAG_ALBUM_VOLUME_COUNT, TEST_VOLUME_COUNT, NULL); } if (mask & (1 << 8)) { + gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, + GST_TAG_TRACK_GAIN, TEST_TRACK_GAIN, NULL); } if (mask & (1 << 9)) { + gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, + GST_TAG_ALBUM_GAIN, TEST_ALBUM_GAIN, NULL); } if (mask & (1 << 10)) { + gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, + GST_TAG_TRACK_PEAK, TEST_TRACK_PEAK, NULL); } if (mask & (1 << 11)) { + gst_tag_list_add (tags, GST_TAG_MERGE_KEEP, + GST_TAG_ALBUM_PEAK, TEST_ALBUM_PEAK, NULL); } if (mask & (1 << 12)) { } @@ -193,23 +214,29 @@ test_taglib_id3mux_check_tags (GstTagList * tags, guint32 mask) &count)); fail_unless (count == TEST_VOLUME_COUNT); } -#if 0 if (mask & (1 << 8)) { gdouble gain; fail_unless (gst_tag_list_get_double (tags, GST_TAG_TRACK_GAIN, &gain)); - fail_unless (gain == TEST_TRACK_GAIN); + fail_unless_sorta_equals_float (gain, TEST_TRACK_GAIN); } if (mask & (1 << 9)) { gdouble gain; fail_unless (gst_tag_list_get_double (tags, GST_TAG_ALBUM_GAIN, &gain)); - fail_unless (gain == TEST_ALBUM_GAIN); + fail_unless_sorta_equals_float (gain, TEST_ALBUM_GAIN); } -#endif if (mask & (1 << 10)) { + gdouble peak; + + fail_unless (gst_tag_list_get_double (tags, GST_TAG_TRACK_PEAK, &peak)); + fail_unless_sorta_equals_float (peak, TEST_TRACK_PEAK); } if (mask & (1 << 11)) { + gdouble peak; + + fail_unless (gst_tag_list_get_double (tags, GST_TAG_ALBUM_PEAK, &peak)); + fail_unless_sorta_equals_float (peak, TEST_ALBUM_PEAK); } if (mask & (1 << 12)) { } @@ -269,6 +296,7 @@ got_buffer (GstElement * fakesink, GstBuffer * buf, GstPad * pad, memcpy (GST_BUFFER_DATA (*p_buf) + off, GST_BUFFER_DATA (buf), size); } } + static void demux_pad_added (GstElement * id3demux, GstPad * srcpad, GstBuffer ** p_outbuf) { |