1 /* GStreamer ReplayGain analysis
2 *
3 * Copyright (C) 2006 Rene Stadler <mail@renestadler.de>
4 *
5 * rganalysis.c: Unit test for the rganalysis element
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23 /* Some things to note about the RMS window length of the analysis algorithm and
24 * thus the implementation used in the element: Processing divides input data
25 * into 50ms windows at some point. Some details about this that normally do
26 * not matter:
27 *
28 * 1. At the end of a stream, the remainder of data that did not fill up the
29 * last 50ms window is simply discarded.
30 *
31 * 2. If the sample rate changes during a stream, the currently running window
32 * is discarded and the equal loudness filter gets reset as if a new stream
33 * started.
34 *
35 * 3. For the album gain, it is not entirely correct to think of obtaining it
36 * like "as if all the tracks are analyzed as one track". There isn't a
37 * separate window being tracked for album processing, so at stream (track)
38 * end, the remaining unfilled window does not contribute to the album gain
39 * either.
40 *
41 * 4. If a waveform with a result gain G is concatenated to itself and the
42 * result processed as a track, the gain can be different from G if and only
43 * if the duration of the original waveform is not an integer multiple of
44 * 50ms. If the original waveform gets processed as a single track and then
45 * the same data again as a subsequent track, the album result gain will
46 * always match G (this is implied by 3.).
47 *
48 * 5. A stream shorter than 50ms cannot be analyzed. At 8000 and 48000 Hz,
49 * this corresponds to 400 resp. 2400 frames. If a stream is shorter than
50 * 50ms, the element will not generate tags at EOS (only if an album
51 * finished, but only album tags are generated then). This is not an
52 * erroneous condition, the element should behave normally.
53 *
54 * The limitations outlined in 1.-4. do not apply to the peak values. Every
55 * single sample is accounted for when looking for the peak. Thus the album
56 * peak is guaranteed to be the maximum value of all track peaks.
57 *
58 * In normal day-to-day use, these little facts are unlikely to be relevant, but
59 * they have to be kept in mind for writing the tests here.
60 */
61
62 #include <gst/check/gstcheck.h>
63 #include <gst/audio/audio.h>
64
65 /* For ease of programming we use globals to keep refs for our floating src and
66 * sink pads we create; otherwise we always have to do get_pad, get_peer, and
67 * then remove references in every test function */
68 static GstPad *mysrcpad, *mysinkpad;
69 static GstBus *mybus;
70
71 /* Mapping from supported sample rates to the correct result gain for the
72 * following test waveform: 20 * 512 samples with a quarter-full amplitude of
73 * toggling sign, changing every 48 samples and starting with the positive
74 * value.
75 *
76 * Even if we would generate a wave describing a signal with the same frequency
77 * at each sampling rate, the results would vary (slightly). Hence the simple
78 * generation method, since we cannot use a constant value as expected result
79 * anyways. For all sample rates, changing the sign every 48 frames gives a
80 * sane frequency. Buffers containing data that forms such a waveform is
81 * created using the test_buffer_square_{float,int16}_{mono,stereo} functions
82 * below.
83 *
84 * The results have been checked against what the metaflac and wavegain programs
85 * generate for such a stream. If you want to verify these, be sure that the
86 * metaflac program does not produce incorrect results in your environment: I
87 * found a strange bug in the (defacto) reference code for the analysis that
88 * sometimes leads to incorrect RMS window lengths. */
89
90 struct rate_test
91 {
92 guint sample_rate;
93 gdouble gain;
94 };
95
96 static const struct rate_test supported_rates[] = {
97 {8000, -0.91},
98 {11025, -2.80},
99 {12000, -3.13},
100 {16000, -4.26},
101 {22050, -5.64},
102 {24000, -5.87},
103 {32000, -6.03},
104 {44100, -6.20},
105 {48000, -6.14}
106 };
107
108 /* Lookup the correct gain adjustment result in above array. */
109
110 static gdouble
get_expected_gain(guint sample_rate)111 get_expected_gain (guint sample_rate)
112 {
113 gint i;
114
115 for (i = G_N_ELEMENTS (supported_rates); i--;)
116 if (supported_rates[i].sample_rate == sample_rate)
117 return supported_rates[i].gain;
118 g_return_val_if_reached (0.0);
119 }
120
121 #define SILENCE_GAIN 64.82
122
123 #define REPLAY_GAIN_CAPS \
124 "channels = (int) { 1, 2 }, " \
125 "rate = (int) { 8000, 11025, 12000, 16000, 22050, " \
126 "24000, 32000, 44100, 48000 }"
127
128 #define RG_ANALYSIS_CAPS_TEMPLATE_STRING \
129 "audio/x-raw, " \
130 "format = (string) "GST_AUDIO_NE (F32) ", " \
131 "layout = (string) interleaved, " \
132 REPLAY_GAIN_CAPS \
133 "; " \
134 "audio/x-raw, " \
135 "format = (string) "GST_AUDIO_NE (S16) ", " \
136 "layout = (string) interleaved, " \
137 REPLAY_GAIN_CAPS
138
139 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
140 GST_PAD_SINK,
141 GST_PAD_ALWAYS,
142 GST_STATIC_CAPS (RG_ANALYSIS_CAPS_TEMPLATE_STRING)
143 );
144 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
145 GST_PAD_SRC,
146 GST_PAD_ALWAYS,
147 GST_STATIC_CAPS (RG_ANALYSIS_CAPS_TEMPLATE_STRING)
148 );
149
150 static gboolean
mysink_event_func(GstPad * pad,GstObject * parent,GstEvent * event)151 mysink_event_func (GstPad * pad, GstObject * parent, GstEvent * event)
152 {
153 GST_LOG_OBJECT (pad, "%s event: %" GST_PTR_FORMAT,
154 GST_EVENT_TYPE_NAME (event), event);
155
156 /* a sink would post tag events as messages, so do the same here,
157 * esp. since we're polling on the bus waiting for TAG messages.. */
158 if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
159 GstTagList *taglist;
160
161 gst_event_parse_tag (event, &taglist);
162
163 gst_bus_post (mybus, gst_message_new_tag (GST_OBJECT (mysinkpad),
164 gst_tag_list_copy (taglist)));
165 }
166
167 gst_event_unref (event);
168 return TRUE;
169 }
170
171 static GstElement *
setup_rganalysis(void)172 setup_rganalysis (void)
173 {
174 GstElement *analysis;
175 GstBus *bus;
176
177 GST_DEBUG ("setup_rganalysis");
178 analysis = gst_check_setup_element ("rganalysis");
179 mysrcpad = gst_check_setup_src_pad (analysis, &srctemplate);
180 mysinkpad = gst_check_setup_sink_pad (analysis, &sinktemplate);
181 gst_pad_set_event_function (mysinkpad, mysink_event_func);
182 gst_pad_set_active (mysrcpad, TRUE);
183 gst_pad_set_active (mysinkpad, TRUE);
184
185 bus = gst_bus_new ();
186 gst_element_set_bus (analysis, bus);
187
188 mybus = bus; /* keep ref */
189
190 return analysis;
191 }
192
193 static void
cleanup_rganalysis(GstElement * element)194 cleanup_rganalysis (GstElement * element)
195 {
196 GST_DEBUG ("cleanup_rganalysis");
197
198 g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
199 g_list_free (buffers);
200 buffers = NULL;
201
202 gst_object_unref (mybus);
203 mybus = NULL;
204
205 /* The bus owns references to the element: */
206 gst_element_set_bus (element, NULL);
207
208 gst_pad_set_active (mysrcpad, FALSE);
209 gst_pad_set_active (mysinkpad, FALSE);
210 gst_check_teardown_src_pad (element);
211 gst_check_teardown_sink_pad (element);
212 gst_check_teardown_element (element);
213 }
214
215 static void
set_playing_state(GstElement * element)216 set_playing_state (GstElement * element)
217 {
218 fail_unless (gst_element_set_state (element,
219 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
220 "Could not set state to PLAYING");
221 }
222
223 static void
send_flush_events(GstElement * element)224 send_flush_events (GstElement * element)
225 {
226 gboolean res;
227 GstPad *pad;
228
229 pad = mysrcpad;
230 res = gst_pad_push_event (pad, gst_event_new_flush_start ());
231 fail_unless (res, "flush-start even not handledt");
232 res = gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
233 fail_unless (res, "flush-stop event not handled");
234 }
235
236 static void
send_stream_start_event(GstElement * element)237 send_stream_start_event (GstElement * element)
238 {
239 gboolean res;
240 GstPad *pad;
241
242 pad = mysrcpad;
243 res = gst_pad_push_event (pad, gst_event_new_stream_start ("test"));
244 fail_unless (res, "STREAM_START event not handled");
245 }
246
247 static void
send_caps_event(const gchar * format,gint sample_rate,gint channels)248 send_caps_event (const gchar * format, gint sample_rate, gint channels)
249 {
250 GstCaps *caps;
251
252 caps = gst_caps_new_simple ("audio/x-raw",
253 "format", G_TYPE_STRING, format,
254 "rate", G_TYPE_INT, sample_rate, "channels", G_TYPE_INT, channels,
255 "layout", G_TYPE_STRING, "interleaved", NULL);
256 if (channels == 2) {
257 gst_caps_set_simple (caps,
258 "channel-mask", GST_TYPE_BITMASK,
259 G_GUINT64_CONSTANT (0x0000000000000003), NULL);
260 }
261 gst_pad_set_caps (mysrcpad, caps);
262 gst_caps_unref (caps);
263 }
264
265 static void
send_segment_event(GstElement * element)266 send_segment_event (GstElement * element)
267 {
268 GstSegment segment;
269 gboolean res;
270 GstPad *pad;
271
272 pad = mysrcpad;
273 gst_segment_init (&segment, GST_FORMAT_TIME);
274 res = gst_pad_push_event (pad, gst_event_new_segment (&segment));
275 fail_unless (res, "SEGMENT event not handled");
276 }
277
278 static void
send_eos_event(GstElement * element)279 send_eos_event (GstElement * element)
280 {
281 GstBus *bus = gst_element_get_bus (element);
282 GstPad *pad = mysrcpad;
283 gboolean res;
284
285 res = gst_pad_push_event (pad, gst_event_new_eos ());
286 fail_unless (res, "EOS event not handled");
287
288 /* There is no sink element, so _we_ post the EOS message on the bus here. Of
289 * course we generate any EOS ourselves, but this allows us to poll for the
290 * EOS message in poll_eos if we expect the element to _not_ generate a TAG
291 * message. That's better than waiting for a timeout to lapse. */
292 fail_unless (gst_bus_post (bus, gst_message_new_eos (NULL)));
293
294 gst_object_unref (bus);
295 }
296
297 static void
send_tag_event(GstElement * element,GstTagList * tag_list)298 send_tag_event (GstElement * element, GstTagList * tag_list)
299 {
300 GstPad *pad = mysrcpad;
301 GstEvent *event = gst_event_new_tag (tag_list);
302
303 fail_unless (gst_pad_push_event (pad, event),
304 "Cannot send TAG event: Not handled.");
305 }
306
307 static void
poll_eos(GstElement * element)308 poll_eos (GstElement * element)
309 {
310 GstBus *bus = gst_element_get_bus (element);
311 GstMessage *message;
312
313 message = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_TAG, GST_SECOND);
314 fail_unless (message != NULL, "Could not poll for EOS message: Timed out");
315 fail_unless (message->type == GST_MESSAGE_EOS,
316 "Could not poll for eos message: got message of type %s instead",
317 gst_message_type_get_name (message->type));
318
319 gst_message_unref (message);
320 gst_object_unref (bus);
321 }
322
323 static GstTagList *
poll_tags_only(GstElement * element)324 poll_tags_only (GstElement * element)
325 {
326 GstBus *bus = gst_element_get_bus (element);
327 GstTagList *tag_list;
328 GstMessage *message;
329
330 message = gst_bus_poll (bus, GST_MESSAGE_TAG, GST_SECOND);
331 fail_unless (message != NULL, "Could not poll for TAG message: Timed out");
332
333 gst_message_parse_tag (message, &tag_list);
334 gst_message_unref (message);
335 gst_object_unref (bus);
336
337 return tag_list;
338 }
339
340 /* This also polls for EOS since the TAG message comes right before the end of
341 * streams. */
342
343 static GstTagList *
poll_tags_followed_by_eos(GstElement * element)344 poll_tags_followed_by_eos (GstElement * element)
345 {
346 GstTagList *tag_list = poll_tags_only (element);
347
348 poll_eos (element);
349
350 return tag_list;
351 }
352
353 #define MATCH_PEAK(p1, p2) ((p1 < p2 + 1e-6) && (p2 < p1 + 1e-6))
354 #define MATCH_GAIN(g1, g2) ((g1 < g2 + 1e-13) && (g2 < g1 + 1e-13))
355
356 static void
fail_unless_track_gain(const GstTagList * tag_list,gdouble gain)357 fail_unless_track_gain (const GstTagList * tag_list, gdouble gain)
358 {
359 gdouble result;
360
361 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_GAIN, &result),
362 "Tag list contains no track gain value");
363 fail_unless (MATCH_GAIN (gain, result),
364 "Track gain %+.2f does not match, expected %+.2f", result, gain);
365 }
366
367 static void
fail_unless_track_peak(const GstTagList * tag_list,gdouble peak)368 fail_unless_track_peak (const GstTagList * tag_list, gdouble peak)
369 {
370 gdouble result;
371
372 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_PEAK, &result),
373 "Tag list contains no track peak value");
374 fail_unless (MATCH_PEAK (peak, result),
375 "Track peak %f does not match, expected %f", result, peak);
376 }
377
378 static void
fail_unless_album_gain(const GstTagList * tag_list,gdouble gain)379 fail_unless_album_gain (const GstTagList * tag_list, gdouble gain)
380 {
381 gdouble result;
382
383 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_GAIN, &result),
384 "Tag list contains no album gain value");
385 fail_unless (MATCH_GAIN (result, gain),
386 "Album gain %+.2f does not match, expected %+.2f", result, gain);
387 }
388
389 static void
fail_unless_album_peak(const GstTagList * tag_list,gdouble peak)390 fail_unless_album_peak (const GstTagList * tag_list, gdouble peak)
391 {
392 gdouble result;
393
394 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_PEAK, &result),
395 "Tag list contains no album peak value");
396 fail_unless (MATCH_PEAK (peak, result),
397 "Album peak %f does not match, expected %f", result, peak);
398 }
399
400 static void
fail_if_track_tags(const GstTagList * tag_list)401 fail_if_track_tags (const GstTagList * tag_list)
402 {
403 gdouble result;
404
405 fail_if (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_GAIN, &result),
406 "Tag list contains track gain value (but should not)");
407 fail_if (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_PEAK, &result),
408 "Tag list contains track peak value (but should not)");
409 }
410
411 static void
fail_if_album_tags(const GstTagList * tag_list)412 fail_if_album_tags (const GstTagList * tag_list)
413 {
414 gdouble result;
415
416 fail_if (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_GAIN, &result),
417 "Tag list contains album gain value (but should not)");
418 fail_if (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_PEAK, &result),
419 "Tag list contains album peak value (but should not)");
420 }
421
422 static void
fail_unless_num_tracks(GstElement * element,guint num_tracks)423 fail_unless_num_tracks (GstElement * element, guint num_tracks)
424 {
425 guint current;
426
427 g_object_get (element, "num-tracks", ¤t, NULL);
428 fail_unless (current == num_tracks,
429 "num-tracks property has incorrect value %u, expected %u",
430 current, num_tracks);
431 }
432
433 /* Functions that create buffers with constant sample values, for peak
434 * tests. */
435
436 static GstBuffer *
test_buffer_const_float_mono(gint sample_rate,gsize n_frames,gfloat value)437 test_buffer_const_float_mono (gint sample_rate, gsize n_frames, gfloat value)
438 {
439 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat));
440 GstMapInfo map;
441 gfloat *data;
442 gint i;
443
444 gst_buffer_map (buf, &map, GST_MAP_WRITE);
445 data = (gfloat *) map.data;
446 for (i = n_frames; i--;)
447 *data++ = value;
448 gst_buffer_unmap (buf, &map);
449
450 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
451
452 return buf;
453 }
454
455 static GstBuffer *
test_buffer_const_float_stereo(gint sample_rate,gsize n_frames,gfloat value_l,gfloat value_r)456 test_buffer_const_float_stereo (gint sample_rate, gsize n_frames,
457 gfloat value_l, gfloat value_r)
458 {
459 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat) * 2);
460 GstMapInfo map;
461 gfloat *data;
462 gint i;
463
464 gst_buffer_map (buf, &map, GST_MAP_WRITE);
465 data = (gfloat *) map.data;
466 for (i = n_frames; i--;) {
467 *data++ = value_l;
468 *data++ = value_r;
469 }
470 gst_buffer_unmap (buf, &map);
471
472 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
473
474 return buf;
475 }
476
477 static GstBuffer *
test_buffer_const_int16_mono(gint sample_rate,gint depth,gsize n_frames,gint16 value)478 test_buffer_const_int16_mono (gint sample_rate, gint depth, gsize n_frames,
479 gint16 value)
480 {
481 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16));
482 gint16 *data;
483 GstMapInfo map;
484 gint i;
485
486 gst_buffer_map (buf, &map, GST_MAP_WRITE);
487 data = (gint16 *) map.data;
488 for (i = n_frames; i--;)
489 *data++ = value;
490 gst_buffer_unmap (buf, &map);
491
492 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
493
494 return buf;
495 }
496
497 static GstBuffer *
test_buffer_const_int16_stereo(gint sample_rate,gint depth,gsize n_frames,gint16 value_l,gint16 value_r)498 test_buffer_const_int16_stereo (gint sample_rate, gint depth, gsize n_frames,
499 gint16 value_l, gint16 value_r)
500 {
501 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16) * 2);
502 gint16 *data;
503 GstMapInfo map;
504 gint i;
505
506 gst_buffer_map (buf, &map, GST_MAP_WRITE);
507 data = (gint16 *) map.data;
508 for (i = n_frames; i--;) {
509 *data++ = value_l;
510 *data++ = value_r;
511 }
512 gst_buffer_unmap (buf, &map);
513
514 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
515
516 return buf;
517 }
518
519 /* Functions that create data buffers containing square signal
520 * waveforms. */
521
522 static GstBuffer *
test_buffer_square_float_mono(gint * accumulator,gint sample_rate,gsize n_frames,gfloat value)523 test_buffer_square_float_mono (gint * accumulator, gint sample_rate,
524 gsize n_frames, gfloat value)
525 {
526 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat));
527 gfloat *data;
528 GstMapInfo map;
529 gint i;
530
531 gst_buffer_map (buf, &map, GST_MAP_WRITE);
532 data = (gfloat *) map.data;
533 for (i = n_frames; i--;) {
534 *accumulator += 1;
535 *accumulator %= 96;
536
537 if (*accumulator < 48)
538 *data++ = value;
539 else
540 *data++ = -value;
541 }
542 gst_buffer_unmap (buf, &map);
543
544 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
545
546 return buf;
547 }
548
549 static GstBuffer *
test_buffer_square_float_stereo(gint * accumulator,gint sample_rate,gsize n_frames,gfloat value_l,gfloat value_r)550 test_buffer_square_float_stereo (gint * accumulator, gint sample_rate,
551 gsize n_frames, gfloat value_l, gfloat value_r)
552 {
553 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat) * 2);
554 gfloat *data;
555 GstMapInfo map;
556 gint i;
557
558 gst_buffer_map (buf, &map, GST_MAP_WRITE);
559 data = (gfloat *) map.data;
560 for (i = n_frames; i--;) {
561 *accumulator += 1;
562 *accumulator %= 96;
563
564 if (*accumulator < 48) {
565 *data++ = value_l;
566 *data++ = value_r;
567 } else {
568 *data++ = -value_l;
569 *data++ = -value_r;
570 }
571 }
572 gst_buffer_unmap (buf, &map);
573
574 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
575
576 return buf;
577 }
578
579 static GstBuffer *
test_buffer_square_int16_mono(gint * accumulator,gint sample_rate,gint depth,gsize n_frames,gint16 value)580 test_buffer_square_int16_mono (gint * accumulator, gint sample_rate,
581 gint depth, gsize n_frames, gint16 value)
582 {
583 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16));
584 gint16 *data;
585 GstMapInfo map;
586 gint i;
587
588 gst_buffer_map (buf, &map, GST_MAP_WRITE);
589 data = (gint16 *) map.data;
590 for (i = n_frames; i--;) {
591 *accumulator += 1;
592 *accumulator %= 96;
593
594 if (*accumulator < 48)
595 *data++ = value;
596 else
597 *data++ = -MAX (value, -32767);
598 }
599 gst_buffer_unmap (buf, &map);
600
601 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
602
603 return buf;
604 }
605
606 static GstBuffer *
test_buffer_square_int16_stereo(gint * accumulator,gint sample_rate,gint depth,gsize n_frames,gint16 value_l,gint16 value_r)607 test_buffer_square_int16_stereo (gint * accumulator, gint sample_rate,
608 gint depth, gsize n_frames, gint16 value_l, gint16 value_r)
609 {
610 GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16) * 2);
611 gint16 *data;
612 GstMapInfo map;
613 gint i;
614
615 gst_buffer_map (buf, &map, GST_MAP_WRITE);
616 data = (gint16 *) map.data;
617 for (i = n_frames; i--;) {
618 *accumulator += 1;
619 *accumulator %= 96;
620
621 if (*accumulator < 48) {
622 *data++ = value_l;
623 *data++ = value_r;
624 } else {
625 *data++ = -MAX (value_l, -32767);
626 *data++ = -MAX (value_r, -32767);
627 }
628 }
629 gst_buffer_unmap (buf, &map);
630
631 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
632
633 return buf;
634 }
635
636 static void
push_buffer(GstBuffer * buf)637 push_buffer (GstBuffer * buf)
638 {
639 /* gst_pad_push steals a reference. */
640 fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK);
641 ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
642 }
643
644 /*** Start of the tests. ***/
645
646 /* This test looks redundant, but early versions of the element
647 * crashed when doing, well, nothing: */
648
GST_START_TEST(test_no_buffer)649 GST_START_TEST (test_no_buffer)
650 {
651 GstElement *element = setup_rganalysis ();
652
653 set_playing_state (element);
654 send_eos_event (element);
655 poll_eos (element);
656
657 cleanup_rganalysis (element);
658 }
659
660 GST_END_TEST;
661
GST_START_TEST(test_no_buffer_album_1)662 GST_START_TEST (test_no_buffer_album_1)
663 {
664 GstElement *element = setup_rganalysis ();
665
666 set_playing_state (element);
667
668 /* Single track: */
669 send_stream_start_event (element);
670 send_segment_event (element);
671 send_eos_event (element);
672 poll_eos (element);
673
674 /* First album: */
675 g_object_set (element, "num-tracks", 3, NULL);
676
677 send_flush_events (element);
678 send_segment_event (element);
679 send_eos_event (element);
680 poll_eos (element);
681 fail_unless_num_tracks (element, 2);
682
683 send_flush_events (element);
684 send_segment_event (element);
685 send_eos_event (element);
686 poll_eos (element);
687 fail_unless_num_tracks (element, 1);
688
689 send_flush_events (element);
690 send_segment_event (element);
691 send_eos_event (element);
692 poll_eos (element);
693 fail_unless_num_tracks (element, 0);
694
695 /* Second album: */
696 g_object_set (element, "num-tracks", 2, NULL);
697
698 send_flush_events (element);
699 send_segment_event (element);
700 send_eos_event (element);
701 poll_eos (element);
702 fail_unless_num_tracks (element, 1);
703
704 send_flush_events (element);
705 send_segment_event (element);
706 send_eos_event (element);
707 poll_eos (element);
708 fail_unless_num_tracks (element, 0);
709
710 /* Single track: */
711 send_flush_events (element);
712 send_segment_event (element);
713 send_eos_event (element);
714 poll_eos (element);
715 fail_unless_num_tracks (element, 0);
716
717 cleanup_rganalysis (element);
718 }
719
720 GST_END_TEST;
721
GST_START_TEST(test_no_buffer_album_2)722 GST_START_TEST (test_no_buffer_album_2)
723 {
724 GstElement *element = setup_rganalysis ();
725 GstTagList *tag_list;
726 gint accumulator = 0;
727 gint i;
728
729 g_object_set (element, "num-tracks", 3, NULL);
730 set_playing_state (element);
731
732 /* No buffer for the first track. */
733 send_stream_start_event (element);
734 send_segment_event (element);
735 send_eos_event (element);
736 /* No tags should be posted, there was nothing to analyze: */
737 poll_eos (element);
738 fail_unless_num_tracks (element, 2);
739
740 /* A test waveform with known gain result as second track: */
741
742 send_flush_events (element);
743 send_caps_event (GST_AUDIO_NE (F32), 44100, 1);
744 send_segment_event (element);
745 for (i = 20; i--;)
746 push_buffer (test_buffer_square_float_mono (&accumulator, 44100, 512,
747 0.25));
748 send_eos_event (element);
749 tag_list = poll_tags_followed_by_eos (element);
750 fail_unless_track_peak (tag_list, 0.25);
751 fail_unless_track_gain (tag_list, -6.20);
752 /* Album is not finished yet: */
753 fail_if_album_tags (tag_list);
754 gst_tag_list_unref (tag_list);
755 fail_unless_num_tracks (element, 1);
756
757 /* No buffer for the last track. */
758
759 send_flush_events (element);
760 send_segment_event (element);
761 send_eos_event (element);
762
763 tag_list = poll_tags_followed_by_eos (element);
764 fail_unless_album_peak (tag_list, 0.25);
765 fail_unless_album_gain (tag_list, -6.20);
766 /* No track tags should be posted, as there was no data for it: */
767 fail_if_track_tags (tag_list);
768 gst_tag_list_unref (tag_list);
769 fail_unless_num_tracks (element, 0);
770
771 cleanup_rganalysis (element);
772 }
773
774 GST_END_TEST;
775
GST_START_TEST(test_empty_buffers)776 GST_START_TEST (test_empty_buffers)
777 {
778 GstElement *element = setup_rganalysis ();
779
780 set_playing_state (element);
781
782 /* Single track: */
783 send_stream_start_event (element);
784 send_caps_event (GST_AUDIO_NE (F32), 44100, 2);
785 send_segment_event (element);
786 push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0));
787 send_eos_event (element);
788 poll_eos (element);
789
790 /* First album: */
791 g_object_set (element, "num-tracks", 2, NULL);
792
793 send_flush_events (element);
794 send_segment_event (element);
795 push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0));
796 send_eos_event (element);
797 poll_eos (element);
798 fail_unless_num_tracks (element, 1);
799
800 send_flush_events (element);
801 send_segment_event (element);
802 push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0));
803 send_eos_event (element);
804 poll_eos (element);
805 fail_unless_num_tracks (element, 0);
806
807 /* Second album, with a single track: */
808 g_object_set (element, "num-tracks", 1, NULL);
809 send_flush_events (element);
810 send_segment_event (element);
811 push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0));
812 send_eos_event (element);
813 poll_eos (element);
814 fail_unless_num_tracks (element, 0);
815
816 /* Single track: */
817 send_flush_events (element);
818 send_segment_event (element);
819 push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0));
820 send_eos_event (element);
821 poll_eos (element);
822
823 cleanup_rganalysis (element);
824 }
825
826 GST_END_TEST;
827
828 /* Tests for correctness of the peak values. */
829
830 /* Float peak test. For stereo, one channel has the constant value of -1.369,
831 * the other one 0.0. This tests many things: The result peak value should
832 * occur on any channel. The peak is of course the absolute amplitude, so 1.369
833 * should be the result. This will also detect if the code uses the absolute
834 * value during the comparison. If it is buggy it will return 0.0 since 0.0 >
835 * -1.369. Furthermore, this makes sure that there is no problem with headroom
836 * (exceeding 0dBFS). In the wild you get float samples > 1.0 from stuff like
837 * vorbis. */
838
GST_START_TEST(test_peak_float)839 GST_START_TEST (test_peak_float)
840 {
841 GstElement *element = setup_rganalysis ();
842 GstTagList *tag_list;
843
844 set_playing_state (element);
845 send_stream_start_event (element);
846 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
847 send_segment_event (element);
848 push_buffer (test_buffer_const_float_stereo (8000, 512, -1.369, 0.0));
849 send_eos_event (element);
850 tag_list = poll_tags_followed_by_eos (element);
851 fail_unless_track_peak (tag_list, 1.369);
852 gst_tag_list_unref (tag_list);
853
854 /* Swapped channels. */
855 send_flush_events (element);
856 send_segment_event (element);
857 push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, -1.369));
858 send_eos_event (element);
859 tag_list = poll_tags_followed_by_eos (element);
860 fail_unless_track_peak (tag_list, 1.369);
861 gst_tag_list_unref (tag_list);
862
863 /* Mono. */
864 send_flush_events (element);
865 send_caps_event (GST_AUDIO_NE (F32), 8000, 1);
866 send_segment_event (element);
867 push_buffer (test_buffer_const_float_mono (8000, 512, -1.369));
868 send_eos_event (element);
869 tag_list = poll_tags_followed_by_eos (element);
870 fail_unless_track_peak (tag_list, 1.369);
871 gst_tag_list_unref (tag_list);
872
873 cleanup_rganalysis (element);
874 }
875
876 GST_END_TEST;
877
GST_START_TEST(test_peak_int16_16)878 GST_START_TEST (test_peak_int16_16)
879 {
880 GstElement *element = setup_rganalysis ();
881 GstTagList *tag_list;
882
883 set_playing_state (element);
884
885 /* Half amplitude. */
886 send_stream_start_event (element);
887 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
888 send_segment_event (element);
889 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 1 << 14, 0));
890 send_eos_event (element);
891 tag_list = poll_tags_followed_by_eos (element);
892 fail_unless_track_peak (tag_list, 0.5);
893 gst_tag_list_unref (tag_list);
894
895 /* Swapped channels. */
896 send_flush_events (element);
897 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
898 send_segment_event (element);
899 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, 1 << 14));
900 send_eos_event (element);
901 tag_list = poll_tags_followed_by_eos (element);
902 fail_unless_track_peak (tag_list, 0.5);
903 gst_tag_list_unref (tag_list);
904
905 /* Mono. */
906 send_flush_events (element);
907 send_caps_event (GST_AUDIO_NE (S16), 8000, 1);
908 send_segment_event (element);
909 push_buffer (test_buffer_const_int16_mono (8000, 16, 512, 1 << 14));
910 send_eos_event (element);
911 tag_list = poll_tags_followed_by_eos (element);
912 fail_unless_track_peak (tag_list, 0.5);
913 gst_tag_list_unref (tag_list);
914
915 /* Half amplitude, negative variant. */
916 send_flush_events (element);
917 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
918 send_segment_event (element);
919 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, -(1 << 14), 0));
920 send_eos_event (element);
921 tag_list = poll_tags_followed_by_eos (element);
922 fail_unless_track_peak (tag_list, 0.5);
923 gst_tag_list_unref (tag_list);
924
925 /* Swapped channels. */
926 send_flush_events (element);
927 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
928 send_segment_event (element);
929 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, -(1 << 14)));
930 send_eos_event (element);
931 tag_list = poll_tags_followed_by_eos (element);
932 fail_unless_track_peak (tag_list, 0.5);
933 gst_tag_list_unref (tag_list);
934
935 /* Mono. */
936 send_flush_events (element);
937 send_caps_event (GST_AUDIO_NE (S16), 8000, 1);
938 send_segment_event (element);
939 push_buffer (test_buffer_const_int16_mono (8000, 16, 512, -(1 << 14)));
940 send_eos_event (element);
941 tag_list = poll_tags_followed_by_eos (element);
942 fail_unless_track_peak (tag_list, 0.5);
943 gst_tag_list_unref (tag_list);
944
945
946 /* Now check for correct normalization of the peak value: Sample
947 * values of this format range from -32768 to 32767. So for the
948 * highest positive amplitude we do not reach 1.0, only for
949 * -32768! */
950
951 send_flush_events (element);
952 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
953 send_segment_event (element);
954 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 32767, 0));
955 send_eos_event (element);
956 tag_list = poll_tags_followed_by_eos (element);
957 fail_unless_track_peak (tag_list, 32767. / 32768.);
958 gst_tag_list_unref (tag_list);
959
960 /* Swapped channels. */
961 send_flush_events (element);
962 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
963 send_segment_event (element);
964 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, 32767));
965 send_eos_event (element);
966 tag_list = poll_tags_followed_by_eos (element);
967 fail_unless_track_peak (tag_list, 32767. / 32768.);
968 gst_tag_list_unref (tag_list);
969
970 /* Mono. */
971 send_flush_events (element);
972 send_caps_event (GST_AUDIO_NE (S16), 8000, 1);
973 send_segment_event (element);
974 push_buffer (test_buffer_const_int16_mono (8000, 16, 512, 32767));
975 send_eos_event (element);
976 tag_list = poll_tags_followed_by_eos (element);
977 fail_unless_track_peak (tag_list, 32767. / 32768.);
978 gst_tag_list_unref (tag_list);
979
980
981 /* Negative variant, reaching 1.0. */
982 send_flush_events (element);
983 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
984 send_segment_event (element);
985 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, -32768, 0));
986 send_eos_event (element);
987 tag_list = poll_tags_followed_by_eos (element);
988 fail_unless_track_peak (tag_list, 1.0);
989 gst_tag_list_unref (tag_list);
990
991 /* Swapped channels. */
992 send_flush_events (element);
993 send_caps_event (GST_AUDIO_NE (S16), 8000, 2);
994 send_segment_event (element);
995 push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, -32768));
996 send_eos_event (element);
997 tag_list = poll_tags_followed_by_eos (element);
998 fail_unless_track_peak (tag_list, 1.0);
999 gst_tag_list_unref (tag_list);
1000
1001 /* Mono. */
1002 send_flush_events (element);
1003 send_caps_event (GST_AUDIO_NE (S16), 8000, 1);
1004 send_segment_event (element);
1005 push_buffer (test_buffer_const_int16_mono (8000, 16, 512, -32768));
1006 send_eos_event (element);
1007 tag_list = poll_tags_followed_by_eos (element);
1008 fail_unless_track_peak (tag_list, 1.0);
1009 gst_tag_list_unref (tag_list);
1010
1011 cleanup_rganalysis (element);
1012 }
1013
1014 GST_END_TEST;
1015
GST_START_TEST(test_peak_album)1016 GST_START_TEST (test_peak_album)
1017 {
1018 GstElement *element = setup_rganalysis ();
1019 GstTagList *tag_list;
1020
1021 g_object_set (element, "num-tracks", 2, NULL);
1022 set_playing_state (element);
1023
1024 send_stream_start_event (element);
1025 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
1026 send_segment_event (element);
1027 push_buffer (test_buffer_const_float_stereo (8000, 1024, 1.0, 0.0));
1028 send_eos_event (element);
1029 tag_list = poll_tags_followed_by_eos (element);
1030 fail_unless_track_peak (tag_list, 1.0);
1031 fail_if_album_tags (tag_list);
1032 gst_tag_list_unref (tag_list);
1033 fail_unless_num_tracks (element, 1);
1034
1035 send_flush_events (element);
1036 send_segment_event (element);
1037 push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.0, 0.5));
1038 send_eos_event (element);
1039 tag_list = poll_tags_followed_by_eos (element);
1040 fail_unless_track_peak (tag_list, 0.5);
1041 fail_unless_album_peak (tag_list, 1.0);
1042 gst_tag_list_unref (tag_list);
1043 fail_unless_num_tracks (element, 0);
1044
1045 /* Try a second album: */
1046 g_object_set (element, "num-tracks", 3, NULL);
1047
1048 send_flush_events (element);
1049 send_segment_event (element);
1050 push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.4, 0.4));
1051 send_eos_event (element);
1052 tag_list = poll_tags_followed_by_eos (element);
1053 fail_unless_track_peak (tag_list, 0.4);
1054 fail_if_album_tags (tag_list);
1055 gst_tag_list_unref (tag_list);
1056 fail_unless_num_tracks (element, 2);
1057
1058 send_flush_events (element);
1059 send_segment_event (element);
1060 push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.45, 0.45));
1061 send_eos_event (element);
1062 tag_list = poll_tags_followed_by_eos (element);
1063 fail_unless_track_peak (tag_list, 0.45);
1064 fail_if_album_tags (tag_list);
1065 gst_tag_list_unref (tag_list);
1066 fail_unless_num_tracks (element, 1);
1067
1068 send_flush_events (element);
1069 send_segment_event (element);
1070 push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.2, 0.2));
1071 send_eos_event (element);
1072 tag_list = poll_tags_followed_by_eos (element);
1073 fail_unless_track_peak (tag_list, 0.2);
1074 fail_unless_album_peak (tag_list, 0.45);
1075 gst_tag_list_unref (tag_list);
1076 fail_unless_num_tracks (element, 0);
1077
1078 /* And now a single track, not in album mode (num-tracks is 0
1079 * now): */
1080 send_flush_events (element);
1081 send_segment_event (element);
1082 push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.1, 0.1));
1083 send_eos_event (element);
1084 tag_list = poll_tags_followed_by_eos (element);
1085 fail_unless_track_peak (tag_list, 0.1);
1086 fail_if_album_tags (tag_list);
1087 gst_tag_list_unref (tag_list);
1088
1089 cleanup_rganalysis (element);
1090 }
1091
1092 GST_END_TEST;
1093
1094 /* Switching from track to album mode. */
1095
GST_START_TEST(test_peak_track_album)1096 GST_START_TEST (test_peak_track_album)
1097 {
1098 GstElement *element = setup_rganalysis ();
1099 GstTagList *tag_list;
1100
1101 set_playing_state (element);
1102
1103 send_stream_start_event (element);
1104 send_caps_event (GST_AUDIO_NE (F32), 8000, 1);
1105 send_segment_event (element);
1106 push_buffer (test_buffer_const_float_mono (8000, 1024, 1.0));
1107 send_eos_event (element);
1108 tag_list = poll_tags_followed_by_eos (element);
1109 fail_unless_track_peak (tag_list, 1.0);
1110 fail_if_album_tags (tag_list);
1111 gst_tag_list_unref (tag_list);
1112
1113 g_object_set (element, "num-tracks", 1, NULL);
1114 send_flush_events (element);
1115 send_segment_event (element);
1116 push_buffer (test_buffer_const_float_mono (8000, 1024, 0.5));
1117 send_eos_event (element);
1118 tag_list = poll_tags_followed_by_eos (element);
1119 fail_unless_track_peak (tag_list, 0.5);
1120 fail_unless_album_peak (tag_list, 0.5);
1121 gst_tag_list_unref (tag_list);
1122 fail_unless_num_tracks (element, 0);
1123
1124 cleanup_rganalysis (element);
1125 }
1126
1127 GST_END_TEST;
1128
1129 /* Disabling album processing before the end of the album. Probably a rare edge
1130 * case and applications should not rely on this to work. They need to send the
1131 * element to the READY state to clear up after an aborted album anyway since
1132 * they might need to process another album afterwards. */
1133
GST_START_TEST(test_peak_album_abort_to_track)1134 GST_START_TEST (test_peak_album_abort_to_track)
1135 {
1136 GstElement *element = setup_rganalysis ();
1137 GstTagList *tag_list;
1138
1139 g_object_set (element, "num-tracks", 2, NULL);
1140 set_playing_state (element);
1141
1142 send_stream_start_event (element);
1143 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
1144 send_segment_event (element);
1145 push_buffer (test_buffer_const_float_stereo (8000, 1024, 1.0, 0.0));
1146 send_eos_event (element);
1147 tag_list = poll_tags_followed_by_eos (element);
1148 fail_unless_track_peak (tag_list, 1.0);
1149 fail_if_album_tags (tag_list);
1150 gst_tag_list_unref (tag_list);
1151 fail_unless_num_tracks (element, 1);
1152
1153 g_object_set (element, "num-tracks", 0, NULL);
1154
1155 send_flush_events (element);
1156 send_segment_event (element);
1157 push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.0, 0.5));
1158 send_eos_event (element);
1159 tag_list = poll_tags_followed_by_eos (element);
1160 fail_unless_track_peak (tag_list, 0.5);
1161 fail_if_album_tags (tag_list);
1162 gst_tag_list_unref (tag_list);
1163
1164 cleanup_rganalysis (element);
1165 }
1166
1167 GST_END_TEST;
1168
GST_START_TEST(test_gain_album)1169 GST_START_TEST (test_gain_album)
1170 {
1171 GstElement *element = setup_rganalysis ();
1172 GstTagList *tag_list;
1173 gint accumulator;
1174 gint i;
1175
1176 g_object_set (element, "num-tracks", 3, NULL);
1177 set_playing_state (element);
1178
1179 /* The three tracks are constructed such that if any of these is in fact
1180 * ignored for the album gain, the album gain will differ. */
1181 send_stream_start_event (element);
1182 send_caps_event (GST_AUDIO_NE (F32), 44100, 2);
1183 send_segment_event (element);
1184 accumulator = 0;
1185 for (i = 8; i--;)
1186 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1187 0.75, 0.75));
1188 send_eos_event (element);
1189 tag_list = poll_tags_followed_by_eos (element);
1190 fail_unless_track_peak (tag_list, 0.75);
1191 fail_unless_track_gain (tag_list, -15.70);
1192 fail_if_album_tags (tag_list);
1193 gst_tag_list_unref (tag_list);
1194
1195 send_flush_events (element);
1196 send_segment_event (element);
1197 accumulator = 0;
1198 for (i = 12; i--;)
1199 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1200 0.5, 0.5));
1201 send_eos_event (element);
1202 tag_list = poll_tags_followed_by_eos (element);
1203 fail_unless_track_peak (tag_list, 0.5);
1204 fail_unless_track_gain (tag_list, -12.22);
1205 fail_if_album_tags (tag_list);
1206 gst_tag_list_unref (tag_list);
1207
1208 send_flush_events (element);
1209 send_segment_event (element);
1210 accumulator = 0;
1211 for (i = 180; i--;)
1212 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1213 0.25, 0.25));
1214 send_eos_event (element);
1215
1216 tag_list = poll_tags_followed_by_eos (element);
1217 fail_unless_track_peak (tag_list, 0.25);
1218 fail_unless_track_gain (tag_list, -6.20);
1219 fail_unless_album_peak (tag_list, 0.75);
1220 /* Strangely, wavegain reports -12.17 for the album, but the fixed
1221 * metaflac agrees to us. Could be a 32767 vs. 32768 issue. */
1222 fail_unless_album_gain (tag_list, -12.18);
1223 gst_tag_list_unref (tag_list);
1224
1225 cleanup_rganalysis (element);
1226 }
1227
1228 GST_END_TEST;
1229
1230 /* Checks ensuring that the "forced" property works as advertised. */
1231
GST_START_TEST(test_forced)1232 GST_START_TEST (test_forced)
1233 {
1234 GstElement *element = setup_rganalysis ();
1235 GstTagList *tag_list;
1236 gint accumulator = 0;
1237 gint i;
1238
1239 g_object_set (element, "forced", FALSE, NULL);
1240 set_playing_state (element);
1241
1242 send_stream_start_event (element);
1243 send_caps_event (GST_AUDIO_NE (F32), 44100, 2);
1244 send_segment_event (element);
1245 tag_list = gst_tag_list_new_empty ();
1246 /* Provided values are totally arbitrary. */
1247 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1248 GST_TAG_TRACK_PEAK, 1.0, GST_TAG_TRACK_GAIN, 2.21, NULL);
1249 send_tag_event (element, tag_list);
1250
1251 for (i = 20; i--;)
1252 push_buffer (test_buffer_const_float_stereo (44100, 512, 0.5, 0.5));
1253 send_eos_event (element);
1254
1255 /* This fails if a tag message is generated: */
1256 /* Same values as above */
1257 tag_list = poll_tags_followed_by_eos (element);
1258 fail_unless_track_gain (tag_list, 2.21);
1259 fail_unless_track_peak (tag_list, 1.0);
1260 gst_tag_list_unref (tag_list);
1261
1262 /* Now back to a track without tags. */
1263 send_flush_events (element);
1264 send_segment_event (element);
1265 for (i = 20; i--;)
1266 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1267 0.25, 0.25));
1268 send_eos_event (element);
1269 tag_list = poll_tags_followed_by_eos (element);
1270 fail_unless_track_peak (tag_list, 0.25);
1271 fail_unless_track_gain (tag_list, get_expected_gain (44100));
1272 gst_tag_list_unref (tag_list);
1273
1274 cleanup_rganalysis (element);
1275 }
1276
1277 GST_END_TEST;
1278
1279 /* Sending track gain and peak in separate tag lists. */
1280
GST_START_TEST(test_forced_separate)1281 GST_START_TEST (test_forced_separate)
1282 {
1283 GstElement *element = setup_rganalysis ();
1284 GstTagList *tag_list;
1285 gint accumulator = 0;
1286 gint i;
1287
1288 g_object_set (element, "forced", FALSE, NULL);
1289 set_playing_state (element);
1290
1291 send_stream_start_event (element);
1292 send_caps_event (GST_AUDIO_NE (F32), 44100, 2);
1293 send_segment_event (element);
1294 tag_list = gst_tag_list_new_empty ();
1295 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, GST_TAG_TRACK_GAIN, 2.21,
1296 NULL);
1297 send_tag_event (element, tag_list);
1298
1299 tag_list = gst_tag_list_new_empty ();
1300 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, GST_TAG_TRACK_PEAK, 1.0,
1301 NULL);
1302 send_tag_event (element, tag_list);
1303
1304 for (i = 20; i--;)
1305 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1306 0.5, 0.5));
1307 send_eos_event (element);
1308
1309 /* Same values as above */
1310 tag_list = poll_tags_only (element);
1311 fail_unless_track_gain (tag_list, 2.21);
1312 gst_tag_list_unref (tag_list);
1313
1314 tag_list = poll_tags_followed_by_eos (element);
1315 fail_unless_track_peak (tag_list, 1.0);
1316 gst_tag_list_unref (tag_list);
1317
1318 /* Now a track without tags. */
1319 send_flush_events (element);
1320 send_segment_event (element);
1321 accumulator = 0;
1322 for (i = 20; i--;)
1323 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1324 0.25, 0.25));
1325 send_eos_event (element);
1326 tag_list = poll_tags_followed_by_eos (element);
1327 fail_unless_track_peak (tag_list, 0.25);
1328 fail_unless_track_gain (tag_list, get_expected_gain (44100));
1329 fail_if_album_tags (tag_list);
1330 gst_tag_list_unref (tag_list);
1331
1332 cleanup_rganalysis (element);
1333 }
1334
1335 GST_END_TEST;
1336
1337 /* A TAG event is sent _after_ data has already been processed. In real
1338 * pipelines, this could happen if there is more than one rganalysis element (by
1339 * accident). While it would have analyzed all the data prior to receiving the
1340 * event, I expect it to not post its results if not forced. This test is
1341 * almost equivalent to test_forced. */
1342
GST_START_TEST(test_forced_after_data)1343 GST_START_TEST (test_forced_after_data)
1344 {
1345 GstElement *element = setup_rganalysis ();
1346 GstTagList *tag_list;
1347 gint accumulator = 0;
1348 gint i;
1349
1350 g_object_set (element, "forced", FALSE, NULL);
1351 set_playing_state (element);
1352
1353 send_stream_start_event (element);
1354 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
1355 send_segment_event (element);
1356 for (i = 20; i--;)
1357 push_buffer (test_buffer_const_float_stereo (8000, 512, 0.5, 0.5));
1358
1359 tag_list = gst_tag_list_new_empty ();
1360 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1361 GST_TAG_TRACK_PEAK, 1.0, GST_TAG_TRACK_GAIN, 2.21, NULL);
1362 send_tag_event (element, tag_list);
1363
1364 send_eos_event (element);
1365
1366 /* Same values as above */
1367 tag_list = poll_tags_followed_by_eos (element);
1368 fail_unless_track_gain (tag_list, 2.21);
1369 fail_unless_track_peak (tag_list, 1.0);
1370 gst_tag_list_unref (tag_list);
1371
1372 send_flush_events (element);
1373 send_segment_event (element);
1374 /* Now back to a normal track, this one has no tags: */
1375 for (i = 20; i--;)
1376 push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25,
1377 0.25));
1378 send_eos_event (element);
1379 tag_list = poll_tags_followed_by_eos (element);
1380 fail_unless_track_peak (tag_list, 0.25);
1381 fail_unless_track_gain (tag_list, get_expected_gain (8000));
1382 gst_tag_list_unref (tag_list);
1383
1384 cleanup_rganalysis (element);
1385 }
1386
1387 GST_END_TEST;
1388
1389 /* Like test_forced, but *analyze* an album afterwards. The two tests following
1390 * this one check the *skipping* of albums. */
1391
GST_START_TEST(test_forced_album)1392 GST_START_TEST (test_forced_album)
1393 {
1394 GstElement *element = setup_rganalysis ();
1395 GstTagList *tag_list;
1396 gint accumulator;
1397 gint i;
1398
1399 g_object_set (element, "forced", FALSE, NULL);
1400 set_playing_state (element);
1401
1402 send_stream_start_event (element);
1403 send_caps_event (GST_AUDIO_NE (F32), 44100, 2);
1404 send_segment_event (element);
1405 tag_list = gst_tag_list_new_empty ();
1406 /* Provided values are totally arbitrary. */
1407 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1408 GST_TAG_TRACK_PEAK, 1.0, GST_TAG_TRACK_GAIN, 2.21, NULL);
1409 send_tag_event (element, tag_list);
1410
1411 accumulator = 0;
1412 for (i = 20; i--;)
1413 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1414 0.5, 0.5));
1415 send_eos_event (element);
1416
1417 /* Same values as above */
1418 tag_list = poll_tags_followed_by_eos (element);
1419 fail_unless_track_gain (tag_list, 2.21);
1420 fail_unless_track_peak (tag_list, 1.0);
1421 gst_tag_list_unref (tag_list);
1422
1423 /* Now an album without tags. */
1424 g_object_set (element, "num-tracks", 2, NULL);
1425
1426 send_flush_events (element);
1427 send_segment_event (element);
1428 accumulator = 0;
1429 for (i = 20; i--;)
1430 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1431 0.25, 0.25));
1432 send_eos_event (element);
1433 tag_list = poll_tags_followed_by_eos (element);
1434 fail_unless_track_peak (tag_list, 0.25);
1435 fail_unless_track_gain (tag_list, get_expected_gain (44100));
1436 fail_if_album_tags (tag_list);
1437 gst_tag_list_unref (tag_list);
1438 fail_unless_num_tracks (element, 1);
1439
1440 send_flush_events (element);
1441 send_segment_event (element);
1442 accumulator = 0;
1443 for (i = 20; i--;)
1444 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1445 0.25, 0.25));
1446 send_eos_event (element);
1447 tag_list = poll_tags_followed_by_eos (element);
1448 fail_unless_track_peak (tag_list, 0.25);
1449 fail_unless_track_gain (tag_list, get_expected_gain (44100));
1450 fail_unless_album_peak (tag_list, 0.25);
1451 fail_unless_album_gain (tag_list, get_expected_gain (44100));
1452 gst_tag_list_unref (tag_list);
1453 fail_unless_num_tracks (element, 0);
1454
1455 cleanup_rganalysis (element);
1456 }
1457
1458 GST_END_TEST;
1459
GST_START_TEST(test_forced_album_skip)1460 GST_START_TEST (test_forced_album_skip)
1461 {
1462 GstElement *element = setup_rganalysis ();
1463 GstTagList *tag_list;
1464 gint accumulator = 0;
1465 gint i;
1466
1467 g_object_set (element, "forced", FALSE, "num-tracks", 2, NULL);
1468 set_playing_state (element);
1469
1470 send_stream_start_event (element);
1471 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
1472 send_segment_event (element);
1473 tag_list = gst_tag_list_new_empty ();
1474 /* Provided values are totally arbitrary. */
1475 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1476 GST_TAG_TRACK_PEAK, 0.75, GST_TAG_TRACK_GAIN, 2.21,
1477 GST_TAG_ALBUM_PEAK, 0.80, GST_TAG_ALBUM_GAIN, -0.11, NULL);
1478 send_tag_event (element, tag_list);
1479
1480 for (i = 20; i--;)
1481 push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25,
1482 0.25));
1483 send_eos_event (element);
1484
1485 /* Same values as above */
1486 tag_list = poll_tags_followed_by_eos (element);
1487 fail_unless_track_gain (tag_list, 2.21);
1488 fail_unless_track_peak (tag_list, 0.75);
1489 gst_tag_list_unref (tag_list);
1490
1491 fail_unless_num_tracks (element, 1);
1492
1493 /* This track has no tags, but needs to be skipped anyways since we
1494 * are in album processing mode. */
1495 send_flush_events (element);
1496 send_segment_event (element);
1497 for (i = 20; i--;)
1498 push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, 0.0));
1499 send_eos_event (element);
1500 poll_eos (element);
1501 fail_unless_num_tracks (element, 0);
1502
1503 /* Normal track after the album. Of course not to be skipped. */
1504 send_flush_events (element);
1505 send_segment_event (element);
1506 accumulator = 0;
1507 for (i = 20; i--;)
1508 push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25,
1509 0.25));
1510 send_eos_event (element);
1511 tag_list = poll_tags_followed_by_eos (element);
1512 fail_unless_track_peak (tag_list, 0.25);
1513 fail_unless_track_gain (tag_list, get_expected_gain (8000));
1514 fail_if_album_tags (tag_list);
1515 gst_tag_list_unref (tag_list);
1516
1517 cleanup_rganalysis (element);
1518 }
1519
1520 GST_END_TEST;
1521
GST_START_TEST(test_forced_album_no_skip)1522 GST_START_TEST (test_forced_album_no_skip)
1523 {
1524 GstElement *element = setup_rganalysis ();
1525 GstTagList *tag_list;
1526 gint accumulator = 0;
1527 gint i;
1528
1529 g_object_set (element, "forced", FALSE, "num-tracks", 2, NULL);
1530 set_playing_state (element);
1531
1532 send_stream_start_event (element);
1533 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
1534 send_segment_event (element);
1535 for (i = 20; i--;)
1536 push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25,
1537 0.25));
1538 send_eos_event (element);
1539 tag_list = poll_tags_followed_by_eos (element);
1540 fail_unless_track_peak (tag_list, 0.25);
1541 fail_unless_track_gain (tag_list, get_expected_gain (8000));
1542 fail_if_album_tags (tag_list);
1543 gst_tag_list_unref (tag_list);
1544 fail_unless_num_tracks (element, 1);
1545
1546 /* The second track has indeed full tags, but although being not forced, this
1547 * one has to be processed because album processing is on. */
1548 send_flush_events (element);
1549 send_segment_event (element);
1550 tag_list = gst_tag_list_new_empty ();
1551 /* Provided values are totally arbitrary. */
1552 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1553 GST_TAG_TRACK_PEAK, 0.75, GST_TAG_TRACK_GAIN, 2.21,
1554 GST_TAG_ALBUM_PEAK, 0.80, GST_TAG_ALBUM_GAIN, -0.11, NULL);
1555 send_tag_event (element, tag_list);
1556 for (i = 20; i--;)
1557 push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, 0.0));
1558 send_eos_event (element);
1559
1560 /* the first batch from the tags */
1561 tag_list = poll_tags_only (element);
1562 fail_unless_track_peak (tag_list, 0.75);
1563 fail_unless_track_gain (tag_list, 2.21);
1564 gst_tag_list_unref (tag_list);
1565
1566 /* the second from the processing */
1567 tag_list = poll_tags_followed_by_eos (element);
1568 fail_unless_track_peak (tag_list, 0.0);
1569 fail_unless_track_gain (tag_list, SILENCE_GAIN);
1570 /* Second track was just silence so the album peak equals the first
1571 * track's peak. */
1572 fail_unless_album_peak (tag_list, 0.25);
1573 /* Statistical processing leads to the second track being
1574 * ignored for the gain (because it is so short): */
1575 fail_unless_album_gain (tag_list, get_expected_gain (8000));
1576 gst_tag_list_unref (tag_list);
1577 fail_unless_num_tracks (element, 0);
1578
1579 cleanup_rganalysis (element);
1580 }
1581
1582 GST_END_TEST;
1583
GST_START_TEST(test_forced_abort_album_no_skip)1584 GST_START_TEST (test_forced_abort_album_no_skip)
1585 {
1586 GstElement *element = setup_rganalysis ();
1587 GstTagList *tag_list;
1588 gint accumulator = 0;
1589 gint i;
1590
1591 g_object_set (element, "forced", FALSE, "num-tracks", 2, NULL);
1592 set_playing_state (element);
1593
1594 send_stream_start_event (element);
1595 send_caps_event (GST_AUDIO_NE (F32), 8000, 2);
1596 send_segment_event (element);
1597 for (i = 20; i--;)
1598 push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25,
1599 0.25));
1600 send_eos_event (element);
1601 tag_list = poll_tags_followed_by_eos (element);
1602 fail_unless_track_peak (tag_list, 0.25);
1603 fail_unless_track_gain (tag_list, get_expected_gain (8000));
1604 fail_if_album_tags (tag_list);
1605 gst_tag_list_unref (tag_list);
1606 fail_unless_num_tracks (element, 1);
1607
1608 /* Disabling album processing before end of album: */
1609 g_object_set (element, "num-tracks", 0, NULL);
1610
1611 send_flush_events (element);
1612 send_segment_event (element);
1613
1614 /* Processing a track that has to be skipped. */
1615 tag_list = gst_tag_list_new_empty ();
1616 /* Provided values are totally arbitrary. */
1617 gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND,
1618 GST_TAG_TRACK_PEAK, 0.75, GST_TAG_TRACK_GAIN, 2.21,
1619 GST_TAG_ALBUM_PEAK, 0.80, GST_TAG_ALBUM_GAIN, -0.11, NULL);
1620 send_tag_event (element, tag_list);
1621 for (i = 20; i--;)
1622 push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, 0.0));
1623 send_eos_event (element);
1624
1625 tag_list = poll_tags_followed_by_eos (element);
1626 fail_unless_track_peak (tag_list, 0.75);
1627 fail_unless_track_gain (tag_list, 2.21);
1628 gst_tag_list_unref (tag_list);
1629
1630 cleanup_rganalysis (element);
1631 }
1632
1633 GST_END_TEST;
1634
GST_START_TEST(test_reference_level)1635 GST_START_TEST (test_reference_level)
1636 {
1637 GstElement *element = setup_rganalysis ();
1638 GstTagList *tag_list;
1639 gdouble ref_level;
1640 gint accumulator = 0;
1641 gint i;
1642
1643 set_playing_state (element);
1644
1645 send_stream_start_event (element);
1646 send_caps_event (GST_AUDIO_NE (F32), 44100, 2);
1647 send_segment_event (element);
1648 for (i = 20; i--;)
1649 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1650 0.25, 0.25));
1651 send_eos_event (element);
1652 tag_list = poll_tags_followed_by_eos (element);
1653 fail_unless_track_peak (tag_list, 0.25);
1654 fail_unless_track_gain (tag_list, get_expected_gain (44100));
1655 fail_if_album_tags (tag_list);
1656 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL,
1657 &ref_level) && MATCH_GAIN (ref_level, 89.),
1658 "Incorrect reference level tag");
1659 gst_tag_list_unref (tag_list);
1660
1661 g_object_set (element, "reference-level", 83., "num-tracks", 2, NULL);
1662
1663 send_flush_events (element);
1664 send_segment_event (element);
1665 for (i = 20; i--;)
1666 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1667 0.25, 0.25));
1668 send_eos_event (element);
1669 tag_list = poll_tags_followed_by_eos (element);
1670 fail_unless_track_peak (tag_list, 0.25);
1671 fail_unless_track_gain (tag_list, get_expected_gain (44100) - 6.);
1672 fail_if_album_tags (tag_list);
1673 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL,
1674 &ref_level) && MATCH_GAIN (ref_level, 83.),
1675 "Incorrect reference level tag");
1676 gst_tag_list_unref (tag_list);
1677
1678 send_flush_events (element);
1679 send_segment_event (element);
1680 accumulator = 0;
1681 for (i = 20; i--;)
1682 push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512,
1683 0.25, 0.25));
1684 send_eos_event (element);
1685 tag_list = poll_tags_followed_by_eos (element);
1686 fail_unless_track_peak (tag_list, 0.25);
1687 fail_unless_track_gain (tag_list, get_expected_gain (44100) - 6.);
1688 fail_unless_album_peak (tag_list, 0.25);
1689 /* We provided the same waveform twice, with a reset separating
1690 * them. Therefore, the album gain matches the track gain. */
1691 fail_unless_album_gain (tag_list, get_expected_gain (44100) - 6.);
1692 fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL,
1693 &ref_level) && MATCH_GAIN (ref_level, 83.),
1694 "Incorrect reference level tag");
1695 gst_tag_list_unref (tag_list);
1696
1697 cleanup_rganalysis (element);
1698 }
1699
1700 GST_END_TEST;
1701
GST_START_TEST(test_all_formats)1702 GST_START_TEST (test_all_formats)
1703 {
1704 GstElement *element = setup_rganalysis ();
1705 GstTagList *tag_list;
1706 gint accumulator = 0;
1707 gint i, j;
1708
1709 set_playing_state (element);
1710 send_stream_start_event (element);
1711 for (i = G_N_ELEMENTS (supported_rates); i--;) {
1712 send_flush_events (element);
1713 send_caps_event (GST_AUDIO_NE (F32), supported_rates[i].sample_rate, 2);
1714 send_segment_event (element);
1715 accumulator = 0;
1716 for (j = 0; j < 4; j++)
1717 push_buffer (test_buffer_square_float_stereo (&accumulator,
1718 supported_rates[i].sample_rate, 512, 0.25, 0.25));
1719 send_caps_event (GST_AUDIO_NE (F32), supported_rates[i].sample_rate, 1);
1720 for (j = 0; j < 3; j++)
1721 push_buffer (test_buffer_square_float_mono (&accumulator,
1722 supported_rates[i].sample_rate, 512, 0.25));
1723 send_caps_event (GST_AUDIO_NE (S16), supported_rates[i].sample_rate, 2);
1724 for (j = 0; j < 4; j++)
1725 push_buffer (test_buffer_square_int16_stereo (&accumulator,
1726 supported_rates[i].sample_rate, 16, 512, 1 << 13, 1 << 13));
1727 send_caps_event (GST_AUDIO_NE (S16), supported_rates[i].sample_rate, 1);
1728 for (j = 0; j < 3; j++)
1729 push_buffer (test_buffer_square_int16_mono (&accumulator,
1730 supported_rates[i].sample_rate, 16, 512, 1 << 13));
1731 send_eos_event (element);
1732 tag_list = poll_tags_followed_by_eos (element);
1733 fail_unless_track_peak (tag_list, 0.25);
1734 fail_unless_track_gain (tag_list, supported_rates[i].gain);
1735 gst_tag_list_unref (tag_list);
1736 }
1737
1738 cleanup_rganalysis (element);
1739 }
1740
1741 GST_END_TEST;
1742
1743 /* Checks ensuring all advertised supported sample rates are really
1744 * accepted, for integer and float, mono and stereo. This also
1745 * verifies that the correct gain is computed for all formats (except
1746 * odd bit depths). */
1747
1748 #define MAKE_GAIN_TEST_FLOAT_MONO(sample_rate) \
1749 GST_START_TEST (test_gain_float_mono_##sample_rate) \
1750 { \
1751 GstElement *element = setup_rganalysis (); \
1752 GstTagList *tag_list; \
1753 gint accumulator = 0; \
1754 gint i; \
1755 \
1756 set_playing_state (element); \
1757 send_stream_start_event (element); \
1758 send_caps_event (GST_AUDIO_NE (F32), sample_rate, 1); \
1759 send_segment_event (element); \
1760 \
1761 for (i = 0; i < 20; i++) \
1762 push_buffer (test_buffer_square_float_mono (&accumulator, \
1763 sample_rate, 512, 0.25)); \
1764 send_eos_event (element); \
1765 tag_list = poll_tags_followed_by_eos (element); \
1766 fail_unless_track_peak (tag_list, 0.25); \
1767 fail_unless_track_gain (tag_list, \
1768 get_expected_gain (sample_rate)); \
1769 gst_tag_list_unref (tag_list); \
1770 \
1771 cleanup_rganalysis (element); \
1772 } \
1773 \
1774 GST_END_TEST;
1775
1776 #define MAKE_GAIN_TEST_FLOAT_STEREO(sample_rate) \
1777 GST_START_TEST (test_gain_float_stereo_##sample_rate) \
1778 { \
1779 GstElement *element = setup_rganalysis (); \
1780 GstTagList *tag_list; \
1781 gint accumulator = 0; \
1782 gint i; \
1783 \
1784 set_playing_state (element); \
1785 send_stream_start_event (element); \
1786 send_caps_event (GST_AUDIO_NE (F32), sample_rate, 2); \
1787 send_segment_event (element); \
1788 \
1789 for (i = 0; i < 20; i++) \
1790 push_buffer (test_buffer_square_float_stereo (&accumulator, \
1791 sample_rate, 512, 0.25, 0.25)); \
1792 send_eos_event (element); \
1793 tag_list = poll_tags_followed_by_eos (element); \
1794 fail_unless_track_peak (tag_list, 0.25); \
1795 fail_unless_track_gain (tag_list, \
1796 get_expected_gain (sample_rate)); \
1797 gst_tag_list_unref (tag_list); \
1798 \
1799 cleanup_rganalysis (element); \
1800 } \
1801 \
1802 GST_END_TEST;
1803
1804 #define MAKE_GAIN_TEST_INT16_MONO(sample_rate, depth) \
1805 GST_START_TEST (test_gain_int16_##depth##_mono_##sample_rate) \
1806 { \
1807 GstElement *element = setup_rganalysis (); \
1808 GstTagList *tag_list; \
1809 gint accumulator = 0; \
1810 gint i; \
1811 \
1812 set_playing_state (element); \
1813 send_stream_start_event (element); \
1814 send_caps_event (GST_AUDIO_NE (S16), sample_rate, 1); \
1815 send_segment_event (element); \
1816 \
1817 for (i = 0; i < 20; i++) \
1818 push_buffer (test_buffer_square_int16_mono (&accumulator, \
1819 sample_rate, depth, 512, 1 << (13 + depth - 16))); \
1820 \
1821 send_eos_event (element); \
1822 tag_list = poll_tags_followed_by_eos (element); \
1823 fail_unless_track_peak (tag_list, 0.25); \
1824 fail_unless_track_gain (tag_list, \
1825 get_expected_gain (sample_rate)); \
1826 gst_tag_list_unref (tag_list); \
1827 \
1828 cleanup_rganalysis (element); \
1829 } \
1830 \
1831 GST_END_TEST;
1832
1833 #define MAKE_GAIN_TEST_INT16_STEREO(sample_rate, depth) \
1834 GST_START_TEST (test_gain_int16_##depth##_stereo_##sample_rate) \
1835 { \
1836 GstElement *element = setup_rganalysis (); \
1837 GstTagList *tag_list; \
1838 gint accumulator = 0; \
1839 gint i; \
1840 \
1841 set_playing_state (element); \
1842 send_stream_start_event (element); \
1843 send_caps_event (GST_AUDIO_NE (S16), sample_rate, 2); \
1844 send_segment_event (element); \
1845 \
1846 for (i = 0; i < 20; i++) \
1847 push_buffer (test_buffer_square_int16_stereo (&accumulator, \
1848 sample_rate, depth, 512, 1 << (13 + depth - 16), \
1849 1 << (13 + depth - 16))); \
1850 send_eos_event (element); \
1851 tag_list = poll_tags_followed_by_eos (element); \
1852 fail_unless_track_peak (tag_list, 0.25); \
1853 fail_unless_track_gain (tag_list, \
1854 get_expected_gain (sample_rate)); \
1855 gst_tag_list_unref (tag_list); \
1856 \
1857 cleanup_rganalysis (element); \
1858 } \
1859 \
1860 GST_END_TEST;
1861
1862 MAKE_GAIN_TEST_FLOAT_MONO (8000);
1863 MAKE_GAIN_TEST_FLOAT_MONO (11025);
1864 MAKE_GAIN_TEST_FLOAT_MONO (12000);
1865 MAKE_GAIN_TEST_FLOAT_MONO (16000);
1866 MAKE_GAIN_TEST_FLOAT_MONO (22050);
1867 MAKE_GAIN_TEST_FLOAT_MONO (24000);
1868 MAKE_GAIN_TEST_FLOAT_MONO (32000);
1869 MAKE_GAIN_TEST_FLOAT_MONO (44100);
1870 MAKE_GAIN_TEST_FLOAT_MONO (48000);
1871
1872 MAKE_GAIN_TEST_FLOAT_STEREO (8000);
1873 MAKE_GAIN_TEST_FLOAT_STEREO (11025);
1874 MAKE_GAIN_TEST_FLOAT_STEREO (12000);
1875 MAKE_GAIN_TEST_FLOAT_STEREO (16000);
1876 MAKE_GAIN_TEST_FLOAT_STEREO (22050);
1877 MAKE_GAIN_TEST_FLOAT_STEREO (24000);
1878 MAKE_GAIN_TEST_FLOAT_STEREO (32000);
1879 MAKE_GAIN_TEST_FLOAT_STEREO (44100);
1880 MAKE_GAIN_TEST_FLOAT_STEREO (48000);
1881
1882 MAKE_GAIN_TEST_INT16_MONO (8000, 16);
1883 MAKE_GAIN_TEST_INT16_MONO (11025, 16);
1884 MAKE_GAIN_TEST_INT16_MONO (12000, 16);
1885 MAKE_GAIN_TEST_INT16_MONO (16000, 16);
1886 MAKE_GAIN_TEST_INT16_MONO (22050, 16);
1887 MAKE_GAIN_TEST_INT16_MONO (24000, 16);
1888 MAKE_GAIN_TEST_INT16_MONO (32000, 16);
1889 MAKE_GAIN_TEST_INT16_MONO (44100, 16);
1890 MAKE_GAIN_TEST_INT16_MONO (48000, 16);
1891
1892 MAKE_GAIN_TEST_INT16_STEREO (8000, 16);
1893 MAKE_GAIN_TEST_INT16_STEREO (11025, 16);
1894 MAKE_GAIN_TEST_INT16_STEREO (12000, 16);
1895 MAKE_GAIN_TEST_INT16_STEREO (16000, 16);
1896 MAKE_GAIN_TEST_INT16_STEREO (22050, 16);
1897 MAKE_GAIN_TEST_INT16_STEREO (24000, 16);
1898 MAKE_GAIN_TEST_INT16_STEREO (32000, 16);
1899 MAKE_GAIN_TEST_INT16_STEREO (44100, 16);
1900 MAKE_GAIN_TEST_INT16_STEREO (48000, 16);
1901
1902 static Suite *
rganalysis_suite(void)1903 rganalysis_suite (void)
1904 {
1905 Suite *s = suite_create ("rganalysis");
1906 TCase *tc_chain = tcase_create ("general");
1907
1908 suite_add_tcase (s, tc_chain);
1909
1910 tcase_add_test (tc_chain, test_no_buffer);
1911 tcase_add_test (tc_chain, test_no_buffer_album_1);
1912 tcase_add_test (tc_chain, test_no_buffer_album_2);
1913 tcase_add_test (tc_chain, test_empty_buffers);
1914
1915 tcase_add_test (tc_chain, test_peak_float);
1916 tcase_add_test (tc_chain, test_peak_int16_16);
1917
1918 tcase_add_test (tc_chain, test_peak_album);
1919 tcase_add_test (tc_chain, test_peak_track_album);
1920 tcase_add_test (tc_chain, test_peak_album_abort_to_track);
1921
1922 tcase_add_test (tc_chain, test_gain_album);
1923
1924 tcase_add_test (tc_chain, test_forced);
1925 tcase_add_test (tc_chain, test_forced_separate);
1926 tcase_add_test (tc_chain, test_forced_after_data);
1927 tcase_add_test (tc_chain, test_forced_album);
1928 tcase_add_test (tc_chain, test_forced_album_skip);
1929 tcase_add_test (tc_chain, test_forced_album_no_skip);
1930 tcase_add_test (tc_chain, test_forced_abort_album_no_skip);
1931
1932 tcase_add_test (tc_chain, test_reference_level);
1933
1934 tcase_add_test (tc_chain, test_all_formats);
1935
1936 tcase_add_test (tc_chain, test_gain_float_mono_8000);
1937 tcase_add_test (tc_chain, test_gain_float_mono_11025);
1938 tcase_add_test (tc_chain, test_gain_float_mono_12000);
1939 tcase_add_test (tc_chain, test_gain_float_mono_16000);
1940 tcase_add_test (tc_chain, test_gain_float_mono_22050);
1941 tcase_add_test (tc_chain, test_gain_float_mono_24000);
1942 tcase_add_test (tc_chain, test_gain_float_mono_32000);
1943 tcase_add_test (tc_chain, test_gain_float_mono_44100);
1944 tcase_add_test (tc_chain, test_gain_float_mono_48000);
1945
1946 tcase_add_test (tc_chain, test_gain_float_stereo_8000);
1947 tcase_add_test (tc_chain, test_gain_float_stereo_11025);
1948 tcase_add_test (tc_chain, test_gain_float_stereo_12000);
1949 tcase_add_test (tc_chain, test_gain_float_stereo_16000);
1950 tcase_add_test (tc_chain, test_gain_float_stereo_22050);
1951 tcase_add_test (tc_chain, test_gain_float_stereo_24000);
1952 tcase_add_test (tc_chain, test_gain_float_stereo_32000);
1953 tcase_add_test (tc_chain, test_gain_float_stereo_44100);
1954 tcase_add_test (tc_chain, test_gain_float_stereo_48000);
1955
1956 tcase_add_test (tc_chain, test_gain_int16_16_mono_8000);
1957 tcase_add_test (tc_chain, test_gain_int16_16_mono_11025);
1958 tcase_add_test (tc_chain, test_gain_int16_16_mono_12000);
1959 tcase_add_test (tc_chain, test_gain_int16_16_mono_16000);
1960 tcase_add_test (tc_chain, test_gain_int16_16_mono_22050);
1961 tcase_add_test (tc_chain, test_gain_int16_16_mono_24000);
1962 tcase_add_test (tc_chain, test_gain_int16_16_mono_32000);
1963 tcase_add_test (tc_chain, test_gain_int16_16_mono_44100);
1964 tcase_add_test (tc_chain, test_gain_int16_16_mono_48000);
1965
1966 tcase_add_test (tc_chain, test_gain_int16_16_stereo_8000);
1967 tcase_add_test (tc_chain, test_gain_int16_16_stereo_11025);
1968 tcase_add_test (tc_chain, test_gain_int16_16_stereo_12000);
1969 tcase_add_test (tc_chain, test_gain_int16_16_stereo_16000);
1970 tcase_add_test (tc_chain, test_gain_int16_16_stereo_22050);
1971 tcase_add_test (tc_chain, test_gain_int16_16_stereo_24000);
1972 tcase_add_test (tc_chain, test_gain_int16_16_stereo_32000);
1973 tcase_add_test (tc_chain, test_gain_int16_16_stereo_44100);
1974 tcase_add_test (tc_chain, test_gain_int16_16_stereo_48000);
1975
1976 return s;
1977 }
1978
1979 GST_CHECK_MAIN (rganalysis);
1980