diff --git a/ChangeLog b/ChangeLog index 55fee5d32d..00e078a55f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-11-06 Sebastian Dröge + + * docs/libs/gst-plugins-base-libs-sections.txt: + * gst-libs/gst/fft/gstfftf32.c: + * gst-libs/gst/fft/gstfftf32.h: + * gst-libs/gst/fft/gstfftf64.c: + * gst-libs/gst/fft/gstfftf64.h: + * gst-libs/gst/fft/gstffts16.c: + * gst-libs/gst/fft/gstffts16.h: + * gst-libs/gst/fft/gstffts32.c: + * gst-libs/gst/fft/gstffts32.h: + * tests/check/libs/fft.c: (GST_START_TEST): + Remove the magnitude and phase calculation functions as these have + very special use cases and can't even be used for the spectrum + element. Also adjust the docs to mention some properties of the used + FFT implemention, i.e. how the values are scaled. Fixes #492098. + 2007-11-06 Tim-Philipp Müller * gst/playback/gstplaybasebin.c: (queue_threshold_reached), diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index fb43291ca6..0ef3e43baf 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -242,10 +242,8 @@ GstFFTS16Complex gst_fft_s16_new gst_fft_s16_fft gst_fft_s16_inverse_fft -gst_fft_s16_free -gst_fft_s16_magnitude -gst_fft_s16_phase gst_fft_s16_window +gst_fft_s16_free
@@ -256,10 +254,8 @@ GstFFTS32Complex gst_fft_s32_new gst_fft_s32_fft gst_fft_s32_inverse_fft -gst_fft_s32_free -gst_fft_s32_magnitude -gst_fft_s32_phase gst_fft_s32_window +gst_fft_s32_free
@@ -270,10 +266,8 @@ GstFFTF32Complex gst_fft_f32_new gst_fft_f32_fft gst_fft_f32_inverse_fft -gst_fft_f32_free -gst_fft_f32_magnitude -gst_fft_f32_phase gst_fft_f32_window +gst_fft_f32_free
@@ -284,10 +278,8 @@ GstFFTF64Complex gst_fft_f64_new gst_fft_f64_fft gst_fft_f64_inverse_fft -gst_fft_f64_free -gst_fft_f64_magnitude -gst_fft_f64_phase gst_fft_f64_window +gst_fft_f64_free
# floatcast diff --git a/gst-libs/gst/fft/gstfftf32.c b/gst-libs/gst/fft/gstfftf32.c index 53038e064e..b704b5ff2b 100644 --- a/gst-libs/gst/fft/gstfftf32.c +++ b/gst-libs/gst/fft/gstfftf32.c @@ -48,10 +48,11 @@ * to apply a window function to it. For this gst_fft_f32_window() can comfortably * be used. * - * For calculating the magnitude or phase of frequency data the functions - * gst_fft_f32_magnitude() and gst_fft_f32_phase() exist, if you want to calculate - * the magnitude yourself note that the magnitude of the frequency data is - * a value between 0 and 1 and is to be scaled by the length of the FFT. + * Be aware, that you can't simply run gst_fft_f32_inverse_fft() on the + * resulting frequency data of gst_fft_f32_fft() to get the original data back. + * The relation between them is iFFT (FFT (x)) = x * nfft where nfft is the + * length of the FFT. This also has to be taken into account when calculation + * the magnitude of the frequency data. * */ @@ -200,71 +201,3 @@ gst_fft_f32_window (GstFFTF32 * self, gfloat * timedata, GstFFTWindow window) break; } } - -/** - * gst_fft_f32_magnitude: - * @self: #GstFFTF32 instance for this call - * @freqdata: Frequency domain samples - * @magnitude: Target buffer for the magnitude - * @decibel: %TRUE if the magnitude should be in decibel, %FALSE if it should be an amplitude - * - * This calculates the magnitude of @freqdata in @magnitude. Depending on the value - * of @decibel the magnitude can be calculated in decibel or as amplitude between 0.0 - * and 1.0. - * - * @magnitude must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_f32_magnitude (GstFFTF32 * self, GstFFTF32Complex * freqdata, - gdouble * magnitude, gboolean decibel) -{ - gint i, len, nfft; - gdouble val; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (magnitude); - - len = self->len / 2 + 1; - nfft = self->len; - - for (i = 0; i < len; i++) { - val = (gdouble) freqdata[i].r * (gdouble) freqdata[i].r - + (gdouble) freqdata[i].i * (gdouble) freqdata[i].i; - val = sqrt (val) / nfft; - - if (decibel) - val = 20.0 * log10 (val); - - magnitude[i] = val; - } -} - -/** - * gst_fft_f32_phase: - * @self: #GstFFTF32 instance for this call - * @freqdata: Frequency domain samples - * @phase: Target buffer for the phase - * - * This calculates the phases of @freqdata in @phase. The returned - * phases will be values between -pi and pi. - * - * @phase must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_f32_phase (GstFFTF32 * self, GstFFTF32Complex * freqdata, - gdouble * phase) -{ - gint i, len; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (phase); - - len = self->len / 2 + 1; - - for (i = 0; i < len; i++) - phase[i] = atan2 (freqdata[i].i, freqdata[i].r); -} diff --git a/gst-libs/gst/fft/gstfftf32.h b/gst-libs/gst/fft/gstfftf32.h index b0b6f673f3..8ec61b21b0 100644 --- a/gst-libs/gst/fft/gstfftf32.h +++ b/gst-libs/gst/fft/gstfftf32.h @@ -69,9 +69,4 @@ void gst_fft_f32_free (GstFFTF32 *self); void gst_fft_f32_window (GstFFTF32 *self, gfloat *timedata, GstFFTWindow window); -void gst_fft_f32_magnitude (GstFFTF32 *self, GstFFTF32Complex *freqdata, - gdouble *magnitude, gboolean decibel); -void gst_fft_f32_phase (GstFFTF32 *self, GstFFTF32Complex *freqdata, - gdouble *phase); - #endif /* __GST_FFT_F32_H__ */ diff --git a/gst-libs/gst/fft/gstfftf64.c b/gst-libs/gst/fft/gstfftf64.c index 1a65014bf0..cd6db088b1 100644 --- a/gst-libs/gst/fft/gstfftf64.c +++ b/gst-libs/gst/fft/gstfftf64.c @@ -48,10 +48,11 @@ * to apply a window function to it. For this gst_fft_f64_window() can comfortably * be used. * - * For calculating the magnitude or phase of frequency data the functions - * gst_fft_f64_magnitude() and gst_fft_f64_phase() exist, if you want to calculate - * the magnitude yourself note that the magnitude of the frequency data is - * a value between 0 and 1 and is to be scaled by the length of the FFT. + * Be aware, that you can't simply run gst_fft_f32_inverse_fft() on the + * resulting frequency data of gst_fft_f32_fft() to get the original data back. + * The relation between them is iFFT (FFT (x)) = x * nfft where nfft is the + * length of the FFT. This also has to be taken into account when calculation + * the magnitude of the frequency data. * */ @@ -200,71 +201,3 @@ gst_fft_f64_window (GstFFTF64 * self, gdouble * timedata, GstFFTWindow window) break; } } - -/** - * gst_fft_f64_magnitude: - * @self: #GstFFTF64 instance for this call - * @freqdata: Frequency domain samples - * @magnitude: Target buffer for the magnitude - * @decibel: %TRUE if the magnitude should be in decibel, %FALSE if it should be an amplitude - * - * This calculates the magnitude of @freqdata in @magnitude. Depending on the value - * of @decibel the magnitude can be calculated in decibel or as amplitude between 0.0 - * and 1.0. - * - * @magnitude must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_f64_magnitude (GstFFTF64 * self, GstFFTF64Complex * freqdata, - gdouble * magnitude, gboolean decibel) -{ - gint i, len, nfft; - gdouble val; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (magnitude); - - len = self->len / 2 + 1; - nfft = self->len; - - for (i = 0; i < len; i++) { - val = (gdouble) freqdata[i].r * (gdouble) freqdata[i].r - + (gdouble) freqdata[i].i * (gdouble) freqdata[i].i; - val = sqrt (val) / nfft; - - if (decibel) - val = 20.0 * log10 (val); - - magnitude[i] = val; - } -} - -/** - * gst_fft_f64_phase: - * @self: #GstFFTF64 instance for this call - * @freqdata: Frequency domain samples - * @phase: Target buffer for the phase - * - * This calculates the phases of @freqdata in @phase. The returned - * phases will be values between -pi and pi. - * - * @phase must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_f64_phase (GstFFTF64 * self, GstFFTF64Complex * freqdata, - gdouble * phase) -{ - gint i, len; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (phase); - - len = self->len / 2 + 1; - - for (i = 0; i < len; i++) - phase[i] = atan2 (freqdata[i].i, freqdata[i].r); -} diff --git a/gst-libs/gst/fft/gstfftf64.h b/gst-libs/gst/fft/gstfftf64.h index 99c1de2709..57ba5aab9c 100644 --- a/gst-libs/gst/fft/gstfftf64.h +++ b/gst-libs/gst/fft/gstfftf64.h @@ -69,9 +69,4 @@ void gst_fft_f64_free (GstFFTF64 *self); void gst_fft_f64_window (GstFFTF64 *self, gdouble *timedata, GstFFTWindow window); -void gst_fft_f64_magnitude (GstFFTF64 *self, GstFFTF64Complex *freqdata, - gdouble *magnitude, gboolean decibel); -void gst_fft_f64_phase (GstFFTF64 *self, GstFFTF64Complex *freqdata, - gdouble *phase); - #endif /* __GST_FFT_F64_H__ */ diff --git a/gst-libs/gst/fft/gstffts16.c b/gst-libs/gst/fft/gstffts16.c index 4827803047..8af64e3842 100644 --- a/gst-libs/gst/fft/gstffts16.c +++ b/gst-libs/gst/fft/gstffts16.c @@ -48,11 +48,12 @@ * to apply a window function to it. For this gst_fft_s16_window() can comfortably * be used. * - * For calculating the magnitude or phase of frequency data the functions - * gst_fft_s16_magnitude() and gst_fft_s16_phase() exist, if you want to calculate - * the magnitude yourself note that the magnitude of the frequency data is - * a value between 0 and 32767 and is not to be scaled by the length of the FFT. - * + * Be aware, that you can't simply run gst_fft_s16_inverse_fft() on the + * resulting frequency data of gst_fft_s16_fft() to get the original data back. + * The relation between them is iFFT (FFT (x)) = x / nfft where nfft is the + * length of the FFT. This also has to be taken into account when calculation + * the magnitude of the frequency data. + * */ /** @@ -200,70 +201,3 @@ gst_fft_s16_window (GstFFTS16 * self, gint16 * timedata, GstFFTWindow window) break; } } - -/** - * gst_fft_s16_magnitude: - * @self: #GstFFTS16 instance for this call - * @freqdata: Frequency domain samples - * @magnitude: Target buffer for the magnitude - * @decibel: %TRUE if the magnitude should be in decibel, %FALSE if it should be an amplitude - * - * This calculates the magnitude of @freqdata in @magnitude. Depending on the value - * of @decibel the magnitude can be calculated in decibel or as amplitude between 0.0 - * and 1.0. - * - * @magnitude must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_s16_magnitude (GstFFTS16 * self, GstFFTS16Complex * freqdata, - gdouble * magnitude, gboolean decibel) -{ - gint i, len; - gdouble val; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (magnitude); - - len = self->len / 2 + 1; - - for (i = 0; i < len; i++) { - val = (gdouble) freqdata[i].r * (gdouble) freqdata[i].r - + (gdouble) freqdata[i].i * (gdouble) freqdata[i].i; - val = sqrt (val) / 32767.0; - - if (decibel) - val = 20.0 * log10 (val); - - magnitude[i] = val; - } -} - -/** - * gst_fft_s16_phase: - * @self: #GstFFTS16 instance for this call - * @freqdata: Frequency domain samples - * @phase: Target buffer for the phase - * - * This calculates the phases of @freqdata in @phase. The returned - * phases will be values between -pi and pi. - * - * @phase must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_s16_phase (GstFFTS16 * self, GstFFTS16Complex * freqdata, - gdouble * phase) -{ - gint i, len; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (phase); - - len = self->len / 2 + 1; - - for (i = 0; i < len; i++) - phase[i] = atan2 (freqdata[i].i, freqdata[i].r); -} diff --git a/gst-libs/gst/fft/gstffts16.h b/gst-libs/gst/fft/gstffts16.h index 4c8e355061..d13b8973b5 100644 --- a/gst-libs/gst/fft/gstffts16.h +++ b/gst-libs/gst/fft/gstffts16.h @@ -68,10 +68,4 @@ void gst_fft_s16_inverse_fft (GstFFTS16 *self, const GstFFTS16Complex *freqdata, void gst_fft_s16_free (GstFFTS16 *self); void gst_fft_s16_window (GstFFTS16 *self, gint16 *timedata, GstFFTWindow window); - -void gst_fft_s16_magnitude (GstFFTS16 *self, GstFFTS16Complex *freqdata, - gdouble *magnitude, gboolean decibel); -void gst_fft_s16_phase (GstFFTS16 *self, GstFFTS16Complex *freqdata, - gdouble *phase); - #endif /* __GST_FFT_S16_H__ */ diff --git a/gst-libs/gst/fft/gstffts32.c b/gst-libs/gst/fft/gstffts32.c index 2851ae3970..574f8250a7 100644 --- a/gst-libs/gst/fft/gstffts32.c +++ b/gst-libs/gst/fft/gstffts32.c @@ -48,11 +48,11 @@ * to apply a window function to it. For this gst_fft_s32_window() can comfortably * be used. * - * For calculating the magnitude or phase of frequency data the functions - * gst_fft_s32_magnitude() and gst_fft_s32_phase() exist, if you want to calculate - * the magnitude yourself note that the magnitude of the frequency data is - * a value between 0 and 2147483647 and is not to be scaled by the length of the FFT. - * + * Be aware, that you can't simply run gst_fft_s32_inverse_fft() on the + * resulting frequency data of gst_fft_s32_fft() to get the original data back. + * The relation between them is iFFT (FFT (x)) = x / nfft where nfft is the + * length of the FFT. This also has to be taken into account when calculation + * the magnitude of the frequency data. */ /** @@ -200,70 +200,3 @@ gst_fft_s32_window (GstFFTS32 * self, gint32 * timedata, GstFFTWindow window) break; } } - -/** - * gst_fft_s32_magnitude: - * @self: #GstFFTS32 instance for this call - * @freqdata: Frequency domain samples - * @magnitude: Target buffer for the magnitude - * @decibel: %TRUE if the magnitude should be in decibel, %FALSE if it should be an amplitude - * - * This calculates the magnitude of @freqdata in @magnitude. Depending on the value - * of @decibel the magnitude can be calculated in decibel or as amplitude between 0.0 - * and 1.0. - * - * @magnitude must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_s32_magnitude (GstFFTS32 * self, GstFFTS32Complex * freqdata, - gdouble * magnitude, gboolean decibel) -{ - gint i, len; - gdouble val; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (magnitude); - - len = self->len / 2 + 1; - - for (i = 0; i < len; i++) { - val = (gdouble) freqdata[i].r * (gdouble) freqdata[i].r - + (gdouble) freqdata[i].i * (gdouble) freqdata[i].i; - val = sqrt (val) / 2147483647.0; - - if (decibel) - val = 20.0 * log10 (val); - - magnitude[i] = val; - } -} - -/** - * gst_fft_s32_phase: - * @self: #GstFFTS32 instance for this call - * @freqdata: Frequency domain samples - * @phase: Target buffer for the phase - * - * This calculates the phases of @freqdata in @phase. The returned - * phases will be values between -pi and pi. - * - * @phase must be large enough to hold @len/2 + 1 values. - * - */ -void -gst_fft_s32_phase (GstFFTS32 * self, GstFFTS32Complex * freqdata, - gdouble * phase) -{ - gint i, len; - - g_return_if_fail (self); - g_return_if_fail (freqdata); - g_return_if_fail (phase); - - len = self->len / 2 + 1; - - for (i = 0; i < len; i++) - phase[i] = atan2 (freqdata[i].i, freqdata[i].r); -} diff --git a/gst-libs/gst/fft/gstffts32.h b/gst-libs/gst/fft/gstffts32.h index a495fd9a2e..b4da3dcc3a 100644 --- a/gst-libs/gst/fft/gstffts32.h +++ b/gst-libs/gst/fft/gstffts32.h @@ -69,9 +69,4 @@ void gst_fft_s32_free (GstFFTS32 *self); void gst_fft_s32_window (GstFFTS32 *self, gint32 *timedata, GstFFTWindow window); -void gst_fft_s32_magnitude (GstFFTS32 *self, GstFFTS32Complex *freqdata, - gdouble *magnitude, gboolean decibel); -void gst_fft_s32_phase (GstFFTS32 *self, GstFFTS32Complex *freqdata, - gdouble *phase); - #endif /* __GST_FFT_S32_H__ */ diff --git a/tests/check/libs/fft.c b/tests/check/libs/fft.c index 3a30111d46..c39a7f28c2 100644 --- a/tests/check/libs/fft.c +++ b/tests/check/libs/fft.c @@ -47,12 +47,10 @@ GST_START_TEST (test_s16_0hz) gint i; gint16 *in; GstFFTS16Complex *out; - gdouble *mag; GstFFTS16 *ctx; in = g_new (gint16, 2048); out = g_new (GstFFTS16Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_s16_new (2048, FALSE); for (i = 0; i < 2048; i++) @@ -60,17 +58,24 @@ GST_START_TEST (test_s16_0hz) gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_s16_fft (ctx, in, out); - gst_fft_s16_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i < 2 && mag[i] < -15.0); - fail_if (i >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag *= 2048.0; + mag /= 32767.0 * 32767.0; + mag = 10.0 * log10 (mag); + if (i < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -55.0); } gst_fft_s16_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -80,12 +85,10 @@ GST_START_TEST (test_s16_11025hz) gint i; gint16 *in; GstFFTS16Complex *out; - gdouble *mag; GstFFTS16 *ctx; in = g_new (gint16, 2048); out = g_new (GstFFTS16Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_s16_new (2048, FALSE); for (i = 0; i < 2048; i += 4) { @@ -97,17 +100,25 @@ GST_START_TEST (test_s16_11025hz) gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_s16_fft (ctx, in, out); - gst_fft_s16_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (abs (512 - i) < 2 && mag[i] < -20.0); - fail_if (abs (512 - i) >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag *= 2048.0; + mag /= 32767.0 * 32767.0; + mag = 10.0 * log10 (mag); + + if (abs (512 - i) < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -55.0); } gst_fft_s16_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -117,12 +128,10 @@ GST_START_TEST (test_s16_22050hz) gint i; gint16 *in; GstFFTS16Complex *out; - gdouble *mag; GstFFTS16 *ctx; in = g_new (gint16, 2048); out = g_new (GstFFTS16Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_s16_new (2048, FALSE); for (i = 0; i < 2048; i += 2) { @@ -132,17 +141,25 @@ GST_START_TEST (test_s16_22050hz) gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_s16_fft (ctx, in, out); - gst_fft_s16_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i > 1022 && mag[i] < -20.0); - fail_if (i <= 1022 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag *= 2048.0; + mag /= 32767.0 * 32767.0; + mag = 10.0 * log10 (mag); + + if (i > 1022) + fail_unless (mag > -15.0); + else + fail_unless (mag < -55.0); } gst_fft_s16_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -152,12 +169,10 @@ GST_START_TEST (test_s32_0hz) gint i; gint32 *in; GstFFTS32Complex *out; - gdouble *mag; GstFFTS32 *ctx; in = g_new (gint32, 2048); out = g_new (GstFFTS32Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_s32_new (2048, FALSE); for (i = 0; i < 2048; i++) @@ -165,17 +180,25 @@ GST_START_TEST (test_s32_0hz) gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_s32_fft (ctx, in, out); - gst_fft_s32_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i < 2 && mag[i] < -15.0); - fail_if (i >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag *= 2048.0; + mag /= 2147483647.0 * 2147483647.0; + mag = 10.0 * log10 (mag); + + if (i < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_s32_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -185,12 +208,10 @@ GST_START_TEST (test_s32_11025hz) gint i; gint32 *in; GstFFTS32Complex *out; - gdouble *mag; GstFFTS32 *ctx; in = g_new (gint32, 2048); out = g_new (GstFFTS32Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_s32_new (2048, FALSE); for (i = 0; i < 2048; i += 4) { @@ -202,17 +223,25 @@ GST_START_TEST (test_s32_11025hz) gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_s32_fft (ctx, in, out); - gst_fft_s32_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (abs (512 - i) < 2 && mag[i] < -20.0); - fail_if (abs (512 - i) >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag *= 2048.0; + mag /= 2147483647.0 * 2147483647.0; + mag = 10.0 * log10 (mag); + + if (abs (512 - i) < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_s32_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -222,12 +251,10 @@ GST_START_TEST (test_s32_22050hz) gint i; gint32 *in; GstFFTS32Complex *out; - gdouble *mag; GstFFTS32 *ctx; in = g_new (gint32, 2048); out = g_new (GstFFTS32Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_s32_new (2048, FALSE); for (i = 0; i < 2048; i += 2) { @@ -237,17 +264,25 @@ GST_START_TEST (test_s32_22050hz) gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_s32_fft (ctx, in, out); - gst_fft_s32_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i > 1022 && mag[i] < -20.0); - fail_if (i <= 1022 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag *= 2048.0; + mag /= 2147483647.0 * 2147483647.0; + mag = 10.0 * log10 (mag); + + if (i > 1022) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_s32_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -257,12 +292,10 @@ GST_START_TEST (test_f32_0hz) gint i; gfloat *in; GstFFTF32Complex *out; - gdouble *mag; GstFFTF32 *ctx; in = g_new (gfloat, 2048); out = g_new (GstFFTF32Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_f32_new (2048, FALSE); for (i = 0; i < 2048; i++) @@ -270,17 +303,24 @@ GST_START_TEST (test_f32_0hz) gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_f32_fft (ctx, in, out); - gst_fft_f32_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i < 2 && mag[i] < -15.0); - fail_if (i >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag /= 2048.0; + mag = 10.0 * log10 (mag); + + if (i < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_f32_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -290,12 +330,10 @@ GST_START_TEST (test_f32_11025hz) gint i; gfloat *in; GstFFTF32Complex *out; - gdouble *mag; GstFFTF32 *ctx; in = g_new (gfloat, 2048); out = g_new (GstFFTF32Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_f32_new (2048, FALSE); for (i = 0; i < 2048; i += 4) { @@ -307,17 +345,24 @@ GST_START_TEST (test_f32_11025hz) gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_f32_fft (ctx, in, out); - gst_fft_f32_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (abs (512 - i) < 2 && mag[i] < -20.0); - fail_if (abs (512 - i) >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag /= 2048.0; + mag = 10.0 * log10 (mag); + + if (abs (512 - i) < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_f32_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -327,12 +372,10 @@ GST_START_TEST (test_f32_22050hz) gint i; gfloat *in; GstFFTF32Complex *out; - gdouble *mag; GstFFTF32 *ctx; in = g_new (gfloat, 2048); out = g_new (GstFFTF32Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_f32_new (2048, FALSE); for (i = 0; i < 2048; i += 2) { @@ -342,17 +385,24 @@ GST_START_TEST (test_f32_22050hz) gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_f32_fft (ctx, in, out); - gst_fft_f32_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i > 1022 && mag[i] < -20.0); - fail_if (i <= 1022 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag /= 2048.0; + mag = 10.0 * log10 (mag); + + if (i > 1022) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_f32_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -362,12 +412,10 @@ GST_START_TEST (test_f64_0hz) gint i; gdouble *in; GstFFTF64Complex *out; - gdouble *mag; GstFFTF64 *ctx; in = g_new (gdouble, 2048); out = g_new (GstFFTF64Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_f64_new (2048, FALSE); for (i = 0; i < 2048; i++) @@ -375,17 +423,24 @@ GST_START_TEST (test_f64_0hz) gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_f64_fft (ctx, in, out); - gst_fft_f64_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i < 2 && mag[i] < -15.0); - fail_if (i >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag /= 2048.0; + mag = 10.0 * log10 (mag); + + if (i < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_f64_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -395,12 +450,10 @@ GST_START_TEST (test_f64_11025hz) gint i; gdouble *in; GstFFTF64Complex *out; - gdouble *mag; GstFFTF64 *ctx; in = g_new (gdouble, 2048); out = g_new (GstFFTF64Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_f64_new (2048, FALSE); for (i = 0; i < 2048; i += 4) { @@ -412,17 +465,24 @@ GST_START_TEST (test_f64_11025hz) gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_f64_fft (ctx, in, out); - gst_fft_f64_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (abs (512 - i) < 2 && mag[i] < -20.0); - fail_if (abs (512 - i) >= 2 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag /= 2048.0; + mag = 10.0 * log10 (mag); + + if (abs (512 - i) < 2) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_f64_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST; @@ -432,12 +492,10 @@ GST_START_TEST (test_f64_22050hz) gint i; gdouble *in; GstFFTF64Complex *out; - gdouble *mag; GstFFTF64 *ctx; in = g_new (gdouble, 2048); out = g_new (GstFFTF64Complex, 1025); - mag = g_new (gdouble, 1025); ctx = gst_fft_f64_new (2048, FALSE); for (i = 0; i < 2048; i += 2) { @@ -447,17 +505,24 @@ GST_START_TEST (test_f64_22050hz) gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING); gst_fft_f64_fft (ctx, in, out); - gst_fft_f64_magnitude (ctx, out, mag, TRUE); for (i = 0; i < 1025; i++) { - fail_if (i > 1022 && mag[i] < -20.0); - fail_if (i <= 1022 && mag[i] > -60.0); + gdouble mag; + + mag = (gdouble) out[i].r * (gdouble) out[i].r; + mag += (gdouble) out[i].i * (gdouble) out[i].i; + mag /= 2048.0; + mag = 10.0 * log10 (mag); + + if (i > 1022) + fail_unless (mag > -15.0); + else + fail_unless (mag < -60.0); } gst_fft_f64_free (ctx); g_free (in); g_free (out); - g_free (mag); } GST_END_TEST;