r3965 - in trunk/bse: . tests
- From: stw svn gnome org
- To: svn-commits-list gnome org
- Subject: r3965 - in trunk/bse: . tests
- Date: Thu, 12 Oct 2006 16:11:33 -0400 (EDT)
Author: stw
Date: 2006-10-12 16:11:29 -0400 (Thu, 12 Oct 2006)
New Revision: 3965
Modified:
trunk/bse/ChangeLog
trunk/bse/bseresampler.cc
trunk/bse/bseresampler.hh
trunk/bse/bseresamplerimpl.hh
trunk/bse/tests/resamplehandle.cc
Log:
Thu Oct 12 21:48:54 2006 Stefan Westerfeld <stefan space twc de>
* bseresampler.hh:
* bseresampler.cc:
* bseresamplerimpl.hh: Added a virtual function Resampler2::delay(),
which can be used for compensation of the resampler introduced delay.
Provide C API wrapper for the function: bse_resampler2_delay().
* tests/resamplehandle.cc: Test the delay compensation function.
Fix a buglet in another test (comparing signals needs fabs()).
Modified: trunk/bse/ChangeLog
===================================================================
--- trunk/bse/ChangeLog 2006-10-12 18:45:54 UTC (rev 3964)
+++ trunk/bse/ChangeLog 2006-10-12 20:11:29 UTC (rev 3965)
@@ -1,3 +1,14 @@
+Thu Oct 12 21:48:54 2006 Stefan Westerfeld <stefan space twc de>
+
+ * bseresampler.hh:
+ * bseresampler.cc:
+ * bseresamplerimpl.hh: Added a virtual function Resampler2::delay(),
+ which can be used for compensation of the resampler introduced delay.
+ Provide C API wrapper for the function: bse_resampler2_delay().
+
+ * tests/resamplehandle.cc: Test the delay compensation function.
+ Fix a buglet in another test (comparing signals needs fabs()).
+
Thu Oct 12 16:54:42 2006 Stefan Westerfeld <stefan space twc de>
* gslfft.h: Improved documentation on FFT normalization.
Modified: trunk/bse/bseresampler.cc
===================================================================
--- trunk/bse/bseresampler.cc 2006-10-12 18:45:54 UTC (rev 3964)
+++ trunk/bse/bseresampler.cc 2006-10-12 20:11:29 UTC (rev 3965)
@@ -295,3 +295,9 @@
{
return reinterpret_cast<Bse::Resampler::Resampler2 *> (resampler)->order();
}
+
+double
+bse_resampler2_delay (BseResampler2 *resampler)
+{
+ return reinterpret_cast<Bse::Resampler::Resampler2 *> (resampler)->delay();
+}
Modified: trunk/bse/bseresampler.hh
===================================================================
--- trunk/bse/bseresampler.hh 2006-10-12 18:45:54 UTC (rev 3964)
+++ trunk/bse/bseresampler.hh 2006-10-12 20:11:29 UTC (rev 3965)
@@ -48,6 +48,7 @@
unsigned int n_input_samples,
float *output);
guint bse_resampler2_order (BseResampler2 *resampler);
+double bse_resampler2_delay (BseResampler2 *resampler);
G_END_DECLS
@@ -79,6 +80,18 @@
* return FIR filter order
*/
virtual guint order() const = 0;
+ /**
+ * Return the delay introduced by the resampler. This delay is guaranteed to
+ * be >= 0.0, and for factor 2 resampling always a multiple of 0.5.
+ *
+ * The return value can also be thought of the index in the output signal,
+ * where the first input sample can be found.
+ *
+ * Beware of fractional delays, for instance for downsampling, a delay() of
+ * 10.5 means that the first input sample would be found by interpolating
+ * output[10] and output[11], and the second input sample equates output[11].
+ */
+ virtual double delay() const = 0;
protected:
static const double halfband_fir_48db_coeffs[16];
static const double halfband_fir_72db_coeffs[24];
Modified: trunk/bse/bseresamplerimpl.hh
===================================================================
--- trunk/bse/bseresamplerimpl.hh 2006-10-12 18:45:54 UTC (rev 3964)
+++ trunk/bse/bseresamplerimpl.hh 2006-10-12 20:11:29 UTC (rev 3965)
@@ -397,6 +397,11 @@
{
return ORDER;
}
+ double
+ delay() const
+ {
+ return order() + 2;
+ }
};
/**
@@ -569,6 +574,11 @@
{
return ORDER;
}
+ double
+ delay() const
+ {
+ return order() / 2 + 0.5;
+ }
};
template<bool USE_SSE> Resampler2*
Modified: trunk/bse/tests/resamplehandle.cc
===================================================================
--- trunk/bse/tests/resamplehandle.cc 2006-10-12 18:45:54 UTC (rev 3964)
+++ trunk/bse/tests/resamplehandle.cc 2006-10-12 20:11:29 UTC (rev 3965)
@@ -259,7 +259,7 @@
{
double expected = sin ((i - delay) * 220 * 2 * M_PI / 44100)
* bse_window_blackman ((double) ((i - delay) * 2 - OUTPUT_SIZE) / OUTPUT_SIZE);
- error = MAX (error, out[i] - expected);
+ error = MAX (error, fabs (out[i] - expected));
}
double error_db = bse_db_from_factor (error, -200);
@@ -271,6 +271,83 @@
TDONE();
}
+static void
+test_delay_compensation (const char *run_type)
+{
+ struct TestParameters {
+ double error_db;
+ BseResampler2Mode mode;
+ BseResampler2Precision precision;
+ } params[] =
+ {
+ { 200, BSE_RESAMPLER2_MODE_UPSAMPLE, BSE_RESAMPLER2_PREC_48DB },
+ { 200, BSE_RESAMPLER2_MODE_UPSAMPLE, BSE_RESAMPLER2_PREC_72DB },
+ { 200, BSE_RESAMPLER2_MODE_UPSAMPLE, BSE_RESAMPLER2_PREC_96DB },
+ { 200, BSE_RESAMPLER2_MODE_UPSAMPLE, BSE_RESAMPLER2_PREC_120DB },
+ { 200, BSE_RESAMPLER2_MODE_UPSAMPLE, BSE_RESAMPLER2_PREC_144DB },
+ { 48, BSE_RESAMPLER2_MODE_DOWNSAMPLE, BSE_RESAMPLER2_PREC_48DB },
+ { 67, BSE_RESAMPLER2_MODE_DOWNSAMPLE, BSE_RESAMPLER2_PREC_72DB },
+ { 96, BSE_RESAMPLER2_MODE_DOWNSAMPLE, BSE_RESAMPLER2_PREC_96DB },
+ { 120, BSE_RESAMPLER2_MODE_DOWNSAMPLE, BSE_RESAMPLER2_PREC_120DB },
+ { 134, BSE_RESAMPLER2_MODE_DOWNSAMPLE, BSE_RESAMPLER2_PREC_144DB },
+ { -1, }
+ };
+
+ using Bse::Resampler::Resampler2;
+ TSTART ("Resampler Delay Compensation (%s)", run_type);
+
+ for (guint p = 0; params[p].error_db > 0; p++)
+ {
+ /* setup test signal and empty output signal space */
+ const int INPUT_SIZE = 44100 * 4, OUTPUT_SIZE = INPUT_SIZE * 2;
+
+ vector<float> in (INPUT_SIZE);
+ vector<float> out (OUTPUT_SIZE);
+
+ generate_test_signal (in, INPUT_SIZE, 44100, 440);
+
+ /* up/downsample test signal */
+ Resampler2 *resampler = Resampler2::create (params[p].mode,
+ params[p].precision);
+ resampler->process_block (&in[0], INPUT_SIZE, &out[0]);
+
+ /* setup increments for comparision loop */
+ size_t iinc = 1, jinc = 1;
+ if (params[p].mode == BSE_RESAMPLER2_MODE_UPSAMPLE)
+ jinc = 2;
+ else
+ iinc = 2;
+
+ /* compensate resampler delay by incrementing comparision start offset */
+ double delay = resampler->delay();
+ size_t i = 0, j = (int) round (delay * 2);
+ if (j % 2)
+ {
+ /* implement half a sample delay (for downsampling only) */
+ g_assert (params[p].mode == BSE_RESAMPLER2_MODE_DOWNSAMPLE);
+ i++;
+ j += 2;
+ }
+ j /= 2;
+
+ /* actually compare source and resampled signal (one with a stepping of 2) */
+ double error = 0;
+ while (i < in.size() && j < out.size())
+ {
+ error = MAX (error, fabs (out[j] - in[i]));
+ i += iinc; j += jinc;
+ }
+
+ delete resampler;
+
+ /* check error against bound */
+ double error_db = bse_db_from_factor (error, -250);
+ TPRINT ("Resampler Delay Compensation delta: %f\n", error_db);
+ TASSERT (error_db < -params[p].error_db);
+ }
+ TDONE();
+}
+
int
main (int argc,
char *argv[])
@@ -278,6 +355,7 @@
sfi_init_test (&argc, &argv, NULL);
test_c_api ("FPU");
+ test_delay_compensation ("FPU");
run_tests ("FPU");
/* load plugins */
@@ -291,6 +369,7 @@
return 0; /* nothing changed */
test_c_api ("SSE");
+ test_delay_compensation ("SSE");
run_tests ("SSE");
return 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]