shithub: opus

Download patch

ref: 7137c26e4fce297c42a1f0baf9717d7b04f44673
parent: 7e94cc4d95bea05c206556956642f723d9e52f93
author: Jean-Marc Valin <[email protected]>
date: Tue Mar 4 12:43:09 EST 2008

fixed-point: exp_rotation() now fully converted, using an approximation of the
cos() and sin() functions.

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -40,12 +40,13 @@
 #include "cwrs.h"
 
 
-void exp_rotation(celt_norm_t *X, int len, float theta, int dir, int stride, int iter)
+void exp_rotation(celt_norm_t *X, int len, celt_word16_t theta, int dir, int stride, int iter)
 {
    int i, k;
    celt_word16_t c, s;
-   c = Q15ONE*cos(theta);
-   s = dir*Q15ONE*sin(theta);
+   /* c = cos(theta); s = dir*sin(theta); but we're approximating here for small theta */
+   c = Q15ONE-MULT16_16_Q15(QCONST16(.5f,15),MULT16_16_Q15(theta,theta));
+   s = dir*theta;
    for (k=0;k<iter;k++)
    {
       /* We could use MULT16_16_P15 instead of MULT16_16_Q15 for more accuracy, 
@@ -251,12 +252,13 @@
    for (i=0;i<m->nbEBands;i++)
    {
       int q;
-      float theta, n;
+      celt_word16_t theta;
+      float n;
       q = pulses[i];
       /*Scale factor of .0625f is just there to prevent overflows in fixed-point
        (has no effect on float)*/
       n = .0625f*sqrt(B*(eBands[i+1]-eBands[i]));
-      theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+q);
+      theta = Q15ONE*.007*(B*(eBands[i+1]-eBands[i]))/(.1f+q);
 
       /* If pitch isn't available, use intra-frame prediction */
       if (eBands[i] >= m->pitchEnd || q<=0)
@@ -312,12 +314,13 @@
    for (i=0;i<m->nbEBands;i++)
    {
       int q;
-      float theta, n;
+      celt_word16_t theta;
+      float n;
       q = pulses[i];
       /*Scale factor of .0625f is just there to prevent overflows in fixed-point
       (has no effect on float)*/
       n = .0625f*sqrt(B*(eBands[i+1]-eBands[i]));
-      theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+q);
+      theta = Q15ONE*.007*(B*(eBands[i+1]-eBands[i]))/(.1f+q);
 
       /* If pitch isn't available, use intra-frame prediction */
       if (eBands[i] >= m->pitchEnd || q<=0)
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -41,7 +41,7 @@
 /** Applies a series of rotations so that pulses are spread like a two-sided
 exponential. The effect of this is to reduce the tonal noise created by the
 sparse spectrum resulting from the pulse codebook */
-void exp_rotation(celt_norm_t *X, int len, float theta, int dir, int stride, int iter);
+void exp_rotation(celt_norm_t *X, int len, celt_word16_t theta, int dir, int stride, int iter);
 
 /** Compute the amplitude (sqrt energy) in each of the bands 
  * @param m Mode data 
--- a/tests/rotation-test.c
+++ b/tests/rotation-test.c
@@ -14,7 +14,7 @@
 {
    int i;
    double err = 0, ener = 0, snr;
-   float theta = .007*N/K;
+   celt_word16_t theta = Q15_ONE*.007*N/K;
    celt_word16_t x0[MAX_SIZE];
    celt_word16_t x1[MAX_SIZE];
    for (i=0;i<N;i++)