aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2014-10-03 15:11:03 +0200
committerSylvain Munaut <tnt@246tNt.com>2014-10-04 02:12:13 +0200
commit369d789c221b53c0a4f54d5ad88049c63fbbee43 (patch)
tree3cf868cdfe6b1a5ab1de4d3ada5fc14b1f2f72c9
parent5c817d55154bfd9dff3e6a00e0e524c7f0511453 (diff)
codec/math: Import new function fo DWT float<->complex
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--src/codec/math.c64
-rw-r--r--src/codec/private.h4
2 files changed, 66 insertions, 2 deletions
diff --git a/src/codec/math.c b/src/codec/math.c
index ffad9ad..b93d837 100644
--- a/src/codec/math.c
+++ b/src/codec/math.c
@@ -27,8 +27,7 @@
#include <math.h>
-
-#define M_PIf ((float)M_PI) /*!< \brief Value of pi as a float */
+#include "private.h"
/*! \brief Table for \ref cosf_fast and \ref sinf_fast */
@@ -115,4 +114,65 @@ ambe_idct(float *out, float *in, int N, int M)
}
}
+/*! \brief Forward Discrete Fourrier Transform (float->complex)
+ * \param[out] out_i Real component result buffer (freq domain, N/2+1 elements)
+ * \param[out] out_q Imag component result buffer (freq domain, N/2+1 elements)
+ * \param[in] in Input buffer (time domain, M elements)
+ * \param[in] N Number of points of the DFT
+ * \param[in] M Limit to to the number of available time domain elements
+ *
+ * Since the input is float, the result is symmetric and so only one side
+ * is computed. The output index 0 is DC.
+ */
+void
+ambe_fdft_fc(float *out_i, float *out_q, float *in, int N, int M)
+{
+ int fb, ts;
+
+ for (fb=0; fb<=(N/2); fb++)
+ {
+ float i=0.0f, q=0.0f;
+
+ for (ts=0; ts<M; ts++)
+ {
+ float angle = (- 2.0f * M_PIf / N) * fb * ts;
+ i += in[ts] * cosf_fast(angle);
+ q += in[ts] * sinf_fast(angle);
+ }
+
+ out_i[fb] = i;
+ out_q[fb] = q;
+ }
+}
+
+/*! \brief Inverse Discret Fourrier Transform (complex->float)
+ * \param[out] out Result buffer (time domain, M
+ * \param[in] in_i Real component input buffer (freq domain, N/2+1 elements)
+ * \param[in] in_q Imag component input buffer (freq domain, N/2+1 elements)
+ * \param[in] N Number of points of the DFT
+ * \param[in] M Limit to the number of time domain elements to generate
+ *
+ * The input is assumed to be symmetric and so only N/2+1 inputs are
+ * needed. DC component must be input index 0.
+ */
+void
+ambe_idft_cf(float *out, float *in_i, float *in_q, int N, int M)
+{
+ int fb, ts;
+
+ for (ts=0; ts<M; ts++)
+ {
+ float r=0.0f;
+
+ for (fb=0; fb<=(N/2); fb++)
+ {
+ float angle = (- 2.0f * M_PIf / N) * fb * ts;
+ float m = (fb == 0 || fb == (N/2)) ? 1.0f : 2.0f;
+ r += m * (in_i[fb] * cosf_fast(angle) + in_q[fb] * sinf_fast(angle));
+ }
+
+ out[ts] = r / N;
+ }
+}
+
/*! @} */
diff --git a/src/codec/private.h b/src/codec/private.h
index 9a44b7a..177947b 100644
--- a/src/codec/private.h
+++ b/src/codec/private.h
@@ -103,10 +103,14 @@ int ambe_frame_decode_params(struct ambe_subframe *sf,
struct ambe_raw_params *rp);
/* From math.c */
+#define M_PIf (3.141592653589793f) /*!< \brief Value of pi as a float */
+
float cosf_fast(float angle);
float sinf_fast(float angle);
void ambe_fdct(float *out, float *in, int N, int M);
void ambe_idct(float *out, float *in, int N, int M);
+void ambe_fdft_fc(float *out_i, float *out_q, float *in, int N, int M);
+void ambe_idft_cf(float *out, float *in_i, float *in_q, int N, int M);
/* From tables.c */
extern const uint8_t ambe_hpg_tbl[48][4];