• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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", &current, 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