git-svn-id: http://webrtc.googlecode.com/svn/trunk@4 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
165
modules/audio_coding/codecs/iSAC/main/source/transform.c
Normal file
165
modules/audio_coding/codecs/iSAC/main/source/transform.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
#include "fft.h"
|
||||
#include "codec.h"
|
||||
#include <math.h>
|
||||
|
||||
static double costab1[FRAMESAMPLES_HALF];
|
||||
static double sintab1[FRAMESAMPLES_HALF];
|
||||
static double costab2[FRAMESAMPLES_QUARTER];
|
||||
static double sintab2[FRAMESAMPLES_QUARTER];
|
||||
|
||||
#if defined(WEBRTC_LINUX)
|
||||
extern long int lrint(double x); /* Note! This declaration is missing in math.h, that is why it is declared as extern*/
|
||||
#define WebRtcIsac_lrint lrint
|
||||
#elif defined(WEBRTC_MAC)
|
||||
extern long int lrint(double x); /* Note! This declaration is missing in math.h, that is why it is declared as extern*/
|
||||
#define WebRtcIsac_lrint lrint
|
||||
#elif defined(X64)
|
||||
static __inline WebRtc_Word32 WebRtcIsac_lrint(double flt) {
|
||||
WebRtc_Word32 intgr;
|
||||
intgr = (WebRtc_Word32)floor(flt+.499999999999);
|
||||
return intgr ;
|
||||
}
|
||||
#elif defined(WEBRTC_TARGET_PC)
|
||||
|
||||
static __inline WebRtc_Word32 WebRtcIsac_lrint(double flt) {
|
||||
|
||||
WebRtc_Word32 intgr;
|
||||
|
||||
_asm
|
||||
{
|
||||
fld flt
|
||||
fistp intgr
|
||||
} ;
|
||||
|
||||
return intgr ;
|
||||
}
|
||||
#else// Do a slow but correct implementation of lrint
|
||||
|
||||
static __inline WebRtc_Word32 WebRtcIsac_lrint(double flt) {
|
||||
WebRtc_Word32 intgr;
|
||||
intgr = (WebRtc_Word32)floor(flt+.499999999999);
|
||||
return intgr ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebRtcIsac_InitTransform()
|
||||
{
|
||||
int k;
|
||||
double fact, phase;
|
||||
|
||||
fact = PI / (FRAMESAMPLES_HALF);
|
||||
phase = 0.0;
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
costab1[k] = cos(phase);
|
||||
sintab1[k] = sin(phase);
|
||||
phase += fact;
|
||||
}
|
||||
|
||||
fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF);
|
||||
phase = 0.5 * fact;
|
||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||
costab2[k] = cos(phase);
|
||||
sintab2[k] = sin(phase);
|
||||
phase += fact;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_Time2Spec(double *inre1,
|
||||
double *inre2,
|
||||
WebRtc_Word16 *outreQ7,
|
||||
WebRtc_Word16 *outimQ7,
|
||||
FFTstr *fftstr_obj)
|
||||
{
|
||||
|
||||
int k;
|
||||
int dims[1];
|
||||
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
||||
double tmpre[FRAMESAMPLES_HALF], tmpim[FRAMESAMPLES_HALF];
|
||||
|
||||
|
||||
dims[0] = FRAMESAMPLES_HALF;
|
||||
|
||||
|
||||
/* Multiply with complex exponentials and combine into one complex vector */
|
||||
fact = 0.5 / sqrt(FRAMESAMPLES_HALF);
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
tmp1r = costab1[k];
|
||||
tmp1i = sintab1[k];
|
||||
tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact;
|
||||
tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact;
|
||||
}
|
||||
|
||||
|
||||
/* Get DFT */
|
||||
WebRtcIsac_Fftns(1, dims, tmpre, tmpim, -1, 1.0, fftstr_obj);
|
||||
|
||||
/* Use symmetry to separate into two complex vectors and center frames in time around zero */
|
||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||
xr = tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
|
||||
yi = -tmpre[k] + tmpre[FRAMESAMPLES_HALF - 1 - k];
|
||||
xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k];
|
||||
yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k];
|
||||
|
||||
tmp1r = costab2[k];
|
||||
tmp1i = sintab2[k];
|
||||
outreQ7[k] = (WebRtc_Word16)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
|
||||
outimQ7[k] = (WebRtc_Word16)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
|
||||
outreQ7[FRAMESAMPLES_HALF - 1 - k] = (WebRtc_Word16)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
|
||||
outimQ7[FRAMESAMPLES_HALF - 1 - k] = (WebRtc_Word16)WebRtcIsac_lrint((-yr * tmp1r + yi * tmp1i) * 128.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WebRtcIsac_Spec2time(double *inre, double *inim, double *outre1, double *outre2, FFTstr *fftstr_obj)
|
||||
{
|
||||
|
||||
int k;
|
||||
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
||||
|
||||
int dims;
|
||||
|
||||
dims = FRAMESAMPLES_HALF;
|
||||
|
||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||
/* Move zero in time to beginning of frames */
|
||||
tmp1r = costab2[k];
|
||||
tmp1i = sintab2[k];
|
||||
xr = inre[k] * tmp1r + inim[k] * tmp1i;
|
||||
xi = inim[k] * tmp1r - inre[k] * tmp1i;
|
||||
yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
|
||||
yi = -inre[FRAMESAMPLES_HALF - 1 - k] * tmp1r + inim[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
|
||||
|
||||
/* Combine into one vector, z = x + j * y */
|
||||
outre1[k] = xr - yi;
|
||||
outre1[FRAMESAMPLES_HALF - 1 - k] = xr + yi;
|
||||
outre2[k] = xi + yr;
|
||||
outre2[FRAMESAMPLES_HALF - 1 - k] = -xi + yr;
|
||||
}
|
||||
|
||||
|
||||
/* Get IDFT */
|
||||
WebRtcIsac_Fftns(1, &dims, outre1, outre2, 1, FRAMESAMPLES_HALF, fftstr_obj);
|
||||
|
||||
|
||||
/* Demodulate and separate */
|
||||
fact = sqrt(FRAMESAMPLES_HALF);
|
||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||
tmp1r = costab1[k];
|
||||
tmp1i = sintab1[k];
|
||||
xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact;
|
||||
outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact;
|
||||
outre1[k] = xr;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user