| /* GStreamer ReplayGain analysis |
| * |
| * Copyright (C) 2006 Rene Stadler <mail@renestadler.de> |
| * |
| * rganalysis.c: Unit test for the rganalysis element |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public License |
| * as published by the Free Software Foundation; either version 2.1 of |
| * the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| * 02110-1301 USA |
| */ |
| |
| /* Some things to note about the RMS window length of the analysis algorithm and |
| * thus the implementation used in the element: Processing divides input data |
| * into 50ms windows at some point. Some details about this that normally do |
| * not matter: |
| * |
| * 1. At the end of a stream, the remainder of data that did not fill up the |
| * last 50ms window is simply discarded. |
| * |
| * 2. If the sample rate changes during a stream, the currently running window |
| * is discarded and the equal loudness filter gets reset as if a new stream |
| * started. |
| * |
| * 3. For the album gain, it is not entirely correct to think of obtaining it |
| * like "as if all the tracks are analyzed as one track". There isn't a |
| * separate window being tracked for album processing, so at stream (track) |
| * end, the remaining unfilled window does not contribute to the album gain |
| * either. |
| * |
| * 4. If a waveform with a result gain G is concatenated to itself and the |
| * result processed as a track, the gain can be different from G if and only |
| * if the duration of the original waveform is not an integer multiple of |
| * 50ms. If the original waveform gets processed as a single track and then |
| * the same data again as a subsequent track, the album result gain will |
| * always match G (this is implied by 3.). |
| * |
| * 5. A stream shorter than 50ms cannot be analyzed. At 8000 and 48000 Hz, |
| * this corresponds to 400 resp. 2400 frames. If a stream is shorter than |
| * 50ms, the element will not generate tags at EOS (only if an album |
| * finished, but only album tags are generated then). This is not an |
| * erroneous condition, the element should behave normally. |
| * |
| * The limitations outlined in 1.-4. do not apply to the peak values. Every |
| * single sample is accounted for when looking for the peak. Thus the album |
| * peak is guaranteed to be the maximum value of all track peaks. |
| * |
| * In normal day-to-day use, these little facts are unlikely to be relevant, but |
| * they have to be kept in mind for writing the tests here. |
| */ |
| |
| #include <gst/check/gstcheck.h> |
| #include <gst/audio/audio.h> |
| |
| /* For ease of programming we use globals to keep refs for our floating src and |
| * sink pads we create; otherwise we always have to do get_pad, get_peer, and |
| * then remove references in every test function */ |
| static GstPad *mysrcpad, *mysinkpad; |
| static GstBus *mybus; |
| |
| /* Mapping from supported sample rates to the correct result gain for the |
| * following test waveform: 20 * 512 samples with a quarter-full amplitude of |
| * toggling sign, changing every 48 samples and starting with the positive |
| * value. |
| * |
| * Even if we would generate a wave describing a signal with the same frequency |
| * at each sampling rate, the results would vary (slightly). Hence the simple |
| * generation method, since we cannot use a constant value as expected result |
| * anyways. For all sample rates, changing the sign every 48 frames gives a |
| * sane frequency. Buffers containing data that forms such a waveform is |
| * created using the test_buffer_square_{float,int16}_{mono,stereo} functions |
| * below. |
| * |
| * The results have been checked against what the metaflac and wavegain programs |
| * generate for such a stream. If you want to verify these, be sure that the |
| * metaflac program does not produce incorrect results in your environment: I |
| * found a strange bug in the (defacto) reference code for the analysis that |
| * sometimes leads to incorrect RMS window lengths. */ |
| |
| struct rate_test |
| { |
| guint sample_rate; |
| gdouble gain; |
| }; |
| |
| static const struct rate_test supported_rates[] = { |
| {8000, -0.91}, |
| {11025, -2.80}, |
| {12000, -3.13}, |
| {16000, -4.26}, |
| {22050, -5.64}, |
| {24000, -5.87}, |
| {32000, -6.03}, |
| {44100, -6.20}, |
| {48000, -6.14} |
| }; |
| |
| /* Lookup the correct gain adjustment result in above array. */ |
| |
| static gdouble |
| get_expected_gain (guint sample_rate) |
| { |
| gint i; |
| |
| for (i = G_N_ELEMENTS (supported_rates); i--;) |
| if (supported_rates[i].sample_rate == sample_rate) |
| return supported_rates[i].gain; |
| g_return_val_if_reached (0.0); |
| } |
| |
| #define SILENCE_GAIN 64.82 |
| |
| #define REPLAY_GAIN_CAPS \ |
| "channels = (int) { 1, 2 }, " \ |
| "rate = (int) { 8000, 11025, 12000, 16000, 22050, " \ |
| "24000, 32000, 44100, 48000 }" |
| |
| #define RG_ANALYSIS_CAPS_TEMPLATE_STRING \ |
| "audio/x-raw, " \ |
| "format = (string) "GST_AUDIO_NE (F32) ", " \ |
| "layout = (string) interleaved, " \ |
| REPLAY_GAIN_CAPS \ |
| "; " \ |
| "audio/x-raw, " \ |
| "format = (string) "GST_AUDIO_NE (S16) ", " \ |
| "layout = (string) interleaved, " \ |
| REPLAY_GAIN_CAPS |
| |
| static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", |
| GST_PAD_SINK, |
| GST_PAD_ALWAYS, |
| GST_STATIC_CAPS (RG_ANALYSIS_CAPS_TEMPLATE_STRING) |
| ); |
| static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", |
| GST_PAD_SRC, |
| GST_PAD_ALWAYS, |
| GST_STATIC_CAPS (RG_ANALYSIS_CAPS_TEMPLATE_STRING) |
| ); |
| |
| static gboolean |
| mysink_event_func (GstPad * pad, GstObject * parent, GstEvent * event) |
| { |
| GST_LOG_OBJECT (pad, "%s event: %" GST_PTR_FORMAT, |
| GST_EVENT_TYPE_NAME (event), event); |
| |
| /* a sink would post tag events as messages, so do the same here, |
| * esp. since we're polling on the bus waiting for TAG messages.. */ |
| if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { |
| GstTagList *taglist; |
| |
| gst_event_parse_tag (event, &taglist); |
| |
| gst_bus_post (mybus, gst_message_new_tag (GST_OBJECT (mysinkpad), |
| gst_tag_list_copy (taglist))); |
| } |
| |
| gst_event_unref (event); |
| return TRUE; |
| } |
| |
| static GstElement * |
| setup_rganalysis (void) |
| { |
| GstElement *analysis; |
| GstBus *bus; |
| |
| GST_DEBUG ("setup_rganalysis"); |
| analysis = gst_check_setup_element ("rganalysis"); |
| mysrcpad = gst_check_setup_src_pad (analysis, &srctemplate); |
| mysinkpad = gst_check_setup_sink_pad (analysis, &sinktemplate); |
| gst_pad_set_event_function (mysinkpad, mysink_event_func); |
| gst_pad_set_active (mysrcpad, TRUE); |
| gst_pad_set_active (mysinkpad, TRUE); |
| |
| bus = gst_bus_new (); |
| gst_element_set_bus (analysis, bus); |
| |
| mybus = bus; /* keep ref */ |
| |
| return analysis; |
| } |
| |
| static void |
| cleanup_rganalysis (GstElement * element) |
| { |
| GST_DEBUG ("cleanup_rganalysis"); |
| |
| g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL); |
| g_list_free (buffers); |
| buffers = NULL; |
| |
| gst_object_unref (mybus); |
| mybus = NULL; |
| |
| /* The bus owns references to the element: */ |
| gst_element_set_bus (element, NULL); |
| |
| gst_pad_set_active (mysrcpad, FALSE); |
| gst_pad_set_active (mysinkpad, FALSE); |
| gst_check_teardown_src_pad (element); |
| gst_check_teardown_sink_pad (element); |
| gst_check_teardown_element (element); |
| } |
| |
| static void |
| set_playing_state (GstElement * element) |
| { |
| fail_unless (gst_element_set_state (element, |
| GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, |
| "Could not set state to PLAYING"); |
| } |
| |
| static void |
| send_flush_events (GstElement * element) |
| { |
| gboolean res; |
| GstPad *pad; |
| |
| pad = mysrcpad; |
| res = gst_pad_push_event (pad, gst_event_new_flush_start ()); |
| fail_unless (res, "flush-start even not handledt"); |
| res = gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE)); |
| fail_unless (res, "flush-stop event not handled"); |
| } |
| |
| static void |
| send_stream_start_event (GstElement * element) |
| { |
| gboolean res; |
| GstPad *pad; |
| |
| pad = mysrcpad; |
| res = gst_pad_push_event (pad, gst_event_new_stream_start ("test")); |
| fail_unless (res, "STREAM_START event not handled"); |
| } |
| |
| static void |
| send_caps_event (const gchar * format, gint sample_rate, gint channels) |
| { |
| GstCaps *caps; |
| |
| caps = gst_caps_new_simple ("audio/x-raw", |
| "format", G_TYPE_STRING, format, |
| "rate", G_TYPE_INT, sample_rate, "channels", G_TYPE_INT, channels, |
| "layout", G_TYPE_STRING, "interleaved", NULL); |
| if (channels == 2) { |
| gst_caps_set_simple (caps, |
| "channel-mask", GST_TYPE_BITMASK, |
| G_GUINT64_CONSTANT (0x0000000000000003), NULL); |
| } |
| gst_pad_set_caps (mysrcpad, caps); |
| gst_caps_unref (caps); |
| } |
| |
| static void |
| send_segment_event (GstElement * element) |
| { |
| GstSegment segment; |
| gboolean res; |
| GstPad *pad; |
| |
| pad = mysrcpad; |
| gst_segment_init (&segment, GST_FORMAT_TIME); |
| res = gst_pad_push_event (pad, gst_event_new_segment (&segment)); |
| fail_unless (res, "SEGMENT event not handled"); |
| } |
| |
| static void |
| send_eos_event (GstElement * element) |
| { |
| GstBus *bus = gst_element_get_bus (element); |
| GstPad *pad = mysrcpad; |
| gboolean res; |
| |
| res = gst_pad_push_event (pad, gst_event_new_eos ()); |
| fail_unless (res, "EOS event not handled"); |
| |
| /* There is no sink element, so _we_ post the EOS message on the bus here. Of |
| * course we generate any EOS ourselves, but this allows us to poll for the |
| * EOS message in poll_eos if we expect the element to _not_ generate a TAG |
| * message. That's better than waiting for a timeout to lapse. */ |
| fail_unless (gst_bus_post (bus, gst_message_new_eos (NULL))); |
| |
| gst_object_unref (bus); |
| } |
| |
| static void |
| send_tag_event (GstElement * element, GstTagList * tag_list) |
| { |
| GstPad *pad = mysrcpad; |
| GstEvent *event = gst_event_new_tag (tag_list); |
| |
| fail_unless (gst_pad_push_event (pad, event), |
| "Cannot send TAG event: Not handled."); |
| } |
| |
| static void |
| poll_eos (GstElement * element) |
| { |
| GstBus *bus = gst_element_get_bus (element); |
| GstMessage *message; |
| |
| message = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_TAG, GST_SECOND); |
| fail_unless (message != NULL, "Could not poll for EOS message: Timed out"); |
| fail_unless (message->type == GST_MESSAGE_EOS, |
| "Could not poll for eos message: got message of type %s instead", |
| gst_message_type_get_name (message->type)); |
| |
| gst_message_unref (message); |
| gst_object_unref (bus); |
| } |
| |
| static GstTagList * |
| poll_tags_only (GstElement * element) |
| { |
| GstBus *bus = gst_element_get_bus (element); |
| GstTagList *tag_list; |
| GstMessage *message; |
| |
| message = gst_bus_poll (bus, GST_MESSAGE_TAG, GST_SECOND); |
| fail_unless (message != NULL, "Could not poll for TAG message: Timed out"); |
| |
| gst_message_parse_tag (message, &tag_list); |
| gst_message_unref (message); |
| gst_object_unref (bus); |
| |
| return tag_list; |
| } |
| |
| /* This also polls for EOS since the TAG message comes right before the end of |
| * streams. */ |
| |
| static GstTagList * |
| poll_tags_followed_by_eos (GstElement * element) |
| { |
| GstTagList *tag_list = poll_tags_only (element); |
| |
| poll_eos (element); |
| |
| return tag_list; |
| } |
| |
| #define MATCH_PEAK(p1, p2) ((p1 < p2 + 1e-6) && (p2 < p1 + 1e-6)) |
| #define MATCH_GAIN(g1, g2) ((g1 < g2 + 1e-13) && (g2 < g1 + 1e-13)) |
| |
| static void |
| fail_unless_track_gain (const GstTagList * tag_list, gdouble gain) |
| { |
| gdouble result; |
| |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_GAIN, &result), |
| "Tag list contains no track gain value"); |
| fail_unless (MATCH_GAIN (gain, result), |
| "Track gain %+.2f does not match, expected %+.2f", result, gain); |
| } |
| |
| static void |
| fail_unless_track_peak (const GstTagList * tag_list, gdouble peak) |
| { |
| gdouble result; |
| |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_PEAK, &result), |
| "Tag list contains no track peak value"); |
| fail_unless (MATCH_PEAK (peak, result), |
| "Track peak %f does not match, expected %f", result, peak); |
| } |
| |
| static void |
| fail_unless_album_gain (const GstTagList * tag_list, gdouble gain) |
| { |
| gdouble result; |
| |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_GAIN, &result), |
| "Tag list contains no album gain value"); |
| fail_unless (MATCH_GAIN (result, gain), |
| "Album gain %+.2f does not match, expected %+.2f", result, gain); |
| } |
| |
| static void |
| fail_unless_album_peak (const GstTagList * tag_list, gdouble peak) |
| { |
| gdouble result; |
| |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_PEAK, &result), |
| "Tag list contains no album peak value"); |
| fail_unless (MATCH_PEAK (peak, result), |
| "Album peak %f does not match, expected %f", result, peak); |
| } |
| |
| static void |
| fail_if_track_tags (const GstTagList * tag_list) |
| { |
| gdouble result; |
| |
| fail_if (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_GAIN, &result), |
| "Tag list contains track gain value (but should not)"); |
| fail_if (gst_tag_list_get_double (tag_list, GST_TAG_TRACK_PEAK, &result), |
| "Tag list contains track peak value (but should not)"); |
| } |
| |
| static void |
| fail_if_album_tags (const GstTagList * tag_list) |
| { |
| gdouble result; |
| |
| fail_if (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_GAIN, &result), |
| "Tag list contains album gain value (but should not)"); |
| fail_if (gst_tag_list_get_double (tag_list, GST_TAG_ALBUM_PEAK, &result), |
| "Tag list contains album peak value (but should not)"); |
| } |
| |
| static void |
| fail_unless_num_tracks (GstElement * element, guint num_tracks) |
| { |
| guint current; |
| |
| g_object_get (element, "num-tracks", ¤t, NULL); |
| fail_unless (current == num_tracks, |
| "num-tracks property has incorrect value %u, expected %u", |
| current, num_tracks); |
| } |
| |
| /* Functions that create buffers with constant sample values, for peak |
| * tests. */ |
| |
| static GstBuffer * |
| test_buffer_const_float_mono (gint sample_rate, gsize n_frames, gfloat value) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat)); |
| GstMapInfo map; |
| gfloat *data; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gfloat *) map.data; |
| for (i = n_frames; i--;) |
| *data++ = value; |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static GstBuffer * |
| test_buffer_const_float_stereo (gint sample_rate, gsize n_frames, |
| gfloat value_l, gfloat value_r) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat) * 2); |
| GstMapInfo map; |
| gfloat *data; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gfloat *) map.data; |
| for (i = n_frames; i--;) { |
| *data++ = value_l; |
| *data++ = value_r; |
| } |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static GstBuffer * |
| test_buffer_const_int16_mono (gint sample_rate, gint depth, gsize n_frames, |
| gint16 value) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16)); |
| gint16 *data; |
| GstMapInfo map; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gint16 *) map.data; |
| for (i = n_frames; i--;) |
| *data++ = value; |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static GstBuffer * |
| test_buffer_const_int16_stereo (gint sample_rate, gint depth, gsize n_frames, |
| gint16 value_l, gint16 value_r) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16) * 2); |
| gint16 *data; |
| GstMapInfo map; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gint16 *) map.data; |
| for (i = n_frames; i--;) { |
| *data++ = value_l; |
| *data++ = value_r; |
| } |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| /* Functions that create data buffers containing square signal |
| * waveforms. */ |
| |
| static GstBuffer * |
| test_buffer_square_float_mono (gint * accumulator, gint sample_rate, |
| gsize n_frames, gfloat value) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat)); |
| gfloat *data; |
| GstMapInfo map; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gfloat *) map.data; |
| for (i = n_frames; i--;) { |
| *accumulator += 1; |
| *accumulator %= 96; |
| |
| if (*accumulator < 48) |
| *data++ = value; |
| else |
| *data++ = -value; |
| } |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static GstBuffer * |
| test_buffer_square_float_stereo (gint * accumulator, gint sample_rate, |
| gsize n_frames, gfloat value_l, gfloat value_r) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gfloat) * 2); |
| gfloat *data; |
| GstMapInfo map; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gfloat *) map.data; |
| for (i = n_frames; i--;) { |
| *accumulator += 1; |
| *accumulator %= 96; |
| |
| if (*accumulator < 48) { |
| *data++ = value_l; |
| *data++ = value_r; |
| } else { |
| *data++ = -value_l; |
| *data++ = -value_r; |
| } |
| } |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static GstBuffer * |
| test_buffer_square_int16_mono (gint * accumulator, gint sample_rate, |
| gint depth, gsize n_frames, gint16 value) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16)); |
| gint16 *data; |
| GstMapInfo map; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gint16 *) map.data; |
| for (i = n_frames; i--;) { |
| *accumulator += 1; |
| *accumulator %= 96; |
| |
| if (*accumulator < 48) |
| *data++ = value; |
| else |
| *data++ = -MAX (value, -32767); |
| } |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static GstBuffer * |
| test_buffer_square_int16_stereo (gint * accumulator, gint sample_rate, |
| gint depth, gsize n_frames, gint16 value_l, gint16 value_r) |
| { |
| GstBuffer *buf = gst_buffer_new_and_alloc (n_frames * sizeof (gint16) * 2); |
| gint16 *data; |
| GstMapInfo map; |
| gint i; |
| |
| gst_buffer_map (buf, &map, GST_MAP_WRITE); |
| data = (gint16 *) map.data; |
| for (i = n_frames; i--;) { |
| *accumulator += 1; |
| *accumulator %= 96; |
| |
| if (*accumulator < 48) { |
| *data++ = value_l; |
| *data++ = value_r; |
| } else { |
| *data++ = -MAX (value_l, -32767); |
| *data++ = -MAX (value_r, -32767); |
| } |
| } |
| gst_buffer_unmap (buf, &map); |
| |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| |
| return buf; |
| } |
| |
| static void |
| push_buffer (GstBuffer * buf) |
| { |
| /* gst_pad_push steals a reference. */ |
| fail_unless (gst_pad_push (mysrcpad, buf) == GST_FLOW_OK); |
| ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); |
| } |
| |
| /*** Start of the tests. ***/ |
| |
| /* This test looks redundant, but early versions of the element |
| * crashed when doing, well, nothing: */ |
| |
| GST_START_TEST (test_no_buffer) |
| { |
| GstElement *element = setup_rganalysis (); |
| |
| set_playing_state (element); |
| send_eos_event (element); |
| poll_eos (element); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_no_buffer_album_1) |
| { |
| GstElement *element = setup_rganalysis (); |
| |
| set_playing_state (element); |
| |
| /* Single track: */ |
| send_stream_start_event (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| |
| /* First album: */ |
| g_object_set (element, "num-tracks", 3, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 2); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 1); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 0); |
| |
| /* Second album: */ |
| g_object_set (element, "num-tracks", 2, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 1); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 0); |
| |
| /* Single track: */ |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 0); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_no_buffer_album_2) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "num-tracks", 3, NULL); |
| set_playing_state (element); |
| |
| /* No buffer for the first track. */ |
| send_stream_start_event (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| /* No tags should be posted, there was nothing to analyze: */ |
| poll_eos (element); |
| fail_unless_num_tracks (element, 2); |
| |
| /* A test waveform with known gain result as second track: */ |
| |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 1); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_mono (&accumulator, 44100, 512, |
| 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, -6.20); |
| /* Album is not finished yet: */ |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| /* No buffer for the last track. */ |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| send_eos_event (element); |
| |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_album_peak (tag_list, 0.25); |
| fail_unless_album_gain (tag_list, -6.20); |
| /* No track tags should be posted, as there was no data for it: */ |
| fail_if_track_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 0); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_empty_buffers) |
| { |
| GstElement *element = setup_rganalysis (); |
| |
| set_playing_state (element); |
| |
| /* Single track: */ |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0)); |
| send_eos_event (element); |
| poll_eos (element); |
| |
| /* First album: */ |
| g_object_set (element, "num-tracks", 2, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0)); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 1); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0)); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 0); |
| |
| /* Second album, with a single track: */ |
| g_object_set (element, "num-tracks", 1, NULL); |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0)); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 0); |
| |
| /* Single track: */ |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (44100, 0, 0.0, 0.0)); |
| send_eos_event (element); |
| poll_eos (element); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Tests for correctness of the peak values. */ |
| |
| /* Float peak test. For stereo, one channel has the constant value of -1.369, |
| * the other one 0.0. This tests many things: The result peak value should |
| * occur on any channel. The peak is of course the absolute amplitude, so 1.369 |
| * should be the result. This will also detect if the code uses the absolute |
| * value during the comparison. If it is buggy it will return 0.0 since 0.0 > |
| * -1.369. Furthermore, this makes sure that there is no problem with headroom |
| * (exceeding 0dBFS). In the wild you get float samples > 1.0 from stuff like |
| * vorbis. */ |
| |
| GST_START_TEST (test_peak_float) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| |
| set_playing_state (element); |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 512, -1.369, 0.0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.369); |
| gst_tag_list_unref (tag_list); |
| |
| /* Swapped channels. */ |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, -1.369)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.369); |
| gst_tag_list_unref (tag_list); |
| |
| /* Mono. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 1); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_mono (8000, 512, -1.369)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.369); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_peak_int16_16) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| |
| set_playing_state (element); |
| |
| /* Half amplitude. */ |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 1 << 14, 0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| |
| /* Swapped channels. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, 1 << 14)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| |
| /* Mono. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 1); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_mono (8000, 16, 512, 1 << 14)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| |
| /* Half amplitude, negative variant. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, -1 << 14, 0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| |
| /* Swapped channels. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, -1 << 14)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| |
| /* Mono. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 1); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_mono (8000, 16, 512, -1 << 14)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| |
| |
| /* Now check for correct normalization of the peak value: Sample |
| * values of this format range from -32768 to 32767. So for the |
| * highest positive amplitude we do not reach 1.0, only for |
| * -32768! */ |
| |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 32767, 0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 32767. / 32768.); |
| gst_tag_list_unref (tag_list); |
| |
| /* Swapped channels. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, 32767)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 32767. / 32768.); |
| gst_tag_list_unref (tag_list); |
| |
| /* Mono. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 1); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_mono (8000, 16, 512, 32767)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 32767. / 32768.); |
| gst_tag_list_unref (tag_list); |
| |
| |
| /* Negative variant, reaching 1.0. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, -32768, 0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| /* Swapped channels. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_stereo (8000, 16, 512, 0, -32768)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| /* Mono. */ |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (S16), 8000, 1); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_int16_mono (8000, 16, 512, -32768)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_peak_album) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| |
| g_object_set (element, "num-tracks", 2, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 1.0, 0.0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.0, 0.5)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| fail_unless_album_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 0); |
| |
| /* Try a second album: */ |
| g_object_set (element, "num-tracks", 3, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.4, 0.4)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.4); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 2); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.45, 0.45)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.45); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.2, 0.2)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.2); |
| fail_unless_album_peak (tag_list, 0.45); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 0); |
| |
| /* And now a single track, not in album mode (num-tracks is 0 |
| * now): */ |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.1, 0.1)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.1); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Switching from track to album mode. */ |
| |
| GST_START_TEST (test_peak_track_album) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 1); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_mono (8000, 1024, 1.0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| g_object_set (element, "num-tracks", 1, NULL); |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_mono (8000, 1024, 0.5)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| fail_unless_album_peak (tag_list, 0.5); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 0); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Disabling album processing before the end of the album. Probably a rare edge |
| * case and applications should not rely on this to work. They need to send the |
| * element to the READY state to clear up after an aborted album anyway since |
| * they might need to process another album afterwards. */ |
| |
| GST_START_TEST (test_peak_album_abort_to_track) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| |
| g_object_set (element, "num-tracks", 2, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 1.0, 0.0)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| g_object_set (element, "num-tracks", 0, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| push_buffer (test_buffer_const_float_stereo (8000, 1024, 0.0, 0.5)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_gain_album) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator; |
| gint i; |
| |
| g_object_set (element, "num-tracks", 3, NULL); |
| set_playing_state (element); |
| |
| /* The three tracks are constructed such that if any of these is in fact |
| * ignored for the album gain, the album gain will differ. */ |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 2); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 8; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.75, 0.75)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.75); |
| fail_unless_track_gain (tag_list, -15.70); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 12; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.5, 0.5)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.5); |
| fail_unless_track_gain (tag_list, -12.22); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 180; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, -6.20); |
| fail_unless_album_peak (tag_list, 0.75); |
| /* Strangely, wavegain reports -12.17 for the album, but the fixed |
| * metaflac agrees to us. Could be a 32767 vs. 32768 issue. */ |
| fail_unless_album_gain (tag_list, -12.18); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Checks ensuring that the "forced" property works as advertised. */ |
| |
| GST_START_TEST (test_forced) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 2); |
| send_segment_event (element); |
| tag_list = gst_tag_list_new_empty (); |
| /* Provided values are totally arbitrary. */ |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, |
| GST_TAG_TRACK_PEAK, 1.0, GST_TAG_TRACK_GAIN, 2.21, NULL); |
| send_tag_event (element, tag_list); |
| |
| for (i = 20; i--;) |
| push_buffer (test_buffer_const_float_stereo (44100, 512, 0.5, 0.5)); |
| send_eos_event (element); |
| |
| /* This fails if a tag message is generated: */ |
| /* Same values as above */ |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_gain (tag_list, 2.21); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| /* Now back to a track without tags. */ |
| send_flush_events (element); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100)); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Sending track gain and peak in separate tag lists. */ |
| |
| GST_START_TEST (test_forced_separate) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 2); |
| send_segment_event (element); |
| tag_list = gst_tag_list_new_empty (); |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, GST_TAG_TRACK_GAIN, 2.21, |
| NULL); |
| send_tag_event (element, tag_list); |
| |
| tag_list = gst_tag_list_new_empty (); |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, GST_TAG_TRACK_PEAK, 1.0, |
| NULL); |
| send_tag_event (element, tag_list); |
| |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.5, 0.5)); |
| send_eos_event (element); |
| |
| /* Same values as above */ |
| tag_list = poll_tags_only (element); |
| fail_unless_track_gain (tag_list, 2.21); |
| gst_tag_list_unref (tag_list); |
| |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| /* Now a track without tags. */ |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100)); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* A TAG event is sent _after_ data has already been processed. In real |
| * pipelines, this could happen if there is more than one rganalysis element (by |
| * accident). While it would have analyzed all the data prior to receiving the |
| * event, I expect it to not post its results if not forced. This test is |
| * almost equivalent to test_forced. */ |
| |
| GST_START_TEST (test_forced_after_data) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_const_float_stereo (8000, 512, 0.5, 0.5)); |
| |
| tag_list = gst_tag_list_new_empty (); |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, |
| GST_TAG_TRACK_PEAK, 1.0, GST_TAG_TRACK_GAIN, 2.21, NULL); |
| send_tag_event (element, tag_list); |
| |
| send_eos_event (element); |
| |
| /* Same values as above */ |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_gain (tag_list, 2.21); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| /* Now back to a normal track, this one has no tags: */ |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25, |
| 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (8000)); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Like test_forced, but *analyze* an album afterwards. The two tests following |
| * this one check the *skipping* of albums. */ |
| |
| GST_START_TEST (test_forced_album) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 2); |
| send_segment_event (element); |
| tag_list = gst_tag_list_new_empty (); |
| /* Provided values are totally arbitrary. */ |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, |
| GST_TAG_TRACK_PEAK, 1.0, GST_TAG_TRACK_GAIN, 2.21, NULL); |
| send_tag_event (element, tag_list); |
| |
| accumulator = 0; |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.5, 0.5)); |
| send_eos_event (element); |
| |
| /* Same values as above */ |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_gain (tag_list, 2.21); |
| fail_unless_track_peak (tag_list, 1.0); |
| gst_tag_list_unref (tag_list); |
| |
| /* Now an album without tags. */ |
| g_object_set (element, "num-tracks", 2, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100)); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100)); |
| fail_unless_album_peak (tag_list, 0.25); |
| fail_unless_album_gain (tag_list, get_expected_gain (44100)); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 0); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_forced_album_skip) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, "num-tracks", 2, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| tag_list = gst_tag_list_new_empty (); |
| /* Provided values are totally arbitrary. */ |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, |
| GST_TAG_TRACK_PEAK, 0.75, GST_TAG_TRACK_GAIN, 2.21, |
| GST_TAG_ALBUM_PEAK, 0.80, GST_TAG_ALBUM_GAIN, -0.11, NULL); |
| send_tag_event (element, tag_list); |
| |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25, |
| 0.25)); |
| send_eos_event (element); |
| |
| /* Same values as above */ |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_gain (tag_list, 2.21); |
| fail_unless_track_peak (tag_list, 0.75); |
| gst_tag_list_unref (tag_list); |
| |
| fail_unless_num_tracks (element, 1); |
| |
| /* This track has no tags, but needs to be skipped anyways since we |
| * are in album processing mode. */ |
| send_flush_events (element); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, 0.0)); |
| send_eos_event (element); |
| poll_eos (element); |
| fail_unless_num_tracks (element, 0); |
| |
| /* Normal track after the album. Of course not to be skipped. */ |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25, |
| 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (8000)); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_forced_album_no_skip) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, "num-tracks", 2, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25, |
| 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (8000)); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| /* The second track has indeed full tags, but although being not forced, this |
| * one has to be processed because album processing is on. */ |
| send_flush_events (element); |
| send_segment_event (element); |
| tag_list = gst_tag_list_new_empty (); |
| /* Provided values are totally arbitrary. */ |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, |
| GST_TAG_TRACK_PEAK, 0.75, GST_TAG_TRACK_GAIN, 2.21, |
| GST_TAG_ALBUM_PEAK, 0.80, GST_TAG_ALBUM_GAIN, -0.11, NULL); |
| send_tag_event (element, tag_list); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, 0.0)); |
| send_eos_event (element); |
| |
| /* the first batch from the tags */ |
| tag_list = poll_tags_only (element); |
| fail_unless_track_peak (tag_list, 0.75); |
| fail_unless_track_gain (tag_list, 2.21); |
| gst_tag_list_unref (tag_list); |
| |
| /* the second from the processing */ |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.0); |
| fail_unless_track_gain (tag_list, SILENCE_GAIN); |
| /* Second track was just silence so the album peak equals the first |
| * track's peak. */ |
| fail_unless_album_peak (tag_list, 0.25); |
| /* Statistical processing leads to the second track being |
| * ignored for the gain (because it is so short): */ |
| fail_unless_album_gain (tag_list, get_expected_gain (8000)); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 0); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_forced_abort_album_no_skip) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i; |
| |
| g_object_set (element, "forced", FALSE, "num-tracks", 2, NULL); |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 8000, 2); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 8000, 512, 0.25, |
| 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (8000)); |
| fail_if_album_tags (tag_list); |
| gst_tag_list_unref (tag_list); |
| fail_unless_num_tracks (element, 1); |
| |
| /* Disabling album processing before end of album: */ |
| g_object_set (element, "num-tracks", 0, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| |
| /* Processing a track that has to be skipped. */ |
| tag_list = gst_tag_list_new_empty (); |
| /* Provided values are totally arbitrary. */ |
| gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, |
| GST_TAG_TRACK_PEAK, 0.75, GST_TAG_TRACK_GAIN, 2.21, |
| GST_TAG_ALBUM_PEAK, 0.80, GST_TAG_ALBUM_GAIN, -0.11, NULL); |
| send_tag_event (element, tag_list); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_const_float_stereo (8000, 512, 0.0, 0.0)); |
| send_eos_event (element); |
| |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.75); |
| fail_unless_track_gain (tag_list, 2.21); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_reference_level) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gdouble ref_level; |
| gint accumulator = 0; |
| gint i; |
| |
| set_playing_state (element); |
| |
| send_stream_start_event (element); |
| send_caps_event (GST_AUDIO_NE (F32), 44100, 2); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100)); |
| fail_if_album_tags (tag_list); |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL, |
| &ref_level) && MATCH_GAIN (ref_level, 89.), |
| "Incorrect reference level tag"); |
| gst_tag_list_unref (tag_list); |
| |
| g_object_set (element, "reference-level", 83., "num-tracks", 2, NULL); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100) - 6.); |
| fail_if_album_tags (tag_list); |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL, |
| &ref_level) && MATCH_GAIN (ref_level, 83.), |
| "Incorrect reference level tag"); |
| gst_tag_list_unref (tag_list); |
| |
| send_flush_events (element); |
| send_segment_event (element); |
| accumulator = 0; |
| for (i = 20; i--;) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, 44100, 512, |
| 0.25, 0.25)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, get_expected_gain (44100) - 6.); |
| fail_unless_album_peak (tag_list, 0.25); |
| /* We provided the same waveform twice, with a reset separating |
| * them. Therefore, the album gain matches the track gain. */ |
| fail_unless_album_gain (tag_list, get_expected_gain (44100) - 6.); |
| fail_unless (gst_tag_list_get_double (tag_list, GST_TAG_REFERENCE_LEVEL, |
| &ref_level) && MATCH_GAIN (ref_level, 83.), |
| "Incorrect reference level tag"); |
| gst_tag_list_unref (tag_list); |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_all_formats) |
| { |
| GstElement *element = setup_rganalysis (); |
| GstTagList *tag_list; |
| gint accumulator = 0; |
| gint i, j; |
| |
| set_playing_state (element); |
| send_stream_start_event (element); |
| for (i = G_N_ELEMENTS (supported_rates); i--;) { |
| send_flush_events (element); |
| send_caps_event (GST_AUDIO_NE (F32), supported_rates[i].sample_rate, 2); |
| send_segment_event (element); |
| accumulator = 0; |
| for (j = 0; j < 4; j++) |
| push_buffer (test_buffer_square_float_stereo (&accumulator, |
| supported_rates[i].sample_rate, 512, 0.25, 0.25)); |
| send_caps_event (GST_AUDIO_NE (F32), supported_rates[i].sample_rate, 1); |
| for (j = 0; j < 3; j++) |
| push_buffer (test_buffer_square_float_mono (&accumulator, |
| supported_rates[i].sample_rate, 512, 0.25)); |
| send_caps_event (GST_AUDIO_NE (S16), supported_rates[i].sample_rate, 2); |
| for (j = 0; j < 4; j++) |
| push_buffer (test_buffer_square_int16_stereo (&accumulator, |
| supported_rates[i].sample_rate, 16, 512, 1 << 13, 1 << 13)); |
| send_caps_event (GST_AUDIO_NE (S16), supported_rates[i].sample_rate, 1); |
| for (j = 0; j < 3; j++) |
| push_buffer (test_buffer_square_int16_mono (&accumulator, |
| supported_rates[i].sample_rate, 16, 512, 1 << 13)); |
| send_eos_event (element); |
| tag_list = poll_tags_followed_by_eos (element); |
| fail_unless_track_peak (tag_list, 0.25); |
| fail_unless_track_gain (tag_list, supported_rates[i].gain); |
| gst_tag_list_unref (tag_list); |
| } |
| |
| cleanup_rganalysis (element); |
| } |
| |
| GST_END_TEST; |
| |
| /* Checks ensuring all advertised supported sample rates are really |
| * accepted, for integer and float, mono and stereo. This also |
| * verifies that the correct gain is computed for all formats (except |
| * odd bit depths). */ |
| |
| #define MAKE_GAIN_TEST_FLOAT_MONO(sample_rate) \ |
| GST_START_TEST (test_gain_float_mono_##sample_rate) \ |
| { \ |
| GstElement *element = setup_rganalysis (); \ |
| GstTagList *tag_list; \ |
| gint accumulator = 0; \ |
| gint i; \ |
| \ |
| set_playing_state (element); \ |
| send_stream_start_event (element); \ |
| send_caps_event (GST_AUDIO_NE (F32), sample_rate, 1); \ |
| send_segment_event (element); \ |
| \ |
| for (i = 0; i < 20; i++) \ |
| push_buffer (test_buffer_square_float_mono (&accumulator, \ |
| sample_rate, 512, 0.25)); \ |
| send_eos_event (element); \ |
| tag_list = poll_tags_followed_by_eos (element); \ |
| fail_unless_track_peak (tag_list, 0.25); \ |
| fail_unless_track_gain (tag_list, \ |
| get_expected_gain (sample_rate)); \ |
| gst_tag_list_unref (tag_list); \ |
| \ |
| cleanup_rganalysis (element); \ |
| } \ |
| \ |
| GST_END_TEST; |
| |
| #define MAKE_GAIN_TEST_FLOAT_STEREO(sample_rate) \ |
| GST_START_TEST (test_gain_float_stereo_##sample_rate) \ |
| { \ |
| GstElement *element = setup_rganalysis (); \ |
| GstTagList *tag_list; \ |
| gint accumulator = 0; \ |
| gint i; \ |
| \ |
| set_playing_state (element); \ |
| send_stream_start_event (element); \ |
| send_caps_event (GST_AUDIO_NE (F32), sample_rate, 2); \ |
| send_segment_event (element); \ |
| \ |
| for (i = 0; i < 20; i++) \ |
| push_buffer (test_buffer_square_float_stereo (&accumulator, \ |
| sample_rate, 512, 0.25, 0.25)); \ |
| send_eos_event (element); \ |
| tag_list = poll_tags_followed_by_eos (element); \ |
| fail_unless_track_peak (tag_list, 0.25); \ |
| fail_unless_track_gain (tag_list, \ |
| get_expected_gain (sample_rate)); \ |
| gst_tag_list_unref (tag_list); \ |
| \ |
| cleanup_rganalysis (element); \ |
| } \ |
| \ |
| GST_END_TEST; |
| |
| #define MAKE_GAIN_TEST_INT16_MONO(sample_rate, depth) \ |
| GST_START_TEST (test_gain_int16_##depth##_mono_##sample_rate) \ |
| { \ |
| GstElement *element = setup_rganalysis (); \ |
| GstTagList *tag_list; \ |
| gint accumulator = 0; \ |
| gint i; \ |
| \ |
| set_playing_state (element); \ |
| send_stream_start_event (element); \ |
| send_caps_event (GST_AUDIO_NE (S16), sample_rate, 1); \ |
| send_segment_event (element); \ |
| \ |
| for (i = 0; i < 20; i++) \ |
| push_buffer (test_buffer_square_int16_mono (&accumulator, \ |
| sample_rate, depth, 512, 1 << (13 + depth - 16))); \ |
| \ |
| send_eos_event (element); \ |
| tag_list = poll_tags_followed_by_eos (element); \ |
| fail_unless_track_peak (tag_list, 0.25); \ |
| fail_unless_track_gain (tag_list, \ |
| get_expected_gain (sample_rate)); \ |
| gst_tag_list_unref (tag_list); \ |
| \ |
| cleanup_rganalysis (element); \ |
| } \ |
| \ |
| GST_END_TEST; |
| |
| #define MAKE_GAIN_TEST_INT16_STEREO(sample_rate, depth) \ |
| GST_START_TEST (test_gain_int16_##depth##_stereo_##sample_rate) \ |
| { \ |
| GstElement *element = setup_rganalysis (); \ |
| GstTagList *tag_list; \ |
| gint accumulator = 0; \ |
| gint i; \ |
| \ |
| set_playing_state (element); \ |
| send_stream_start_event (element); \ |
| send_caps_event (GST_AUDIO_NE (S16), sample_rate, 2); \ |
| send_segment_event (element); \ |
| \ |
| for (i = 0; i < 20; i++) \ |
| push_buffer (test_buffer_square_int16_stereo (&accumulator, \ |
| sample_rate, depth, 512, 1 << (13 + depth - 16), \ |
| 1 << (13 + depth - 16))); \ |
| send_eos_event (element); \ |
| tag_list = poll_tags_followed_by_eos (element); \ |
| fail_unless_track_peak (tag_list, 0.25); \ |
| fail_unless_track_gain (tag_list, \ |
| get_expected_gain (sample_rate)); \ |
| gst_tag_list_unref (tag_list); \ |
| \ |
| cleanup_rganalysis (element); \ |
| } \ |
| \ |
| GST_END_TEST; |
| |
| MAKE_GAIN_TEST_FLOAT_MONO (8000); |
| MAKE_GAIN_TEST_FLOAT_MONO (11025); |
| MAKE_GAIN_TEST_FLOAT_MONO (12000); |
| MAKE_GAIN_TEST_FLOAT_MONO (16000); |
| MAKE_GAIN_TEST_FLOAT_MONO (22050); |
| MAKE_GAIN_TEST_FLOAT_MONO (24000); |
| MAKE_GAIN_TEST_FLOAT_MONO (32000); |
| MAKE_GAIN_TEST_FLOAT_MONO (44100); |
| MAKE_GAIN_TEST_FLOAT_MONO (48000); |
| |
| MAKE_GAIN_TEST_FLOAT_STEREO (8000); |
| MAKE_GAIN_TEST_FLOAT_STEREO (11025); |
| MAKE_GAIN_TEST_FLOAT_STEREO (12000); |
| MAKE_GAIN_TEST_FLOAT_STEREO (16000); |
| MAKE_GAIN_TEST_FLOAT_STEREO (22050); |
| MAKE_GAIN_TEST_FLOAT_STEREO (24000); |
| MAKE_GAIN_TEST_FLOAT_STEREO (32000); |
| MAKE_GAIN_TEST_FLOAT_STEREO (44100); |
| MAKE_GAIN_TEST_FLOAT_STEREO (48000); |
| |
| MAKE_GAIN_TEST_INT16_MONO (8000, 16); |
| MAKE_GAIN_TEST_INT16_MONO (11025, 16); |
| MAKE_GAIN_TEST_INT16_MONO (12000, 16); |
| MAKE_GAIN_TEST_INT16_MONO (16000, 16); |
| MAKE_GAIN_TEST_INT16_MONO (22050, 16); |
| MAKE_GAIN_TEST_INT16_MONO (24000, 16); |
| MAKE_GAIN_TEST_INT16_MONO (32000, 16); |
| MAKE_GAIN_TEST_INT16_MONO (44100, 16); |
| MAKE_GAIN_TEST_INT16_MONO (48000, 16); |
| |
| MAKE_GAIN_TEST_INT16_STEREO (8000, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (11025, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (12000, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (16000, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (22050, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (24000, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (32000, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (44100, 16); |
| MAKE_GAIN_TEST_INT16_STEREO (48000, 16); |
| |
| static Suite * |
| rganalysis_suite (void) |
| { |
| Suite *s = suite_create ("rganalysis"); |
| TCase *tc_chain = tcase_create ("general"); |
| |
| suite_add_tcase (s, tc_chain); |
| |
| tcase_add_test (tc_chain, test_no_buffer); |
| tcase_add_test (tc_chain, test_no_buffer_album_1); |
| tcase_add_test (tc_chain, test_no_buffer_album_2); |
| tcase_add_test (tc_chain, test_empty_buffers); |
| |
| tcase_add_test (tc_chain, test_peak_float); |
| tcase_add_test (tc_chain, test_peak_int16_16); |
| |
| tcase_add_test (tc_chain, test_peak_album); |
| tcase_add_test (tc_chain, test_peak_track_album); |
| tcase_add_test (tc_chain, test_peak_album_abort_to_track); |
| |
| tcase_add_test (tc_chain, test_gain_album); |
| |
| tcase_add_test (tc_chain, test_forced); |
| tcase_add_test (tc_chain, test_forced_separate); |
| tcase_add_test (tc_chain, test_forced_after_data); |
| tcase_add_test (tc_chain, test_forced_album); |
| tcase_add_test (tc_chain, test_forced_album_skip); |
| tcase_add_test (tc_chain, test_forced_album_no_skip); |
| tcase_add_test (tc_chain, test_forced_abort_album_no_skip); |
| |
| tcase_add_test (tc_chain, test_reference_level); |
| |
| tcase_add_test (tc_chain, test_all_formats); |
| |
| tcase_add_test (tc_chain, test_gain_float_mono_8000); |
| tcase_add_test (tc_chain, test_gain_float_mono_11025); |
| tcase_add_test (tc_chain, test_gain_float_mono_12000); |
| tcase_add_test (tc_chain, test_gain_float_mono_16000); |
| tcase_add_test (tc_chain, test_gain_float_mono_22050); |
| tcase_add_test (tc_chain, test_gain_float_mono_24000); |
| tcase_add_test (tc_chain, test_gain_float_mono_32000); |
| tcase_add_test (tc_chain, test_gain_float_mono_44100); |
| tcase_add_test (tc_chain, test_gain_float_mono_48000); |
| |
| tcase_add_test (tc_chain, test_gain_float_stereo_8000); |
| tcase_add_test (tc_chain, test_gain_float_stereo_11025); |
| tcase_add_test (tc_chain, test_gain_float_stereo_12000); |
| tcase_add_test (tc_chain, test_gain_float_stereo_16000); |
| tcase_add_test (tc_chain, test_gain_float_stereo_22050); |
| tcase_add_test (tc_chain, test_gain_float_stereo_24000); |
| tcase_add_test (tc_chain, test_gain_float_stereo_32000); |
| tcase_add_test (tc_chain, test_gain_float_stereo_44100); |
| tcase_add_test (tc_chain, test_gain_float_stereo_48000); |
| |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_8000); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_11025); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_12000); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_16000); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_22050); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_24000); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_32000); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_44100); |
| tcase_add_test (tc_chain, test_gain_int16_16_mono_48000); |
| |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_8000); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_11025); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_12000); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_16000); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_22050); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_24000); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_32000); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_44100); |
| tcase_add_test (tc_chain, test_gain_int16_16_stereo_48000); |
| |
| return s; |
| } |
| |
| GST_CHECK_MAIN (rganalysis); |