summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2007-09-06 07:21:22 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2007-09-06 07:21:22 +0000
commit76a3fd7100246d47d3dcf08cd1e3370adca244af (patch)
tree8ed36919f4ad868314fa6cec4b4df4f34c999819 /tests
parent27f25ccd9bc38a0fb685bf26b28d3f5d5023b110 (diff)
downloadgst-plugins-bad-76a3fd7100246d47d3dcf08cd1e3370adca244af.tar.gz
gst-plugins-bad-76a3fd7100246d47d3dcf08cd1e3370adca244af.tar.bz2
gst-plugins-bad-76a3fd7100246d47d3dcf08cd1e3370adca244af.zip
Port GstSpectrum to GstAudioFilter and libgstfft, add support for int32, float and double, use floats for the message...
Original commit message from CVS: * configure.ac: * gst/spectrum/Makefile.am: * gst/spectrum/demo-audiotest.c: (draw_spectrum), (message_handler), (main): * gst/spectrum/demo-osssrc.c: (draw_spectrum), (message_handler): * gst/spectrum/gstspectrum.c: (gst_spectrum_base_init), (gst_spectrum_class_init), (gst_spectrum_init), (gst_spectrum_dispose), (gst_spectrum_set_property), (gst_spectrum_get_property), (gst_spectrum_start), (gst_spectrum_setup), (gst_spectrum_message_new), (gst_spectrum_transform_ip): * gst/spectrum/gstspectrum.h: Port GstSpectrum to GstAudioFilter and libgstfft, add support for int32, float and double, use floats for the message contents, average all FFTs done in one interval for better results, use a better windowing function, allow posting the phase in the message and actually do an FFT with the requested number of bands instead of interpolating. * tests/check/elements/spectrum.c: (GST_START_TEST), (spectrum_suite): Improve the units tests by checking for a 11025Hz sine wave and add unit tests for all 4 supported sample types.
Diffstat (limited to 'tests')
-rw-r--r--tests/check/elements/spectrum.c393
1 files changed, 374 insertions, 19 deletions
diff --git a/tests/check/elements/spectrum.c b/tests/check/elements/spectrum.c
index 7e3d1e10..7dee5fe1 100644
--- a/tests/check/elements/spectrum.c
+++ b/tests/check/elements/spectrum.c
@@ -33,24 +33,59 @@ gboolean have_eos = FALSE;
GstPad *mysrcpad, *mysinkpad;
#define SPECT_CAPS_TEMPLATE_STRING \
+ "audio/x-raw-int, " \
+ " width = (int) 16, " \
+ " depth = (int) 16, " \
+ " signed = (boolean) true, " \
+ " endianness = (int) BYTE_ORDER, " \
+ " rate = (int) [ 1, MAX ], " \
+ " channels = (int) [ 1, MAX ]; " \
+ "audio/x-raw-int, " \
+ " width = (int) 32, " \
+ " depth = (int) 32, " \
+ " signed = (boolean) true, " \
+ " endianness = (int) BYTE_ORDER, " \
+ " rate = (int) [ 1, MAX ], " \
+ " channels = (int) [ 1, MAX ]; " \
+ "audio/x-raw-float, " \
+ " width = (int) { 32, 64 }, " \
+ " endianness = (int) BYTE_ORDER, " \
+ " rate = (int) [ 1, MAX ], " \
+ " channels = (int) [ 1, MAX ]"
+
+#define SPECT_CAPS_STRING_S16 \
"audio/x-raw-int, " \
- "rate = (int) [ 1, MAX ], " \
- "channels = (int) [ 1, 8 ], " \
+ "rate = (int) 44100, " \
+ "channels = (int) 1, " \
"endianness = (int) BYTE_ORDER, " \
- "width = (int) {8, 16}, " \
- "depth = (int) {8, 16}, " \
+ "width = (int) 16, " \
+ "depth = (int) 16, " \
"signed = (boolean) true"
-#define SPECT_CAPS_STRING \
+#define SPECT_CAPS_STRING_S32 \
"audio/x-raw-int, " \
"rate = (int) 44100, " \
"channels = (int) 1, " \
"endianness = (int) BYTE_ORDER, " \
- "width = (int) 16, " \
- "depth = (int) 16, " \
+ "width = (int) 32, " \
+ "depth = (int) 32, " \
"signed = (boolean) true"
-#define SPECT_BANDS 64
+#define SPECT_CAPS_STRING_F32 \
+ "audio/x-raw-float, " \
+ " width = (int) 32, " \
+ " endianness = (int) BYTE_ORDER, " \
+ " rate = (int) 44100, " \
+ " channels = (int) 1"
+
+#define SPECT_CAPS_STRING_F64 \
+ "audio/x-raw-float, " \
+ " width = (int) 64, " \
+ " endianness = (int) BYTE_ORDER, " \
+ " rate = (int) 44100, " \
+ " channels = (int) 1"
+
+#define SPECT_BANDS 256
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -104,24 +139,338 @@ GST_START_TEST (test_int16)
gint16 *data;
const GValue *list, *value;
GstClockTime endtime;
- guchar level;
+ gfloat level;
spectrum = setup_spectrum ();
- g_object_set (spectrum, "message", TRUE, "interval", GST_SECOND / 10,
+ g_object_set (spectrum, "message", TRUE, "interval", GST_SECOND / 100,
"bands", SPECT_BANDS, "threshold", -80, NULL);
fail_unless (gst_element_set_state (spectrum,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
- /* create a fake 1 sec buffer with a half-amplitude block signal */
+ /* create a 1 sec buffer with an 11025 Hz sine wave */
inbuffer = gst_buffer_new_and_alloc (44100 * sizeof (gint16));
data = (gint16 *) GST_BUFFER_DATA (inbuffer);
- for (j = 0; j < 44100; ++j) {
- *data = 16536;
+
+ for (j = 0; j < 44100; j += 4) {
+ *data = 0;
+ ++data;
+ *data = 32767;
+ ++data;
+ *data = 0;
+ ++data;
+ *data = -32767;
+ ++data;
+ }
+
+ caps = gst_caps_from_string (SPECT_CAPS_STRING_S16);
+ gst_buffer_set_caps (inbuffer, caps);
+ gst_caps_unref (caps);
+ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+
+ /* create a bus to get the spectrum message on */
+ bus = gst_bus_new ();
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ gst_element_set_bus (spectrum, bus);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
+
+ /* pushing gives away my reference ... */
+ fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
+ /* ... but it ends up being collected on the global buffer list */
+ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+ fail_unless_equals_int (g_list_length (buffers), 1);
+ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ fail_unless (inbuffer == outbuffer);
+
+ message = gst_bus_poll (bus, GST_MESSAGE_ELEMENT, -1);
+ ASSERT_OBJECT_REFCOUNT (message, "message", 1);
+
+ fail_unless (message != NULL);
+ fail_unless (GST_MESSAGE_SRC (message) == GST_OBJECT (spectrum));
+ fail_unless (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT);
+ structure = gst_message_get_structure (message);
+ fail_if (structure == NULL);
+ fail_unless_equals_string ((char *) gst_structure_get_name (structure),
+ "spectrum");
+ fail_unless (gst_structure_get_clock_time (structure, "endtime", &endtime));
+
+ list = gst_structure_get_value (structure, "magnitude");
+ for (i = 0; i < SPECT_BANDS; ++i) {
+ value = gst_value_list_get_value (list, i);
+ level = g_value_get_float (value);
+ GST_DEBUG ("band[%3d] is %.2f", i, level);
+ /* Only the bands in the middle should have a level above 60 */
+ fail_if ((i == SPECT_BANDS / 2 || i == SPECT_BANDS / 2 - 1)
+ && level < 60.0);
+ fail_if ((i != SPECT_BANDS / 2 && i != SPECT_BANDS / 2 - 1)
+ && level > 60.0);
+ }
+ fail_unless_equals_int (g_list_length (buffers), 1);
+ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ fail_unless (inbuffer == outbuffer);
+
+ /* clean up */
+ /* flush current messages,and future state change messages */
+ gst_bus_set_flushing (bus, TRUE);
+
+ /* message has a ref to the element */
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 2);
+ gst_message_unref (message);
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 1);
+
+ gst_element_set_bus (spectrum, NULL);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ gst_object_unref (bus);
+ gst_buffer_unref (outbuffer);
+ fail_unless (gst_element_set_state (spectrum,
+ GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 1);
+ cleanup_spectrum (spectrum);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_int32)
+{
+ GstElement *spectrum;
+ GstBuffer *inbuffer, *outbuffer;
+ GstBus *bus;
+ GstCaps *caps;
+ GstMessage *message;
+ const GstStructure *structure;
+ int i, j;
+ gint32 *data;
+ const GValue *list, *value;
+ GstClockTime endtime;
+ gfloat level;
+
+ spectrum = setup_spectrum ();
+ g_object_set (spectrum, "message", TRUE, "interval", GST_SECOND / 100,
+ "bands", SPECT_BANDS, "threshold", -80, NULL);
+
+ fail_unless (gst_element_set_state (spectrum,
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
+ "could not set to playing");
+
+ /* create a 1 sec buffer with an 11025 Hz sine wave */
+ inbuffer = gst_buffer_new_and_alloc (44100 * sizeof (gint32));
+ data = (gint32 *) GST_BUFFER_DATA (inbuffer);
+ for (j = 0; j < 44100; j += 4) {
+ *data = 0;
+ ++data;
+ *data = 2147483647;
+ ++data;
+ *data = 0;
+ ++data;
+ *data = -2147483647;
+ ++data;
+ }
+ caps = gst_caps_from_string (SPECT_CAPS_STRING_S32);
+ gst_buffer_set_caps (inbuffer, caps);
+ gst_caps_unref (caps);
+ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+
+ /* create a bus to get the spectrum message on */
+ bus = gst_bus_new ();
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ gst_element_set_bus (spectrum, bus);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
+
+ /* pushing gives away my reference ... */
+ fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
+ /* ... but it ends up being collected on the global buffer list */
+ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+ fail_unless_equals_int (g_list_length (buffers), 1);
+ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ fail_unless (inbuffer == outbuffer);
+
+ message = gst_bus_poll (bus, GST_MESSAGE_ELEMENT, -1);
+ ASSERT_OBJECT_REFCOUNT (message, "message", 1);
+
+ fail_unless (message != NULL);
+ fail_unless (GST_MESSAGE_SRC (message) == GST_OBJECT (spectrum));
+ fail_unless (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT);
+ structure = gst_message_get_structure (message);
+ fail_if (structure == NULL);
+ fail_unless_equals_string ((char *) gst_structure_get_name (structure),
+ "spectrum");
+ fail_unless (gst_structure_get_clock_time (structure, "endtime", &endtime));
+
+ list = gst_structure_get_value (structure, "magnitude");
+ for (i = 0; i < SPECT_BANDS; ++i) {
+ value = gst_value_list_get_value (list, i);
+ level = g_value_get_float (value);
+ GST_DEBUG ("band[%3d] is %.2f", i, level);
+ /* Only the bands in the middle should have a level above 60 */
+ fail_if ((i == SPECT_BANDS / 2 || i == SPECT_BANDS / 2 - 1)
+ && level < 60.0);
+ fail_if ((i != SPECT_BANDS / 2 && i != SPECT_BANDS / 2 - 1)
+ && level > 60.0);
+ }
+ fail_unless_equals_int (g_list_length (buffers), 1);
+ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ fail_unless (inbuffer == outbuffer);
+
+ /* clean up */
+ /* flush current messages,and future state change messages */
+ gst_bus_set_flushing (bus, TRUE);
+
+ /* message has a ref to the element */
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 2);
+ gst_message_unref (message);
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 1);
+
+ gst_element_set_bus (spectrum, NULL);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ gst_object_unref (bus);
+ gst_buffer_unref (outbuffer);
+ fail_unless (gst_element_set_state (spectrum,
+ GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 1);
+ cleanup_spectrum (spectrum);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_float32)
+{
+ GstElement *spectrum;
+ GstBuffer *inbuffer, *outbuffer;
+ GstBus *bus;
+ GstCaps *caps;
+ GstMessage *message;
+ const GstStructure *structure;
+ int i, j;
+ gfloat *data;
+ const GValue *list, *value;
+ GstClockTime endtime;
+ gfloat level;
+
+ spectrum = setup_spectrum ();
+ g_object_set (spectrum, "message", TRUE, "interval", GST_SECOND / 100,
+ "bands", SPECT_BANDS, "threshold", -80, NULL);
+
+ fail_unless (gst_element_set_state (spectrum,
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
+ "could not set to playing");
+
+ /* create a 1 sec buffer with an 11025 Hz sine wave */
+ inbuffer = gst_buffer_new_and_alloc (44100 * sizeof (gfloat));
+ data = (gfloat *) GST_BUFFER_DATA (inbuffer);
+ for (j = 0; j < 44100; j += 4) {
+ *data = 0.0;
+ ++data;
+ *data = 1.0;
+ ++data;
+ *data = 0.0;
+ ++data;
+ *data = -1.0;
+ ++data;
+ }
+ caps = gst_caps_from_string (SPECT_CAPS_STRING_F32);
+ gst_buffer_set_caps (inbuffer, caps);
+ gst_caps_unref (caps);
+ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+
+ /* create a bus to get the spectrum message on */
+ bus = gst_bus_new ();
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ gst_element_set_bus (spectrum, bus);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
+
+ /* pushing gives away my reference ... */
+ fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
+ /* ... but it ends up being collected on the global buffer list */
+ ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+ fail_unless_equals_int (g_list_length (buffers), 1);
+ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ fail_unless (inbuffer == outbuffer);
+
+ message = gst_bus_poll (bus, GST_MESSAGE_ELEMENT, -1);
+ ASSERT_OBJECT_REFCOUNT (message, "message", 1);
+
+ fail_unless (message != NULL);
+ fail_unless (GST_MESSAGE_SRC (message) == GST_OBJECT (spectrum));
+ fail_unless (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ELEMENT);
+ structure = gst_message_get_structure (message);
+ fail_if (structure == NULL);
+ fail_unless_equals_string ((char *) gst_structure_get_name (structure),
+ "spectrum");
+ fail_unless (gst_structure_get_clock_time (structure, "endtime", &endtime));
+
+ list = gst_structure_get_value (structure, "magnitude");
+ for (i = 0; i < SPECT_BANDS; ++i) {
+ value = gst_value_list_get_value (list, i);
+ level = g_value_get_float (value);
+ GST_DEBUG ("band[%3d] is %.2f", i, level);
+ /* Only the bands in the middle should have a level above 60 */
+ fail_if ((i == SPECT_BANDS / 2 || i == SPECT_BANDS / 2 - 1)
+ && level < 60.0);
+ fail_if ((i != SPECT_BANDS / 2 && i != SPECT_BANDS / 2 - 1)
+ && level > 60.0);
+ }
+ fail_unless_equals_int (g_list_length (buffers), 1);
+ fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ fail_unless (inbuffer == outbuffer);
+
+ /* clean up */
+ /* flush current messages,and future state change messages */
+ gst_bus_set_flushing (bus, TRUE);
+
+ /* message has a ref to the element */
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 2);
+ gst_message_unref (message);
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 1);
+
+ gst_element_set_bus (spectrum, NULL);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ gst_object_unref (bus);
+ gst_buffer_unref (outbuffer);
+ fail_unless (gst_element_set_state (spectrum,
+ GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
+ ASSERT_OBJECT_REFCOUNT (spectrum, "spectrum", 1);
+ cleanup_spectrum (spectrum);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_float64)
+{
+ GstElement *spectrum;
+ GstBuffer *inbuffer, *outbuffer;
+ GstBus *bus;
+ GstCaps *caps;
+ GstMessage *message;
+ const GstStructure *structure;
+ int i, j;
+ gdouble *data;
+ const GValue *list, *value;
+ GstClockTime endtime;
+ gfloat level;
+
+ spectrum = setup_spectrum ();
+ g_object_set (spectrum, "message", TRUE, "interval", GST_SECOND / 100,
+ "bands", SPECT_BANDS, "threshold", -80, NULL);
+
+ fail_unless (gst_element_set_state (spectrum,
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
+ "could not set to playing");
+
+ /* create a 1 sec buffer with an 11025 Hz sine wave */
+ inbuffer = gst_buffer_new_and_alloc (44100 * sizeof (gdouble));
+ data = (gdouble *) GST_BUFFER_DATA (inbuffer);
+ for (j = 0; j < 44100; j += 4) {
+ *data = 0.0;
+ ++data;
+ *data = 1.0;
+ ++data;
+ *data = 0.0;
+ ++data;
+ *data = -1.0;
++data;
}
- caps = gst_caps_from_string (SPECT_CAPS_STRING);
+ caps = gst_caps_from_string (SPECT_CAPS_STRING_F64);
gst_buffer_set_caps (inbuffer, caps);
gst_caps_unref (caps);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
@@ -152,13 +501,16 @@ GST_START_TEST (test_int16)
"spectrum");
fail_unless (gst_structure_get_clock_time (structure, "endtime", &endtime));
- /* block wave of half amplitude has -5.94 dB for rms, peak and decay */
- list = gst_structure_get_value (structure, "spectrum");
+ list = gst_structure_get_value (structure, "magnitude");
for (i = 0; i < SPECT_BANDS; ++i) {
value = gst_value_list_get_value (list, i);
- level = g_value_get_uchar (value);
- GST_DEBUG ("band[%3d] is %3d", i, level);
- fail_if (level == 0);
+ level = g_value_get_float (value);
+ GST_DEBUG ("band[%3d] is %.2f", i, level);
+ /* Only the bands in the middle should have a level above 60 */
+ fail_if ((i == SPECT_BANDS / 2 || i == SPECT_BANDS / 2 - 1)
+ && level < 60.0);
+ fail_if ((i != SPECT_BANDS / 2 && i != SPECT_BANDS / 2 - 1)
+ && level > 60.0);
}
fail_unless_equals_int (g_list_length (buffers), 1);
fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
@@ -194,6 +546,9 @@ spectrum_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_int16);
+ tcase_add_test (tc_chain, test_int32);
+ tcase_add_test (tc_chain, test_float32);
+ tcase_add_test (tc_chain, test_float64);
return s;
}