Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "settings.h"
     12 #include "fft.h"
     13 #include "codec.h"
     14 #include "os_specific_inline.h"
     15 #include <math.h>
     16 
     17 void WebRtcIsac_InitTransform(TransformTables* tables) {
     18   int k;
     19   double fact, phase;
     20 
     21   fact = PI / (FRAMESAMPLES_HALF);
     22   phase = 0.0;
     23   for (k = 0; k < FRAMESAMPLES_HALF; k++) {
     24     tables->costab1[k] = cos(phase);
     25     tables->sintab1[k] = sin(phase);
     26     phase += fact;
     27   }
     28 
     29   fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF);
     30   phase = 0.5 * fact;
     31   for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
     32     tables->costab2[k] = cos(phase);
     33     tables->sintab2[k] = sin(phase);
     34     phase += fact;
     35   }
     36 }
     37 
     38 void WebRtcIsac_Time2Spec(const TransformTables* tables,
     39                           double* inre1,
     40                           double* inre2,
     41                           int16_t* outreQ7,
     42                           int16_t* outimQ7,
     43                           FFTstr* fftstr_obj) {
     44   int k;
     45   int dims[1];
     46   double tmp1r, tmp1i, xr, xi, yr, yi, fact;
     47   double tmpre[FRAMESAMPLES_HALF], tmpim[FRAMESAMPLES_HALF];
     48 
     49 
     50   dims[0] = FRAMESAMPLES_HALF;
     51 
     52 
     53   /* Multiply with complex exponentials and combine into one complex vector */
     54   fact = 0.5 / sqrt(FRAMESAMPLES_HALF);
     55   for (k = 0; k < FRAMESAMPLES_HALF; k++) {
     56     tmp1r = tables->costab1[k];
     57     tmp1i = tables->sintab1[k];
     58     tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact;
     59     tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact;
     60   }
     61 
     62 
     63   /* Get DFT */
     64   WebRtcIsac_Fftns(1, dims, tmpre, tmpim, -1, 1.0, fftstr_obj);
     65 
     66   /* Use symmetry to separate into two complex vectors and center frames in time around zero */
     67   for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
     68     xr = tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
     69     yi = -tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
     70     xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k];
     71     yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k];
     72 
     73     tmp1r = tables->costab2[k];
     74     tmp1i = tables->sintab2[k];
     75     outreQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
     76     outimQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
     77     outreQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
     78     outimQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1r + yi * tmp1i) * 128.0);
     79   }
     80 }
     81 
     82 void WebRtcIsac_Spec2time(const TransformTables* tables,
     83                           double* inre,
     84                           double* inim,
     85                           double* outre1,
     86                           double* outre2,
     87                           FFTstr* fftstr_obj) {
     88   int k;
     89   double tmp1r, tmp1i, xr, xi, yr, yi, fact;
     90 
     91   int dims;
     92 
     93   dims = FRAMESAMPLES_HALF;
     94 
     95   for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
     96     /* Move zero in time to beginning of frames */
     97     tmp1r = tables->costab2[k];
     98     tmp1i = tables->sintab2[k];
     99     xr = inre[k] * tmp1r + inim[k] * tmp1i;
    100     xi = inim[k] * tmp1r - inre[k] * tmp1i;
    101     yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
    102     yi = -inre[FRAMESAMPLES_HALF - 1 - k] * tmp1r + inim[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
    103 
    104     /* Combine into one vector,  z = x + j * y */
    105     outre1[k] = xr - yi;
    106     outre1[FRAMESAMPLES_HALF - 1 - k] = xr + yi;
    107     outre2[k] = xi + yr;
    108     outre2[FRAMESAMPLES_HALF - 1 - k] = -xi + yr;
    109   }
    110 
    111 
    112   /* Get IDFT */
    113   WebRtcIsac_Fftns(1, &dims, outre1, outre2, 1, FRAMESAMPLES_HALF, fftstr_obj);
    114 
    115 
    116   /* Demodulate and separate */
    117   fact = sqrt(FRAMESAMPLES_HALF);
    118   for (k = 0; k < FRAMESAMPLES_HALF; k++) {
    119     tmp1r = tables->costab1[k];
    120     tmp1i = tables->sintab1[k];
    121     xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact;
    122     outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact;
    123     outre1[k] = xr;
    124   }
    125 }
    126