Also adds QA code to test decimate by 2 and 5.
Removes lib/filter/gri_fir_filter_with_buffer_ccf.h that is autogenerated.
return (@O_TYPE@)out;
}
+@O_TYPE@
+@NAME@::filter (const @I_TYPE@ input[], unsigned long dec)
+{
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ @ACC_TYPE@ out = 0;
+ for(i = 0; i < ntaps(); i++) {
+ out += @INPUT_CAST@ d_buffer[d_idx + i] * d_taps[i];
+ }
+ return (@O_TYPE@)out;
+}
+
void
@NAME@::filterN (@O_TYPE@ output[],
const @I_TYPE@ input[],
output[i] = filter(input[i]);
}
}
+
+void
+@NAME@::filterNdec (@O_TYPE@ output[],
+ const @I_TYPE@ input[],
+ unsigned long n,
+ unsigned long decimate)
+{
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+}
/*!
* \brief compute a single output value.
*
- * \p input must have ntaps() valid entries.
- * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ * \p input is a single input value of the filter type
*
* \returns the filtered input value.
*/
@O_TYPE@ filter (@I_TYPE@ input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ @O_TYPE@ filter (const @I_TYPE@ input[], unsigned long dec);
+
/*!
* \brief compute an array of N output values.
*
* compute the output values.
*/
void filterNdec (@O_TYPE@ output[], const @I_TYPE@ input[],
- unsigned long n, unsigned decimate);
+ unsigned long n, unsigned long decimate);
/*!
* \brief install \p new_taps as the current taps.
/*!
* \brief compute a single output value.
*
- * \p input must have ntaps() valid entries.
- * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ * \p input is a single input value of the filter type
*
* \returns the filtered input value.
*/
gr_complex filter (gr_complex input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter (const gr_complex input[], unsigned long dec);
+
/*!
* \brief compute an array of N output values.
*
* compute the output values.
*/
void filterNdec (gr_complex output[], const gr_complex input[],
- unsigned long n, unsigned decimate);
+ unsigned long n, unsigned long decimate);
/*!
* \brief install \p new_taps as the current taps.
return sum;
}
+void
+qa_gri_fir_filter_with_buffer_ccc::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccc::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccc::t3 ()
+{
+ test_decimate(5);
+}
+
//
// Test for ntaps in [0,9], and input lengths in [0,17].
// This ensures that we are building the shifted taps correctly,
// and exercises all corner cases on input alignment and length.
//
-
void
-qa_gri_fir_filter_with_buffer_ccc::t1 ()
+qa_gri_fir_filter_with_buffer_ccc::test_decimate(unsigned int decimate)
{
const int MAX_TAPS = 9;
const int OUTPUT_LEN = 17;
// compute expected output values
memset(dline, 0, INPUT_LEN*sizeof(i_type));
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
// use an actual delay line for this test
- for(int oo = INPUT_LEN-1; oo > 0; oo--)
- dline[oo] = dline[oo-1];
- dline[0] = input[o];
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
expected_output[o] = ref_dotprod (dline, taps, n);
}
// zero the output, then do the filtering
memset (actual_output, 0, sizeof (actual_output));
- f1->filterN (actual_output, input, ol);
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
// check results
//
// arithmetic, while the SSE version is using 32 bit float point
// arithmetic.
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
abs (expected_output[o]) * ERR_DELTA);
}
CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_ccc);
CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
CPPUNIT_TEST_SUITE_END ();
private:
+ void test_decimate(unsigned int decimate);
void t1 ();
- // void t2 ();
- // void t3 ();
+ void t2 ();
+ void t3 ();
};
return sum;
}
+void
+qa_gri_fir_filter_with_buffer_ccf::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccf::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccf::t3 ()
+{
+ test_decimate(5);
+}
+
//
// Test for ntaps in [0,9], and input lengths in [0,17].
// This ensures that we are building the shifted taps correctly,
// and exercises all corner cases on input alignment and length.
//
-
void
-qa_gri_fir_filter_with_buffer_ccf::t1 ()
+qa_gri_fir_filter_with_buffer_ccf::test_decimate (unsigned int decimate)
{
const int MAX_TAPS = 9;
const int OUTPUT_LEN = 17;
// compute expected output values
memset(dline, 0, INPUT_LEN*sizeof(i_type));
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
// use an actual delay line for this test
- for(int oo = INPUT_LEN-1; oo > 0; oo--)
- dline[oo] = dline[oo-1];
- dline[0] = input[o];
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
expected_output[o] = ref_dotprod (dline, taps, n);
}
// zero the output, then do the filtering
memset (actual_output, 0, sizeof (actual_output));
- f1->filterN (actual_output, input, ol);
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
// check results
//
// arithmetic, while the SSE version is using 32 bit float point
// arithmetic.
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
abs (expected_output[o]) * ERR_DELTA);
}
CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_ccf);
CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
CPPUNIT_TEST_SUITE_END ();
private:
+ void test_decimate(unsigned int decimate);
void t1 ();
- // void t2 ();
- // void t3 ();
+ void t2 ();
+ void t3 ();
};
return sum;
}
+void
+qa_gri_fir_filter_with_buffer_fcc::t1()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fcc::t2()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fcc::t3()
+{
+ test_decimate(5);
+}
+
+
//
// Test for ntaps in [0,9], and input lengths in [0,17].
// This ensures that we are building the shifted taps correctly,
// and exercises all corner cases on input alignment and length.
//
-
void
-qa_gri_fir_filter_with_buffer_fcc::t1 ()
+qa_gri_fir_filter_with_buffer_fcc::test_decimate(unsigned int decimate)
{
const int MAX_TAPS = 9;
const int OUTPUT_LEN = 17;
// compute expected output values
memset(dline, 0, INPUT_LEN*sizeof(i_type));
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
// use an actual delay line for this test
- for(int oo = INPUT_LEN-1; oo > 0; oo--)
- dline[oo] = dline[oo-1];
- dline[0] = input[o];
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
expected_output[o] = ref_dotprod (dline, taps, n);
}
// zero the output, then do the filtering
memset (actual_output, 0, sizeof (actual_output));
- f1->filterN (actual_output, input, ol);
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
// check results
//
// arithmetic, while the SSE version is using 32 bit float point
// arithmetic.
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
abs (expected_output[o]) * ERR_DELTA);
}
CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_fcc);
CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
CPPUNIT_TEST_SUITE_END ();
private:
+ void test_decimate(unsigned int decimate);
void t1 ();
- // void t2 ();
- // void t3 ();
+ void t2 ();
+ void t3 ();
};
return sum;
}
+void
+qa_gri_fir_filter_with_buffer_fff::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fff::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fff::t3 ()
+{
+ test_decimate(5);
+}
+
//
// Test for ntaps in [0,9], and input lengths in [0,17].
// This ensures that we are building the shifted taps correctly,
// and exercises all corner cases on input alignment and length.
//
-
void
-qa_gri_fir_filter_with_buffer_fff::t1 ()
+qa_gri_fir_filter_with_buffer_fff::test_decimate(unsigned int decimate)
{
const int MAX_TAPS = 9;
const int OUTPUT_LEN = 17;
// compute expected output values
memset(dline, 0, INPUT_LEN*sizeof(i_type));
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
// use an actual delay line for this test
- for(int oo = INPUT_LEN-1; oo > 0; oo--)
- dline[oo] = dline[oo-1];
- dline[0] = input[o];
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
expected_output[o] = ref_dotprod (dline, taps, n);
}
// zero the output, then do the filtering
memset (actual_output, 0, sizeof (actual_output));
- f1->filterN (actual_output, input, ol);
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
// check results
//
// arithmetic, while the SSE version is using 32 bit float point
// arithmetic.
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
CPPUNIT_ASSERT_DOUBLES_EQUAL(expected_output[o], actual_output[o],
fabsf (expected_output[o]) * ERR_DELTA);
}
CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_fff);
CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
CPPUNIT_TEST_SUITE_END ();
private:
+ void test_decimate(unsigned int decimate);
void t1 ();
- // void t2 ();
- // void t3 ();
+ void t2 ();
+ void t3 ();
};
return (o_type)sum;
}
+void
+qa_gri_fir_filter_with_buffer_fsf::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fsf::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fsf::t3 ()
+{
+ test_decimate(5);
+}
+
//
// Test for ntaps in [0,9], and input lengths in [0,17].
// This ensures that we are building the shifted taps correctly,
// and exercises all corner cases on input alignment and length.
//
-
void
-qa_gri_fir_filter_with_buffer_fsf::t1 ()
+qa_gri_fir_filter_with_buffer_fsf::test_decimate (unsigned int decimate)
{
const int MAX_TAPS = 9;
const int OUTPUT_LEN = 17;
// compute expected output values
memset(dline, 0, INPUT_LEN*sizeof(i_type));
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
// use an actual delay line for this test
- for(int oo = INPUT_LEN-1; oo > 0; oo--)
- dline[oo] = dline[oo-1];
- dline[0] = input[o];
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
expected_output[o] = ref_dotprod (dline, taps, n);
}
// zero the output, then do the filtering
memset (actual_output, 0, sizeof (actual_output));
- f1->filterN (actual_output, input, ol);
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
// check results
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
CPPUNIT_ASSERT_EQUAL(expected_output[o], actual_output[o]);
}
delete f1;
CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_fsf);
CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
CPPUNIT_TEST_SUITE_END ();
private:
-
+ void test_decimate(unsigned int decimate);
+
void t1 ();
- // void t2 ();
- // void t3 ();
+ void t2 ();
+ void t3 ();
};
return sum;
}
+void
+qa_gri_fir_filter_with_buffer_scc::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_scc::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_scc::t3 ()
+{
+ test_decimate(5);
+}
+
//
// Test for ntaps in [0,9], and input lengths in [0,17].
// This ensures that we are building the shifted taps correctly,
// and exercises all corner cases on input alignment and length.
//
-
void
-qa_gri_fir_filter_with_buffer_scc::t1 ()
+qa_gri_fir_filter_with_buffer_scc::test_decimate (unsigned int decimate)
{
const int MAX_TAPS = 9;
const int OUTPUT_LEN = 17;
// compute expected output values
memset(dline, 0, INPUT_LEN*sizeof(i_type));
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
// use an actual delay line for this test
- for(int oo = INPUT_LEN-1; oo > 0; oo--)
- dline[oo] = dline[oo-1];
- dline[0] = input[o];
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
expected_output[o] = ref_dotprod (dline, taps, n);
}
// zero the output, then do the filtering
memset (actual_output, 0, sizeof (actual_output));
- f1->filterN (actual_output, input, ol);
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
// check results
//
// arithmetic, while the SSE version is using 32 bit float point
// arithmetic.
- for (int o = 0; o < ol; o++){
+ for (int o = 0; o < (int)(ol/decimate); o++){
CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
abs (expected_output[o]) * ERR_DELTA);
}
CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_scc);
CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
CPPUNIT_TEST_SUITE_END ();
private:
+ void test_decimate(unsigned int decimate);
void t1 ();
- // void t2 ();
- // void t3 ();
+ void t2 ();
+ void t3 ();
};