summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ext/taglib/gstid3v2mux.cc72
-rw-r--r--tests/check/elements/id3v2mux.c42
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)
{