Support for Signal calls.

Merge in RedPhone

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-09-09 13:54:29 -07:00
parent 3d4ae60d81
commit d83a3d71bc
2585 changed files with 803492 additions and 45 deletions

View File

@@ -0,0 +1,5 @@
# These are for the common case of adding or renaming files. If you're doing
# structural changes, please get a review from a reviewer in this file.
per-file *.gyp=*
per-file *.gypi=*

View File

@@ -0,0 +1,60 @@
/*
* 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 "arith_routines.h"
#include "settings.h"
/*
* terminate and return byte stream;
* returns the number of bytes in the stream
*/
int WebRtcIsac_EncTerminate(Bitstr *streamdata) /* in-/output struct containing bitstream */
{
uint8_t *stream_ptr;
/* point to the right place in the stream buffer */
stream_ptr = streamdata->stream + streamdata->stream_index;
/* find minimum length (determined by current interval width) */
if ( streamdata->W_upper > 0x01FFFFFF )
{
streamdata->streamval += 0x01000000;
/* add carry to buffer */
if (streamdata->streamval < 0x01000000)
{
/* propagate carry */
while ( !(++(*--stream_ptr)) );
/* put pointer back to the old value */
stream_ptr = streamdata->stream + streamdata->stream_index;
}
/* write remaining data to bitstream */
*stream_ptr++ = (uint8_t) (streamdata->streamval >> 24);
}
else
{
streamdata->streamval += 0x00010000;
/* add carry to buffer */
if (streamdata->streamval < 0x00010000)
{
/* propagate carry */
while ( !(++(*--stream_ptr)) );
/* put pointer back to the old value */
stream_ptr = streamdata->stream + streamdata->stream_index;
}
/* write remaining data to bitstream */
*stream_ptr++ = (uint8_t) (streamdata->streamval >> 24);
*stream_ptr++ = (uint8_t) ((streamdata->streamval >> 16) & 0x00FF);
}
/* calculate stream length */
return (int)(stream_ptr - streamdata->stream);
}

View File

@@ -0,0 +1,63 @@
/*
* 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.
*/
/*
* arith_routines.h
*
* Functions for arithmetic coding.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_
#include "structs.h"
int WebRtcIsac_EncLogisticMulti2(
Bitstr *streamdata, /* in-/output struct containing bitstream */
int16_t *dataQ7, /* input: data vector */
const uint16_t *env, /* input: side info vector defining the width of the pdf */
const int N, /* input: data vector length */
const int16_t isSWB12kHz); /* if the codec is working in 12kHz bandwidth */
/* returns the number of bytes in the stream */
int WebRtcIsac_EncTerminate(Bitstr *streamdata); /* in-/output struct containing bitstream */
/* returns the number of bytes in the stream so far */
int WebRtcIsac_DecLogisticMulti2(
int16_t *data, /* output: data vector */
Bitstr *streamdata, /* in-/output struct containing bitstream */
const uint16_t *env, /* input: side info vector defining the width of the pdf */
const int16_t *dither, /* input: dither vector */
const int N, /* input: data vector length */
const int16_t isSWB12kHz); /* if the codec is working in 12kHz bandwidth */
void WebRtcIsac_EncHistMulti(
Bitstr *streamdata, /* in-/output struct containing bitstream */
const int *data, /* input: data vector */
const uint16_t **cdf, /* input: array of cdf arrays */
const int N); /* input: data vector length */
int WebRtcIsac_DecHistBisectMulti(
int *data, /* output: data vector */
Bitstr *streamdata, /* in-/output struct containing bitstream */
const uint16_t **cdf, /* input: array of cdf arrays */
const uint16_t *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */
const int N); /* input: data vector length */
int WebRtcIsac_DecHistOneStepMulti(
int *data, /* output: data vector */
Bitstr *streamdata, /* in-/output struct containing bitstream */
const uint16_t **cdf, /* input: array of cdf arrays */
const uint16_t *init_index,/* input: vector of initial cdf table search entries */
const int N); /* input: data vector length */
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ARITH_ROUTINES_H_ */

View File

@@ -0,0 +1,291 @@
/*
* 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 "arith_routines.h"
/*
* code symbols into arithmetic bytestream
*/
void WebRtcIsac_EncHistMulti(Bitstr *streamdata, /* in-/output struct containing bitstream */
const int *data, /* input: data vector */
const uint16_t **cdf, /* input: array of cdf arrays */
const int N) /* input: data vector length */
{
uint32_t W_lower, W_upper;
uint32_t W_upper_LSB, W_upper_MSB;
uint8_t *stream_ptr;
uint8_t *stream_ptr_carry;
uint32_t cdf_lo, cdf_hi;
int k;
/* point to beginning of stream buffer */
stream_ptr = streamdata->stream + streamdata->stream_index;
W_upper = streamdata->W_upper;
for (k=N; k>0; k--)
{
/* fetch cdf_lower and cdf_upper from cdf tables */
cdf_lo = (uint32_t) *(*cdf + *data);
cdf_hi = (uint32_t) *(*cdf++ + *data++ + 1);
/* update interval */
W_upper_LSB = W_upper & 0x0000FFFF;
W_upper_MSB = W_upper >> 16;
W_lower = W_upper_MSB * cdf_lo;
W_lower += (W_upper_LSB * cdf_lo) >> 16;
W_upper = W_upper_MSB * cdf_hi;
W_upper += (W_upper_LSB * cdf_hi) >> 16;
/* shift interval such that it begins at zero */
W_upper -= ++W_lower;
/* add integer to bitstream */
streamdata->streamval += W_lower;
/* handle carry */
if (streamdata->streamval < W_lower)
{
/* propagate carry */
stream_ptr_carry = stream_ptr;
while (!(++(*--stream_ptr_carry)));
}
/* renormalize interval, store most significant byte of streamval and update streamval */
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
{
W_upper <<= 8;
*stream_ptr++ = (uint8_t) (streamdata->streamval >> 24);
streamdata->streamval <<= 8;
}
}
/* calculate new stream_index */
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
streamdata->W_upper = W_upper;
return;
}
/*
* function to decode more symbols from the arithmetic bytestream, using method of bisection
* cdf tables should be of size 2^k-1 (which corresponds to an alphabet size of 2^k-2)
*/
int WebRtcIsac_DecHistBisectMulti(int *data, /* output: data vector */
Bitstr *streamdata, /* in-/output struct containing bitstream */
const uint16_t **cdf, /* input: array of cdf arrays */
const uint16_t *cdf_size, /* input: array of cdf table sizes+1 (power of two: 2^k) */
const int N) /* input: data vector length */
{
uint32_t W_lower, W_upper;
uint32_t W_tmp;
uint32_t W_upper_LSB, W_upper_MSB;
uint32_t streamval;
const uint8_t *stream_ptr;
const uint16_t *cdf_ptr;
int size_tmp;
int k;
W_lower = 0; //to remove warning -DH
stream_ptr = streamdata->stream + streamdata->stream_index;
W_upper = streamdata->W_upper;
if (W_upper == 0)
/* Should not be possible in normal operation */
return -2;
if (streamdata->stream_index == 0) /* first time decoder is called for this stream */
{
/* read first word from bytestream */
streamval = *stream_ptr << 24;
streamval |= *++stream_ptr << 16;
streamval |= *++stream_ptr << 8;
streamval |= *++stream_ptr;
} else {
streamval = streamdata->streamval;
}
for (k=N; k>0; k--)
{
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
W_upper_LSB = W_upper & 0x0000FFFF;
W_upper_MSB = W_upper >> 16;
/* start halfway the cdf range */
size_tmp = *cdf_size++ >> 1;
cdf_ptr = *cdf + (size_tmp - 1);
/* method of bisection */
for ( ;; )
{
W_tmp = W_upper_MSB * *cdf_ptr;
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
size_tmp >>= 1;
if (size_tmp == 0) break;
if (streamval > W_tmp)
{
W_lower = W_tmp;
cdf_ptr += size_tmp;
} else {
W_upper = W_tmp;
cdf_ptr -= size_tmp;
}
}
if (streamval > W_tmp)
{
W_lower = W_tmp;
*data++ = (int)(cdf_ptr - *cdf++);
} else {
W_upper = W_tmp;
*data++ = (int)(cdf_ptr - *cdf++ - 1);
}
/* shift interval to start at zero */
W_upper -= ++W_lower;
/* add integer to bitstream */
streamval -= W_lower;
/* renormalize interval and update streamval */
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
{
/* read next byte from stream */
streamval = (streamval << 8) | *++stream_ptr;
W_upper <<= 8;
}
if (W_upper == 0)
/* Should not be possible in normal operation */
return -2;
}
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
streamdata->W_upper = W_upper;
streamdata->streamval = streamval;
/* find number of bytes in original stream (determined by current interval width) */
if ( W_upper > 0x01FFFFFF )
return streamdata->stream_index - 2;
else
return streamdata->stream_index - 1;
}
/*
* function to decode more symbols from the arithmetic bytestream, taking single step up or
* down at a time
* cdf tables can be of arbitrary size, but large tables may take a lot of iterations
*/
int WebRtcIsac_DecHistOneStepMulti(int *data, /* output: data vector */
Bitstr *streamdata, /* in-/output struct containing bitstream */
const uint16_t **cdf, /* input: array of cdf arrays */
const uint16_t *init_index, /* input: vector of initial cdf table search entries */
const int N) /* input: data vector length */
{
uint32_t W_lower, W_upper;
uint32_t W_tmp;
uint32_t W_upper_LSB, W_upper_MSB;
uint32_t streamval;
const uint8_t *stream_ptr;
const uint16_t *cdf_ptr;
int k;
stream_ptr = streamdata->stream + streamdata->stream_index;
W_upper = streamdata->W_upper;
if (W_upper == 0)
/* Should not be possible in normal operation */
return -2;
if (streamdata->stream_index == 0) /* first time decoder is called for this stream */
{
/* read first word from bytestream */
streamval = *stream_ptr << 24;
streamval |= *++stream_ptr << 16;
streamval |= *++stream_ptr << 8;
streamval |= *++stream_ptr;
} else {
streamval = streamdata->streamval;
}
for (k=N; k>0; k--)
{
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
W_upper_LSB = W_upper & 0x0000FFFF;
W_upper_MSB = W_upper >> 16;
/* start at the specified table entry */
cdf_ptr = *cdf + (*init_index++);
W_tmp = W_upper_MSB * *cdf_ptr;
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
if (streamval > W_tmp)
{
for ( ;; )
{
W_lower = W_tmp;
if (cdf_ptr[0]==65535)
/* range check */
return -3;
W_tmp = W_upper_MSB * *++cdf_ptr;
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
if (streamval <= W_tmp) break;
}
W_upper = W_tmp;
*data++ = (int)(cdf_ptr - *cdf++ - 1);
} else {
for ( ;; )
{
W_upper = W_tmp;
--cdf_ptr;
if (cdf_ptr<*cdf) {
/* range check */
return -3;
}
W_tmp = W_upper_MSB * *cdf_ptr;
W_tmp += (W_upper_LSB * *cdf_ptr) >> 16;
if (streamval > W_tmp) break;
}
W_lower = W_tmp;
*data++ = (int)(cdf_ptr - *cdf++);
}
/* shift interval to start at zero */
W_upper -= ++W_lower;
/* add integer to bitstream */
streamval -= W_lower;
/* renormalize interval and update streamval */
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
{
/* read next byte from stream */
streamval = (streamval << 8) | *++stream_ptr;
W_upper <<= 8;
}
}
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
streamdata->W_upper = W_upper;
streamdata->streamval = streamval;
/* find number of bytes in original stream (determined by current interval width) */
if ( W_upper > 0x01FFFFFF )
return streamdata->stream_index - 2;
else
return streamdata->stream_index - 1;
}

View File

@@ -0,0 +1,294 @@
/*
* 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.
*/
/*
* arith_routines.h
*
* This file contains functions for arithmatically encoding and
* decoding DFT coefficients.
*
*/
#include "arith_routines.h"
static const int32_t kHistEdgesQ15[51] = {
-327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716,
-196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858, -91751, -78644,
-65536, -52429, -39322, -26215, -13108, 0, 13107, 26214, 39321, 52428,
65536, 78643, 91750, 104857, 117964, 131072, 144179, 157286, 170393, 183500,
196608, 209715, 222822, 235929, 249036, 262144, 275251, 288358, 301465, 314572,
327680};
static const int kCdfSlopeQ0[51] = { /* Q0 */
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 13, 23, 47, 87, 154, 315, 700, 1088,
2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312,
1095, 660, 316, 145, 86, 41, 32, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 0};
static const int kCdfQ16[51] = { /* Q16 */
0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
20, 22, 24, 29, 38, 57, 92, 153, 279, 559,
994, 1983, 4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636,
64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514,
65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534,
65535};
/* function to be converted to fixed point */
static __inline uint32_t piecewise(int32_t xinQ15) {
int32_t ind, qtmp1, qtmp2, qtmp3;
uint32_t tmpUW32;
qtmp2 = xinQ15;
if (qtmp2 < kHistEdgesQ15[0]) {
qtmp2 = kHistEdgesQ15[0];
}
if (qtmp2 > kHistEdgesQ15[50]) {
qtmp2 = kHistEdgesQ15[50];
}
qtmp1 = qtmp2 - kHistEdgesQ15[0]; /* Q15 - Q15 = Q15 */
ind = (qtmp1 * 5) >> 16; /* 2^16 / 5 = 0.4 in Q15 */
/* Q15 -> Q0 */
qtmp1 = qtmp2 - kHistEdgesQ15[ind]; /* Q15 - Q15 = Q15 */
qtmp2 = kCdfSlopeQ0[ind] * qtmp1; /* Q0 * Q15 = Q15 */
qtmp3 = qtmp2>>15; /* Q15 -> Q0 */
tmpUW32 = kCdfQ16[ind] + qtmp3; /* Q0 + Q0 = Q0 */
return tmpUW32;
}
int WebRtcIsac_EncLogisticMulti2(
Bitstr *streamdata, /* in-/output struct containing bitstream */
int16_t *dataQ7, /* input: data vector */
const uint16_t *envQ8, /* input: side info vector defining the width of the pdf */
const int N, /* input: data vector length / 2 */
const int16_t isSWB12kHz)
{
uint32_t W_lower, W_upper;
uint32_t W_upper_LSB, W_upper_MSB;
uint8_t *stream_ptr;
uint8_t *maxStreamPtr;
uint8_t *stream_ptr_carry;
uint32_t cdf_lo, cdf_hi;
int k;
/* point to beginning of stream buffer */
stream_ptr = streamdata->stream + streamdata->stream_index;
W_upper = streamdata->W_upper;
maxStreamPtr = streamdata->stream + STREAM_SIZE_MAX_60 - 1;
for (k = 0; k < N; k++)
{
/* compute cdf_lower and cdf_upper by evaluating the piecewise linear cdf */
cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
/* test and clip if probability gets too small */
while (cdf_lo+1 >= cdf_hi) {
/* clip */
if (*dataQ7 > 0) {
*dataQ7 -= 128;
cdf_hi = cdf_lo;
cdf_lo = piecewise((*dataQ7 - 64) * *envQ8);
} else {
*dataQ7 += 128;
cdf_lo = cdf_hi;
cdf_hi = piecewise((*dataQ7 + 64) * *envQ8);
}
}
dataQ7++;
// increment only once per 4 iterations for SWB-16kHz or WB
// increment only once per 2 iterations for SWB-12kHz
envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
/* update interval */
W_upper_LSB = W_upper & 0x0000FFFF;
W_upper_MSB = W_upper >> 16;
W_lower = W_upper_MSB * cdf_lo;
W_lower += (W_upper_LSB * cdf_lo) >> 16;
W_upper = W_upper_MSB * cdf_hi;
W_upper += (W_upper_LSB * cdf_hi) >> 16;
/* shift interval such that it begins at zero */
W_upper -= ++W_lower;
/* add integer to bitstream */
streamdata->streamval += W_lower;
/* handle carry */
if (streamdata->streamval < W_lower)
{
/* propagate carry */
stream_ptr_carry = stream_ptr;
while (!(++(*--stream_ptr_carry)));
}
/* renormalize interval, store most significant byte of streamval and update streamval */
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
{
W_upper <<= 8;
*stream_ptr++ = (uint8_t) (streamdata->streamval >> 24);
if(stream_ptr > maxStreamPtr)
{
return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
}
streamdata->streamval <<= 8;
}
}
/* calculate new stream_index */
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
streamdata->W_upper = W_upper;
return 0;
}
int WebRtcIsac_DecLogisticMulti2(
int16_t *dataQ7, /* output: data vector */
Bitstr *streamdata, /* in-/output struct containing bitstream */
const uint16_t *envQ8, /* input: side info vector defining the width of the pdf */
const int16_t *ditherQ7,/* input: dither vector */
const int N, /* input: data vector length */
const int16_t isSWB12kHz)
{
uint32_t W_lower, W_upper;
uint32_t W_tmp;
uint32_t W_upper_LSB, W_upper_MSB;
uint32_t streamval;
const uint8_t *stream_ptr;
uint32_t cdf_tmp;
int16_t candQ7;
int k;
stream_ptr = streamdata->stream + streamdata->stream_index;
W_upper = streamdata->W_upper;
if (streamdata->stream_index == 0) /* first time decoder is called for this stream */
{
/* read first word from bytestream */
streamval = *stream_ptr << 24;
streamval |= *++stream_ptr << 16;
streamval |= *++stream_ptr << 8;
streamval |= *++stream_ptr;
} else {
streamval = streamdata->streamval;
}
for (k = 0; k < N; k++)
{
/* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
W_upper_LSB = W_upper & 0x0000FFFF;
W_upper_MSB = W_upper >> 16;
/* find first candidate by inverting the logistic cdf */
candQ7 = - *ditherQ7 + 64;
cdf_tmp = piecewise(candQ7 * *envQ8);
W_tmp = W_upper_MSB * cdf_tmp;
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
if (streamval > W_tmp)
{
W_lower = W_tmp;
candQ7 += 128;
cdf_tmp = piecewise(candQ7 * *envQ8);
W_tmp = W_upper_MSB * cdf_tmp;
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
while (streamval > W_tmp)
{
W_lower = W_tmp;
candQ7 += 128;
cdf_tmp = piecewise(candQ7 * *envQ8);
W_tmp = W_upper_MSB * cdf_tmp;
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
/* error check */
if (W_lower == W_tmp) return -1;
}
W_upper = W_tmp;
/* another sample decoded */
*dataQ7 = candQ7 - 64;
}
else
{
W_upper = W_tmp;
candQ7 -= 128;
cdf_tmp = piecewise(candQ7 * *envQ8);
W_tmp = W_upper_MSB * cdf_tmp;
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
while ( !(streamval > W_tmp) )
{
W_upper = W_tmp;
candQ7 -= 128;
cdf_tmp = piecewise(candQ7 * *envQ8);
W_tmp = W_upper_MSB * cdf_tmp;
W_tmp += (W_upper_LSB * cdf_tmp) >> 16;
/* error check */
if (W_upper == W_tmp) return -1;
}
W_lower = W_tmp;
/* another sample decoded */
*dataQ7 = candQ7 + 64;
}
ditherQ7++;
dataQ7++;
// increment only once per 4 iterations for SWB-16kHz or WB
// increment only once per 2 iterations for SWB-12kHz
envQ8 += (isSWB12kHz)? (k & 1):((k & 1) & (k >> 1));
/* shift interval to start at zero */
W_upper -= ++W_lower;
/* add integer to bitstream */
streamval -= W_lower;
/* renormalize interval and update streamval */
while ( !(W_upper & 0xFF000000) ) /* W_upper < 2^24 */
{
/* read next byte from stream */
streamval = (streamval << 8) | *++stream_ptr;
W_upper <<= 8;
}
}
streamdata->stream_index = (int)(stream_ptr - streamdata->stream);
streamdata->W_upper = W_upper;
streamdata->streamval = streamval;
/* find number of bytes in original stream (determined by current interval width) */
if ( W_upper > 0x01FFFFFF )
return streamdata->stream_index - 2;
else
return streamdata->stream_index - 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
/*
* 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.
*/
/*
* bandwidth_estimator.h
*
* This header file contains the API for the Bandwidth Estimator
* designed for iSAC.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_
#include "structs.h"
#include "settings.h"
#define MIN_ISAC_BW 10000
#define MIN_ISAC_BW_LB 10000
#define MIN_ISAC_BW_UB 25000
#define MAX_ISAC_BW 56000
#define MAX_ISAC_BW_UB 32000
#define MAX_ISAC_BW_LB 32000
#define MIN_ISAC_MD 5
#define MAX_ISAC_MD 25
// assumed header size, in bytes; we don't know the exact number
// (header compression may be used)
#define HEADER_SIZE 35
// Initial Frame-Size, in ms, for Wideband & Super-Wideband Mode
#define INIT_FRAME_LEN_WB 60
#define INIT_FRAME_LEN_SWB 30
// Initial Bottleneck Estimate, in bits/sec, for
// Wideband & Super-wideband mode
#define INIT_BN_EST_WB 20e3f
#define INIT_BN_EST_SWB 56e3f
// Initial Header rate (header rate depends on frame-size),
// in bits/sec, for Wideband & Super-Wideband mode.
#define INIT_HDR_RATE_WB \
((float)HEADER_SIZE * 8.0f * 1000.0f / (float)INIT_FRAME_LEN_WB)
#define INIT_HDR_RATE_SWB \
((float)HEADER_SIZE * 8.0f * 1000.0f / (float)INIT_FRAME_LEN_SWB)
// number of packets in a row for a high rate burst
#define BURST_LEN 3
// ms, max time between two full bursts
#define BURST_INTERVAL 500
// number of packets in a row for initial high rate burst
#define INIT_BURST_LEN 5
// bits/s, rate for the first BURST_LEN packets
#define INIT_RATE_WB INIT_BN_EST_WB
#define INIT_RATE_SWB INIT_BN_EST_SWB
#if defined(__cplusplus)
extern "C" {
#endif
/* This function initializes the struct */
/* to be called before using the struct for anything else */
/* returns 0 if everything went fine, -1 otherwise */
int32_t WebRtcIsac_InitBandwidthEstimator(
BwEstimatorstr* bwest_str,
enum IsacSamplingRate encoderSampRate,
enum IsacSamplingRate decoderSampRate);
/* This function updates the receiving estimate */
/* Parameters: */
/* rtp_number - value from RTP packet, from NetEq */
/* frame length - length of signal frame in ms, from iSAC decoder */
/* send_ts - value in RTP header giving send time in samples */
/* arr_ts - value given by timeGetTime() time of arrival in samples of packet from NetEq */
/* pksize - size of packet in bytes, from NetEq */
/* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
/* returns 0 if everything went fine, -1 otherwise */
int16_t WebRtcIsac_UpdateBandwidthEstimator(
BwEstimatorstr* bwest_str,
const uint16_t rtp_number,
const int32_t frame_length,
const uint32_t send_ts,
const uint32_t arr_ts,
const int32_t pksize);
/* Update receiving estimates. Used when we only receive BWE index, no iSAC data packet. */
int16_t WebRtcIsac_UpdateUplinkBwImpl(
BwEstimatorstr* bwest_str,
int16_t Index,
enum IsacSamplingRate encoderSamplingFreq);
/* Returns the bandwidth/jitter estimation code (integer 0...23) to put in the sending iSAC payload */
uint16_t WebRtcIsac_GetDownlinkBwJitIndexImpl(
BwEstimatorstr* bwest_str,
int16_t* bottleneckIndex,
int16_t* jitterInfo,
enum IsacSamplingRate decoderSamplingFreq);
/* Returns the bandwidth estimation (in bps) */
int32_t WebRtcIsac_GetDownlinkBandwidth(
const BwEstimatorstr *bwest_str);
/* Returns the max delay (in ms) */
int32_t WebRtcIsac_GetDownlinkMaxDelay(
const BwEstimatorstr *bwest_str);
/* Returns the bandwidth that iSAC should send with in bps */
void WebRtcIsac_GetUplinkBandwidth(
const BwEstimatorstr* bwest_str,
int32_t* bitRate);
/* Returns the max delay value from the other side in ms */
int32_t WebRtcIsac_GetUplinkMaxDelay(
const BwEstimatorstr *bwest_str);
/*
* update amount of data in bottle neck buffer and burst handling
* returns minimum payload size (bytes)
*/
int WebRtcIsac_GetMinBytes(
RateModel* State,
int StreamSize, /* bytes in bitstream */
const int FrameLen, /* ms per frame */
const double BottleNeck, /* bottle neck rate; excl headers (bps) */
const double DelayBuildUp, /* max delay from bottleneck buffering (ms) */
enum ISACBandwidth bandwidth
/*,int16_t frequentLargePackets*/);
/*
* update long-term average bitrate and amount of data in buffer
*/
void WebRtcIsac_UpdateRateModel(
RateModel* State,
int StreamSize, /* bytes in bitstream */
const int FrameSamples, /* samples per frame */
const double BottleNeck); /* bottle neck rate; excl headers (bps) */
void WebRtcIsac_InitRateModel(
RateModel *State);
/* Returns the new framelength value (input argument: bottle_neck) */
int WebRtcIsac_GetNewFrameLength(
double bottle_neck,
int current_framelength);
/* Returns the new SNR value (input argument: bottle_neck) */
double WebRtcIsac_GetSnr(
double bottle_neck,
int new_framelength);
int16_t WebRtcIsac_UpdateUplinkJitter(
BwEstimatorstr* bwest_str,
int32_t index);
#if defined(__cplusplus)
}
#endif
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_BANDWIDTH_ESTIMATOR_H_ */

View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2012 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.
*/
/*
* codec.h
*
* This header file contains the calls to the internal encoder
* and decoder functions.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_
#include "structs.h"
void WebRtcIsac_ResetBitstream(Bitstr* bit_stream);
int WebRtcIsac_EstimateBandwidth(BwEstimatorstr* bwest_str, Bitstr* streamdata,
int32_t packet_size,
uint16_t rtp_seq_number,
uint32_t send_ts, uint32_t arr_ts,
enum IsacSamplingRate encoderSampRate,
enum IsacSamplingRate decoderSampRate);
int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdec_obj,
int16_t* current_framesamples,
int16_t isRCUPayload);
int WebRtcIsac_DecodeRcuLb(float* signal_out, ISACLBDecStruct* ISACdec_obj,
int16_t* current_framesamples);
int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj,
int16_t codingMode, int16_t
bottleneckIndex);
int WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t* ISACSavedEnc_obj,
Bitstr* ISACBitStr_obj, int BWnumber,
float scale);
int WebRtcIsac_EncodeStoredDataUb(
const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, Bitstr* bitStream,
int32_t jitterInfo, float scale, enum ISACBandwidth bandwidth);
int16_t WebRtcIsac_GetRedPayloadUb(
const ISACUBSaveEncDataStruct* ISACSavedEncObj, Bitstr* bitStreamObj,
enum ISACBandwidth bandwidth);
/******************************************************************************
* WebRtcIsac_RateAllocation()
* Internal function to perform a rate-allocation for upper and lower-band,
* given a total rate.
*
* Input:
* - inRateBitPerSec : a total bit-rate in bits/sec.
*
* Output:
* - rateLBBitPerSec : a bit-rate allocated to the lower-band
* in bits/sec.
* - rateUBBitPerSec : a bit-rate allocated to the upper-band
* in bits/sec.
*
* Return value : 0 if rate allocation has been successful.
* -1 if failed to allocate rates.
*/
int16_t WebRtcIsac_RateAllocation(int32_t inRateBitPerSec,
double* rateLBBitPerSec,
double* rateUBBitPerSec,
enum ISACBandwidth* bandwidthKHz);
/******************************************************************************
* WebRtcIsac_DecodeUb16()
*
* Decode the upper-band if the codec is in 0-16 kHz mode.
*
* Input/Output:
* -ISACdec_obj : pointer to the upper-band decoder object. The
* bit-stream is stored inside the decoder object.
*
* Output:
* -signal_out : decoded audio, 480 samples 30 ms.
*
* Return value : >0 number of decoded bytes.
* <0 if an error occurred.
*/
int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdec_obj,
int16_t isRCUPayload);
/******************************************************************************
* WebRtcIsac_DecodeUb12()
*
* Decode the upper-band if the codec is in 0-12 kHz mode.
*
* Input/Output:
* -ISACdec_obj : pointer to the upper-band decoder object. The
* bit-stream is stored inside the decoder object.
*
* Output:
* -signal_out : decoded audio, 480 samples 30 ms.
*
* Return value : >0 number of decoded bytes.
* <0 if an error occurred.
*/
int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdec_obj,
int16_t isRCUPayload);
/******************************************************************************
* WebRtcIsac_EncodeUb16()
*
* Encode the upper-band if the codec is in 0-16 kHz mode.
*
* Input:
* -in : upper-band audio, 160 samples (10 ms).
*
* Input/Output:
* -ISACdec_obj : pointer to the upper-band encoder object. The
* bit-stream is stored inside the encoder object.
*
* Return value : >0 number of encoded bytes.
* <0 if an error occurred.
*/
int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACenc_obj,
int32_t jitterInfo);
/******************************************************************************
* WebRtcIsac_EncodeUb12()
*
* Encode the upper-band if the codec is in 0-12 kHz mode.
*
* Input:
* -in : upper-band audio, 160 samples (10 ms).
*
* Input/Output:
* -ISACdec_obj : pointer to the upper-band encoder object. The
* bit-stream is stored inside the encoder object.
*
* Return value : >0 number of encoded bytes.
* <0 if an error occurred.
*/
int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACenc_obj,
int32_t jitterInfo);
/************************** initialization functions *************************/
void WebRtcIsac_InitMasking(MaskFiltstr* maskdata);
void WebRtcIsac_InitPreFilterbank(PreFiltBankstr* prefiltdata);
void WebRtcIsac_InitPostFilterbank(PostFiltBankstr* postfiltdata);
void WebRtcIsac_InitPitchFilter(PitchFiltstr* pitchfiltdata);
void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct* State);
/**************************** transform functions ****************************/
void WebRtcIsac_InitTransform();
void WebRtcIsac_Time2Spec(double* inre1, double* inre2, int16_t* outre,
int16_t* outim, FFTstr* fftstr_obj);
void WebRtcIsac_Spec2time(double* inre, double* inim, double* outre1,
double* outre2, FFTstr* fftstr_obj);
/******************************* filter functions ****************************/
void WebRtcIsac_AllPoleFilter(double* InOut, double* Coef, int lengthInOut,
int orderCoef);
void WebRtcIsac_AllZeroFilter(double* In, double* Coef, int lengthInOut,
int orderCoef, double* Out);
void WebRtcIsac_ZeroPoleFilter(double* In, double* ZeroCoef, double* PoleCoef,
int lengthInOut, int orderCoef, double* Out);
/***************************** filterbank functions **************************/
void WebRtcIsac_SplitAndFilterFloat(float* in, float* LP, float* HP,
double* LP_la, double* HP_la,
PreFiltBankstr* prefiltdata);
void WebRtcIsac_FilterAndCombineFloat(float* InLP, float* InHP, float* Out,
PostFiltBankstr* postfiltdata);
/************************* normalized lattice filters ************************/
void WebRtcIsac_NormLatticeFilterMa(int orderCoef, float* stateF, float* stateG,
float* lat_in, double* filtcoeflo,
double* lat_out);
void WebRtcIsac_NormLatticeFilterAr(int orderCoef, float* stateF, float* stateG,
double* lat_in, double* lo_filt_coef,
float* lat_out);
void WebRtcIsac_Dir2Lat(double* a, int orderCoef, float* sth, float* cth);
void WebRtcIsac_AutoCorr(double* r, const double* x, int N, int order);
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_ */

View File

@@ -0,0 +1,110 @@
/*
* 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 "crc.h"
#include <stdlib.h>
#include "signal_processing_library.h"
#define POLYNOMIAL 0x04c11db7L
static const uint32_t kCrcTable[256] = {
0, 0x4c11db7, 0x9823b6e, 0xd4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13, 0x54bf6a4,
0x808d07d, 0xcc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
0x3f9b762c, 0x3b5a6b9b, 0x315d626, 0x7d4cb91, 0xa97ed48, 0xe56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
0x18197087, 0x1cd86d30, 0x29f3d35, 0x65e2082, 0xb1d065b, 0xfdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
/****************************************************************************
* WebRtcIsac_GetCrc(...)
*
* This function returns a 32 bit CRC checksum of a bit stream
*
* Input:
* - bitstream : payload bitstream
* - len_bitstream_in_bytes : number of 8-bit words in the bit stream
*
* Output:
* - crc : checksum
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcIsac_GetCrc(const int16_t* bitstream,
int16_t len_bitstream_in_bytes,
uint32_t* crc)
{
uint8_t* bitstream_ptr_uw8;
uint32_t crc_state;
int byte_cntr;
int crc_tbl_indx;
/* Sanity Check. */
if (bitstream == NULL) {
return -1;
}
/* cast to UWord8 pointer */
bitstream_ptr_uw8 = (uint8_t *)bitstream;
/* initialize */
crc_state = 0xFFFFFFFF;
for (byte_cntr = 0; byte_cntr < len_bitstream_in_bytes; byte_cntr++) {
crc_tbl_indx = (WEBRTC_SPL_RSHIFT_U32(crc_state, 24) ^
bitstream_ptr_uw8[byte_cntr]) & 0xFF;
crc_state = WEBRTC_SPL_LSHIFT_U32(crc_state, 8) ^ kCrcTable[crc_tbl_indx];
}
*crc = ~crc_state;
return 0;
}

View File

@@ -0,0 +1,46 @@
/*
* 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.
*/
/*
* crc.h
*
* Checksum functions
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_
#include "typedefs.h"
/****************************************************************************
* WebRtcIsac_GetCrc(...)
*
* This function returns a 32 bit CRC checksum of a bit stream
*
* Input:
* - encoded : payload bit stream
* - no_of_word8s : number of 8-bit words in the bit stream
*
* Output:
* - crc : checksum
*
* Return value : 0 - Ok
* -1 - Error
*/
int16_t WebRtcIsac_GetCrc(
const int16_t* encoded,
int16_t no_of_word8s,
uint32_t* crc);
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_ */

View File

@@ -0,0 +1,299 @@
/*
* Copyright (c) 2012 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.
*/
/*
* decode_B.c
*
* This file contains definition of funtions for decoding.
* Decoding of lower-band, including normal-decoding and RCU decoding.
* Decoding of upper-band, including 8-12 kHz, when the bandwidth is
* 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
*
*/
#include "codec.h"
#include "entropy_coding.h"
#include "pitch_estimator.h"
#include "bandwidth_estimator.h"
#include "structs.h"
#include "settings.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* function to decode the bitstream
* returns the total number of bytes in the stream
*/
int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
int16_t* current_framesamples,
int16_t isRCUPayload) {
int k;
int len, err;
int16_t bandwidthInd;
float LP_dec_float[FRAMESAMPLES_HALF];
float HP_dec_float[FRAMESAMPLES_HALF];
double LPw[FRAMESAMPLES_HALF];
double HPw[FRAMESAMPLES_HALF];
double LPw_pf[FRAMESAMPLES_HALF];
double lo_filt_coef[(ORDERLO + 1)*SUBFRAMES];
double hi_filt_coef[(ORDERHI + 1)*SUBFRAMES];
double real_f[FRAMESAMPLES_HALF];
double imag_f[FRAMESAMPLES_HALF];
double PitchLags[4];
double PitchGains[4];
double AvgPitchGain;
int16_t PitchGains_Q12[4];
int16_t AvgPitchGain_Q12;
float gain;
int frame_nb; /* counter */
int frame_mode; /* 0 30ms, 1 for 60ms */
/* Processed_samples: 480 (30, 60 ms). Cannot take other values. */
WebRtcIsac_ResetBitstream(&(ISACdecLB_obj->bitstr_obj));
len = 0;
/* Decode framelength and BW estimation - not used,
only for stream pointer*/
err = WebRtcIsac_DecodeFrameLen(&ISACdecLB_obj->bitstr_obj,
current_framesamples);
if (err < 0) {
return err;
}
/* Frame_mode:
* 0: indicates 30 ms frame (480 samples)
* 1: indicates 60 ms frame (960 samples) */
frame_mode = *current_framesamples / MAX_FRAMESAMPLES;
err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd);
if (err < 0) {
return err;
}
/* One loop if it's one frame (20 or 30ms), 2 loops if 2 frames
bundled together (60ms). */
for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
/* Decode & de-quantize pitch parameters */
err = WebRtcIsac_DecodePitchGain(&ISACdecLB_obj->bitstr_obj,
PitchGains_Q12);
if (err < 0) {
return err;
}
err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, PitchGains_Q12,
PitchLags);
if (err < 0) {
return err;
}
AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
/* Decode & de-quantize filter coefficients. */
err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, lo_filt_coef,
hi_filt_coef);
if (err < 0) {
return err;
}
/* Decode & de-quantize spectrum. */
len = WebRtcIsac_DecodeSpec(&ISACdecLB_obj->bitstr_obj, AvgPitchGain_Q12,
kIsacLowerBand, real_f, imag_f);
if (len < 0) {
return len;
}
/* Inverse transform. */
WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw,
&ISACdecLB_obj->fftstr_obj);
/* Convert PitchGains back to float for pitchfilter_post */
for (k = 0; k < 4; k++) {
PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
}
if (isRCUPayload) {
for (k = 0; k < 240; k++) {
LPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
HPw[k] *= RCU_TRANSCODING_SCALE_INVERSE;
}
}
/* Inverse pitch filter. */
WebRtcIsac_PitchfilterPost(LPw, LPw_pf, &ISACdecLB_obj->pitchfiltstr_obj,
PitchLags, PitchGains);
/* Convert AvgPitchGain back to float for computation of gain. */
AvgPitchGain = ((float)AvgPitchGain_Q12) / 4096;
gain = 1.0f - 0.45f * (float)AvgPitchGain;
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
/* Reduce gain to compensate for pitch enhancer. */
LPw_pf[k] *= gain;
}
if (isRCUPayload) {
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
/* Compensation for transcoding gain changes. */
LPw_pf[k] *= RCU_TRANSCODING_SCALE;
HPw[k] *= RCU_TRANSCODING_SCALE;
}
}
/* Perceptual post-filtering (using normalized lattice filter). */
WebRtcIsac_NormLatticeFilterAr(
ORDERLO, ISACdecLB_obj->maskfiltstr_obj.PostStateLoF,
(ISACdecLB_obj->maskfiltstr_obj).PostStateLoG, LPw_pf, lo_filt_coef,
LP_dec_float);
WebRtcIsac_NormLatticeFilterAr(
ORDERHI, ISACdecLB_obj->maskfiltstr_obj.PostStateHiF,
(ISACdecLB_obj->maskfiltstr_obj).PostStateHiG, HPw, hi_filt_coef,
HP_dec_float);
/* Recombine the 2 bands. */
WebRtcIsac_FilterAndCombineFloat(LP_dec_float, HP_dec_float,
signal_out + frame_nb * FRAMESAMPLES,
&ISACdecLB_obj->postfiltbankstr_obj);
}
return len;
}
/*
* This decode function is called when the codec is operating in 16 kHz
* bandwidth to decode the upperband, i.e. 8-16 kHz.
*
* Contrary to lower-band, the upper-band (8-16 kHz) is not split in
* frequency, but split to 12 sub-frames, i.e. twice as lower-band.
*/
int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
int16_t isRCUPayload) {
int len, err;
double halfFrameFirst[FRAMESAMPLES_HALF];
double halfFrameSecond[FRAMESAMPLES_HALF];
double percepFilterParam[(UB_LPC_ORDER + 1) * (SUBFRAMES << 1) +
(UB_LPC_ORDER + 1)];
double real_f[FRAMESAMPLES_HALF];
double imag_f[FRAMESAMPLES_HALF];
const int16_t kAveragePitchGain = 0; /* No pitch-gain for upper-band. */
len = 0;
/* Decode & de-quantize filter coefficients. */
memset(percepFilterParam, 0, sizeof(percepFilterParam));
err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
percepFilterParam, isac16kHz);
if (err < 0) {
return err;
}
/* Decode & de-quantize spectrum. */
len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain,
kIsacUpperBand16, real_f, imag_f);
if (len < 0) {
return len;
}
if (isRCUPayload) {
int n;
for (n = 0; n < 240; n++) {
real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
}
}
/* Inverse transform. */
WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond,
&ISACdecUB_obj->fftstr_obj);
/* Perceptual post-filtering (using normalized lattice filter). */
WebRtcIsac_NormLatticeFilterAr(
UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
(ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameFirst,
&percepFilterParam[(UB_LPC_ORDER + 1)], signal_out);
WebRtcIsac_NormLatticeFilterAr(
UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
(ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameSecond,
&percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER + 1)],
&signal_out[FRAMESAMPLES_HALF]);
return len;
}
/*
* This decode function is called when the codec operates at 0-12 kHz
* bandwidth to decode the upperband, i.e. 8-12 kHz.
*
* At the encoder the upper-band is split into two band, 8-12 kHz & 12-16
* kHz, and only 8-12 kHz is encoded. At the decoder, 8-12 kHz band is
* reconstructed and 12-16 kHz replaced with zeros. Then two bands
* are combined, to reconstruct the upperband 8-16 kHz.
*/
int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
int16_t isRCUPayload) {
int len, err;
float LP_dec_float[FRAMESAMPLES_HALF];
float HP_dec_float[FRAMESAMPLES_HALF];
double LPw[FRAMESAMPLES_HALF];
double HPw[FRAMESAMPLES_HALF];
double percepFilterParam[(UB_LPC_ORDER + 1)*SUBFRAMES];
double real_f[FRAMESAMPLES_HALF];
double imag_f[FRAMESAMPLES_HALF];
const int16_t kAveragePitchGain = 0; /* No pitch-gain for upper-band. */
len = 0;
/* Decode & dequantize filter coefficients. */
err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj,
percepFilterParam, isac12kHz);
if (err < 0) {
return err;
}
/* Decode & de-quantize spectrum. */
len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain,
kIsacUpperBand12, real_f, imag_f);
if (len < 0) {
return len;
}
if (isRCUPayload) {
int n;
for (n = 0; n < 240; n++) {
real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE;
}
}
/* Inverse transform. */
WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj);
/* perceptual post-filtering (using normalized lattice filter) */
WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
(ISACdecUB_obj->maskfiltstr_obj).PostStateLoG,
LPw, percepFilterParam, LP_dec_float);
/* Zero for 12-16 kHz. */
memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF));
/* Recombine the 2 bands. */
WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out,
&ISACdecUB_obj->postfiltbankstr_obj);
return len;
}

View File

@@ -0,0 +1,89 @@
/*
* 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 "structs.h"
#include "bandwidth_estimator.h"
#include "entropy_coding.h"
#include "codec.h"
int
WebRtcIsac_EstimateBandwidth(
BwEstimatorstr* bwest_str,
Bitstr* streamdata,
int32_t packet_size,
uint16_t rtp_seq_number,
uint32_t send_ts,
uint32_t arr_ts,
enum IsacSamplingRate encoderSampRate,
enum IsacSamplingRate decoderSampRate)
{
int16_t index;
int16_t frame_samples;
uint32_t sendTimestampIn16kHz;
uint32_t arrivalTimestampIn16kHz;
uint32_t diffSendTime;
uint32_t diffArrivalTime;
int err;
/* decode framelength and BW estimation */
err = WebRtcIsac_DecodeFrameLen(streamdata, &frame_samples);
if(err < 0) // error check
{
return err;
}
err = WebRtcIsac_DecodeSendBW(streamdata, &index);
if(err < 0) // error check
{
return err;
}
/* UPDATE ESTIMATES FROM OTHER SIDE */
err = WebRtcIsac_UpdateUplinkBwImpl(bwest_str, index, encoderSampRate);
if(err < 0)
{
return err;
}
// We like BWE to work at 16 kHz sampling rate,
// therefore, we have to change the timestamps accordingly.
// translate the send timestamp if required
diffSendTime = (uint32_t)((uint32_t)send_ts -
(uint32_t)bwest_str->senderTimestamp);
bwest_str->senderTimestamp = send_ts;
diffArrivalTime = (uint32_t)((uint32_t)arr_ts -
(uint32_t)bwest_str->receiverTimestamp);
bwest_str->receiverTimestamp = arr_ts;
if(decoderSampRate == kIsacSuperWideband)
{
diffArrivalTime = (uint32_t)diffArrivalTime >> 1;
diffSendTime = (uint32_t)diffSendTime >> 1;
}
// arrival timestamp in 16 kHz
arrivalTimestampIn16kHz = (uint32_t)((uint32_t)
bwest_str->prev_rec_arr_ts + (uint32_t)diffArrivalTime);
// send timestamp in 16 kHz
sendTimestampIn16kHz = (uint32_t)((uint32_t)
bwest_str->prev_rec_send_ts + (uint32_t)diffSendTime);
err = WebRtcIsac_UpdateBandwidthEstimator(bwest_str, rtp_seq_number,
(frame_samples * 1000) / FS, sendTimestampIn16kHz,
arrivalTimestampIn16kHz, packet_size);
// error check
if(err < 0)
{
return err;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,708 @@
/*
* 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.
*/
/*
* code_LPC_UB.c
*
* This file contains definition of functions used to
* encode LPC parameters (Shape & gain) of the upper band.
*
*/
#include "encode_lpc_swb.h"
#include "typedefs.h"
#include "settings.h"
#include "lpc_shape_swb12_tables.h"
#include "lpc_shape_swb16_tables.h"
#include "lpc_gain_swb_tables.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
/******************************************************************************
* WebRtcIsac_RemoveLarMean()
*
* Remove the means from LAR coefficients.
*
* Input:
* -lar : pointer to lar vectors. LAR vectors are
* concatenated.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -lar : pointer to mean-removed LAR:s.
*
*
*/
int16_t
WebRtcIsac_RemoveLarMean(
double* lar,
int16_t bandwidth)
{
int16_t coeffCntr;
int16_t vecCntr;
int16_t numVec;
const double* meanLAR;
switch(bandwidth)
{
case isac12kHz:
{
numVec = UB_LPC_VEC_PER_FRAME;
meanLAR = WebRtcIsac_kMeanLarUb12;
break;
}
case isac16kHz:
{
numVec = UB16_LPC_VEC_PER_FRAME;
meanLAR = WebRtcIsac_kMeanLarUb16;
break;
}
default:
return -1;
}
for(vecCntr = 0; vecCntr < numVec; vecCntr++)
{
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
{
// REMOVE MEAN
*lar++ -= meanLAR[coeffCntr];
}
}
return 0;
}
/******************************************************************************
* WebRtcIsac_DecorrelateIntraVec()
*
* Remove the correlation amonge the components of LAR vectors. If LAR vectors
* of one frame are put in a matrix where each column is a LAR vector of a
* sub-frame, then this is equivalent to multiplying the LAR matrix with
* a decorrelting mtrix from left.
*
* Input:
* -inLar : pointer to mean-removed LAR vecrtors.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : decorrelated LAR vectors.
*/
int16_t
WebRtcIsac_DecorrelateIntraVec(
const double* data,
double* out,
int16_t bandwidth)
{
const double* ptrData;
const double* ptrRow;
int16_t rowCntr;
int16_t colCntr;
int16_t larVecCntr;
int16_t numVec;
const double* decorrMat;
switch(bandwidth)
{
case isac12kHz:
{
decorrMat = &WebRtcIsac_kIntraVecDecorrMatUb12[0][0];
numVec = UB_LPC_VEC_PER_FRAME;
break;
}
case isac16kHz:
{
decorrMat = &WebRtcIsac_kIintraVecDecorrMatUb16[0][0];
numVec = UB16_LPC_VEC_PER_FRAME;
break;
}
default:
return -1;
}
//
// decorrMat * data
//
// data is assumed to contain 'numVec' of LAR
// vectors (mean removed) each of dimension 'UB_LPC_ORDER'
// concatenated one after the other.
//
ptrData = data;
for(larVecCntr = 0; larVecCntr < numVec; larVecCntr++)
{
for(rowCntr = 0; rowCntr < UB_LPC_ORDER; rowCntr++)
{
ptrRow = &decorrMat[rowCntr * UB_LPC_ORDER];
*out = 0;
for(colCntr = 0; colCntr < UB_LPC_ORDER; colCntr++)
{
*out += ptrData[colCntr] * ptrRow[colCntr];
}
out++;
}
ptrData += UB_LPC_ORDER;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_DecorrelateInterVec()
*
* Remover the correlation among mean-removed LAR vectors. If LAR vectors
* of one frame are put in a matrix where each column is a LAR vector of a
* sub-frame, then this is equivalent to multiplying the LAR matrix with
* a decorrelting mtrix from right.
*
* Input:
* -data : pointer to matrix of LAR vectors. The matrix
* is stored column-wise.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : decorrelated LAR vectors.
*/
int16_t
WebRtcIsac_DecorrelateInterVec(
const double* data,
double* out,
int16_t bandwidth)
{
int16_t coeffCntr;
int16_t rowCntr;
int16_t colCntr;
const double* decorrMat;
int16_t interVecDim;
switch(bandwidth)
{
case isac12kHz:
{
decorrMat = &WebRtcIsac_kInterVecDecorrMatUb12[0][0];
interVecDim = UB_LPC_VEC_PER_FRAME;
break;
}
case isac16kHz:
{
decorrMat = &WebRtcIsac_kInterVecDecorrMatUb16[0][0];
interVecDim = UB16_LPC_VEC_PER_FRAME;
break;
}
default:
return -1;
}
//
// data * decorrMat
//
// data is of size 'interVecDim' * 'UB_LPC_ORDER'
// That is 'interVecDim' of LAR vectors (mean removed)
// in columns each of dimension 'UB_LPC_ORDER'.
// matrix is stored column-wise.
//
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
{
for(colCntr = 0; colCntr < interVecDim; colCntr++)
{
out[coeffCntr + colCntr * UB_LPC_ORDER] = 0;
for(rowCntr = 0; rowCntr < interVecDim; rowCntr++)
{
out[coeffCntr + colCntr * UB_LPC_ORDER] +=
data[coeffCntr + rowCntr * UB_LPC_ORDER] *
decorrMat[rowCntr * interVecDim + colCntr];
}
}
}
return 0;
}
/******************************************************************************
* WebRtcIsac_QuantizeUncorrLar()
*
* Quantize the uncorrelated parameters.
*
* Input:
* -data : uncorrelated LAR vectors.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -data : quantized version of the input.
* -idx : pointer to quantization indices.
*/
double
WebRtcIsac_QuantizeUncorrLar(
double* data,
int* recIdx,
int16_t bandwidth)
{
int16_t cntr;
int32_t idx;
int16_t interVecDim;
const double* leftRecPoint;
double quantizationStepSize;
const int16_t* numQuantCell;
switch(bandwidth)
{
case isac12kHz:
{
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb12;
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb12;
numQuantCell = WebRtcIsac_kLpcShapeNumRecPointUb12;
interVecDim = UB_LPC_VEC_PER_FRAME;
break;
}
case isac16kHz:
{
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb16;
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb16;
numQuantCell = WebRtcIsac_kLpcShapeNumRecPointUb16;
interVecDim = UB16_LPC_VEC_PER_FRAME;
break;
}
default:
return -1;
}
//
// Quantize the parametrs.
//
for(cntr = 0; cntr < UB_LPC_ORDER * interVecDim; cntr++)
{
idx = (int32_t)floor((*data - leftRecPoint[cntr]) /
quantizationStepSize + 0.5);
if(idx < 0)
{
idx = 0;
}
else if(idx >= numQuantCell[cntr])
{
idx = numQuantCell[cntr] - 1;
}
*data++ = leftRecPoint[cntr] + idx * quantizationStepSize;
*recIdx++ = idx;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_DequantizeLpcParam()
*
* Get the quantized value of uncorrelated LARs given the quantization indices.
*
* Input:
* -idx : pointer to quantiztion indices.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : pointer to quantized values.
*/
int16_t
WebRtcIsac_DequantizeLpcParam(
const int* idx,
double* out,
int16_t bandwidth)
{
int16_t cntr;
int16_t interVecDim;
const double* leftRecPoint;
double quantizationStepSize;
switch(bandwidth)
{
case isac12kHz:
{
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb12;
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb12;
interVecDim = UB_LPC_VEC_PER_FRAME;
break;
}
case isac16kHz:
{
leftRecPoint = WebRtcIsac_kLpcShapeLeftRecPointUb16;
quantizationStepSize = WebRtcIsac_kLpcShapeQStepSizeUb16;
interVecDim = UB16_LPC_VEC_PER_FRAME;
break;
}
default:
return -1;
}
//
// Dequantize given the quantization indices
//
for(cntr = 0; cntr < UB_LPC_ORDER * interVecDim; cntr++)
{
*out++ = leftRecPoint[cntr] + *idx++ * quantizationStepSize;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_CorrelateIntraVec()
*
* This is the inverse of WebRtcIsac_DecorrelateIntraVec().
*
* Input:
* -data : uncorrelated parameters.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : correlated parametrs.
*/
int16_t
WebRtcIsac_CorrelateIntraVec(
const double* data,
double* out,
int16_t bandwidth)
{
int16_t vecCntr;
int16_t rowCntr;
int16_t colCntr;
int16_t numVec;
const double* ptrData;
const double* intraVecDecorrMat;
switch(bandwidth)
{
case isac12kHz:
{
numVec = UB_LPC_VEC_PER_FRAME;
intraVecDecorrMat = &WebRtcIsac_kIntraVecDecorrMatUb12[0][0];
break;
}
case isac16kHz:
{
numVec = UB16_LPC_VEC_PER_FRAME;
intraVecDecorrMat = &WebRtcIsac_kIintraVecDecorrMatUb16[0][0];
break;
}
default:
return -1;
}
ptrData = data;
for(vecCntr = 0; vecCntr < numVec; vecCntr++)
{
for(colCntr = 0; colCntr < UB_LPC_ORDER; colCntr++)
{
*out = 0;
for(rowCntr = 0; rowCntr < UB_LPC_ORDER; rowCntr++)
{
*out += ptrData[rowCntr] *
intraVecDecorrMat[rowCntr * UB_LPC_ORDER + colCntr];
}
out++;
}
ptrData += UB_LPC_ORDER;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_CorrelateInterVec()
*
* This is the inverse of WebRtcIsac_DecorrelateInterVec().
*
* Input:
* -data
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : correlated parametrs.
*/
int16_t
WebRtcIsac_CorrelateInterVec(
const double* data,
double* out,
int16_t bandwidth)
{
int16_t coeffCntr;
int16_t rowCntr;
int16_t colCntr;
int16_t interVecDim;
double myVec[UB16_LPC_VEC_PER_FRAME];
const double* interVecDecorrMat;
switch(bandwidth)
{
case isac12kHz:
{
interVecDim = UB_LPC_VEC_PER_FRAME;
interVecDecorrMat = &WebRtcIsac_kInterVecDecorrMatUb12[0][0];
break;
}
case isac16kHz:
{
interVecDim = UB16_LPC_VEC_PER_FRAME;
interVecDecorrMat = &WebRtcIsac_kInterVecDecorrMatUb16[0][0];
break;
}
default:
return -1;
}
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
{
for(rowCntr = 0; rowCntr < interVecDim; rowCntr++)
{
myVec[rowCntr] = 0;
for(colCntr = 0; colCntr < interVecDim; colCntr++)
{
myVec[rowCntr] += data[coeffCntr + colCntr * UB_LPC_ORDER] * //*ptrData *
interVecDecorrMat[rowCntr * interVecDim + colCntr];
//ptrData += UB_LPC_ORDER;
}
}
for(rowCntr = 0; rowCntr < interVecDim; rowCntr++)
{
out[coeffCntr + rowCntr * UB_LPC_ORDER] = myVec[rowCntr];
}
}
return 0;
}
/******************************************************************************
* WebRtcIsac_AddLarMean()
*
* This is the inverse of WebRtcIsac_RemoveLarMean()
*
* Input:
* -data : pointer to mean-removed LAR:s.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -data : pointer to LARs.
*/
int16_t
WebRtcIsac_AddLarMean(
double* data,
int16_t bandwidth)
{
int16_t coeffCntr;
int16_t vecCntr;
int16_t numVec;
const double* meanLAR;
switch(bandwidth)
{
case isac12kHz:
{
numVec = UB_LPC_VEC_PER_FRAME;
meanLAR = WebRtcIsac_kMeanLarUb12;
break;
}
case isac16kHz:
{
numVec = UB16_LPC_VEC_PER_FRAME;
meanLAR = WebRtcIsac_kMeanLarUb16;
break;
}
default:
return -1;
}
for(vecCntr = 0; vecCntr < numVec; vecCntr++)
{
for(coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++)
{
*data++ += meanLAR[coeffCntr];
}
}
return 0;
}
/******************************************************************************
* WebRtcIsac_ToLogDomainRemoveMean()
*
* Transform the LPC gain to log domain then remove the mean value.
*
* Input:
* -lpcGain : pointer to LPC Gain, expecting 6 LPC gains
*
* Output:
* -lpcGain : mean-removed in log domain.
*/
int16_t
WebRtcIsac_ToLogDomainRemoveMean(
double* data)
{
int16_t coeffCntr;
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
{
data[coeffCntr] = log(data[coeffCntr]) - WebRtcIsac_kMeanLpcGain;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_DecorrelateLPGain()
*
* Decorrelate LPC gains. There are 6 LPC Gains per frame. This is like
* multiplying gain vector with decorrelating matrix.
*
* Input:
* -data : LPC gain in log-domain with mean removed.
*
* Output:
* -out : decorrelated parameters.
*/
int16_t WebRtcIsac_DecorrelateLPGain(
const double* data,
double* out)
{
int16_t rowCntr;
int16_t colCntr;
for(colCntr = 0; colCntr < UB_LPC_GAIN_DIM; colCntr++)
{
*out = 0;
for(rowCntr = 0; rowCntr < UB_LPC_GAIN_DIM; rowCntr++)
{
*out += data[rowCntr] * WebRtcIsac_kLpcGainDecorrMat[rowCntr][colCntr];
}
out++;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_QuantizeLpcGain()
*
* Quantize the decorrelated log-domain gains.
*
* Input:
* -lpcGain : uncorrelated LPC gains.
*
* Output:
* -idx : quantization indices
* -lpcGain : quantized value of the inpt.
*/
double WebRtcIsac_QuantizeLpcGain(
double* data,
int* idx)
{
int16_t coeffCntr;
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
{
*idx = (int)floor((*data - WebRtcIsac_kLeftRecPointLpcGain[coeffCntr]) /
WebRtcIsac_kQSizeLpcGain + 0.5);
if(*idx < 0)
{
*idx = 0;
}
else if(*idx >= WebRtcIsac_kNumQCellLpcGain[coeffCntr])
{
*idx = WebRtcIsac_kNumQCellLpcGain[coeffCntr] - 1;
}
*data = WebRtcIsac_kLeftRecPointLpcGain[coeffCntr] + *idx *
WebRtcIsac_kQSizeLpcGain;
data++;
idx++;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_DequantizeLpcGain()
*
* Get the quantized values given the quantization indices.
*
* Input:
* -idx : pointer to quantization indices.
*
* Output:
* -lpcGains : quantized values of the given parametes.
*/
int16_t WebRtcIsac_DequantizeLpcGain(
const int* idx,
double* out)
{
int16_t coeffCntr;
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
{
*out = WebRtcIsac_kLeftRecPointLpcGain[coeffCntr] + *idx *
WebRtcIsac_kQSizeLpcGain;
out++;
idx++;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_CorrelateLpcGain()
*
* This is the inverse of WebRtcIsac_DecorrelateLPGain().
*
* Input:
* -data : decorrelated parameters.
*
* Output:
* -out : correlated parameters.
*/
int16_t WebRtcIsac_CorrelateLpcGain(
const double* data,
double* out)
{
int16_t rowCntr;
int16_t colCntr;
for(rowCntr = 0; rowCntr < UB_LPC_GAIN_DIM; rowCntr++)
{
*out = 0;
for(colCntr = 0; colCntr < UB_LPC_GAIN_DIM; colCntr++)
{
*out += WebRtcIsac_kLpcGainDecorrMat[rowCntr][colCntr] * data[colCntr];
}
out++;
}
return 0;
}
/******************************************************************************
* WebRtcIsac_AddMeanToLinearDomain()
*
* This is the inverse of WebRtcIsac_ToLogDomainRemoveMean().
*
* Input:
* -lpcGain : LPC gain in log-domain & mean removed
*
* Output:
* -lpcGain : LPC gain in normal domain.
*/
int16_t WebRtcIsac_AddMeanToLinearDomain(
double* lpcGains)
{
int16_t coeffCntr;
for(coeffCntr = 0; coeffCntr < UB_LPC_GAIN_DIM; coeffCntr++)
{
lpcGains[coeffCntr] = exp(lpcGains[coeffCntr] + WebRtcIsac_kMeanLpcGain);
}
return 0;
}

View File

@@ -0,0 +1,283 @@
/*
* 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.
*/
/*
* encode_lpc_swb.h
*
* This file contains declaration of functions used to
* encode LPC parameters (Shape & gain) of the upper band.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_
#include "typedefs.h"
#include "settings.h"
#include "structs.h"
/******************************************************************************
* WebRtcIsac_RemoveLarMean()
*
* Remove the means from LAR coefficients.
*
* Input:
* -lar : pointer to lar vectors. LAR vectors are
* concatenated.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -lar : pointer to mean-removed LAR:s.
*
*
*/
int16_t WebRtcIsac_RemoveLarMean(
double* lar,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_DecorrelateIntraVec()
*
* Remove the correlation amonge the components of LAR vectors. If LAR vectors
* of one frame are put in a matrix where each column is a LAR vector of a
* sub-frame, then this is equivalent to multiplying the LAR matrix with
* a decorrelting mtrix from left.
*
* Input:
* -inLar : pointer to mean-removed LAR vecrtors.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : decorrelated LAR vectors.
*/
int16_t WebRtcIsac_DecorrelateIntraVec(
const double* inLAR,
double* out,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_DecorrelateInterVec()
*
* Remover the correlation among mean-removed LAR vectors. If LAR vectors
* of one frame are put in a matrix where each column is a LAR vector of a
* sub-frame, then this is equivalent to multiplying the LAR matrix with
* a decorrelting mtrix from right.
*
* Input:
* -data : pointer to matrix of LAR vectors. The matrix
* is stored column-wise.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : decorrelated LAR vectors.
*/
int16_t WebRtcIsac_DecorrelateInterVec(
const double* data,
double* out,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_QuantizeUncorrLar()
*
* Quantize the uncorrelated parameters.
*
* Input:
* -data : uncorrelated LAR vectors.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -data : quantized version of the input.
* -idx : pointer to quantization indices.
*/
double WebRtcIsac_QuantizeUncorrLar(
double* data,
int* idx,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_CorrelateIntraVec()
*
* This is the inverse of WebRtcIsac_DecorrelateIntraVec().
*
* Input:
* -data : uncorrelated parameters.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : correlated parametrs.
*/
int16_t WebRtcIsac_CorrelateIntraVec(
const double* data,
double* out,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_CorrelateInterVec()
*
* This is the inverse of WebRtcIsac_DecorrelateInterVec().
*
* Input:
* -data
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : correlated parametrs.
*/
int16_t WebRtcIsac_CorrelateInterVec(
const double* data,
double* out,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_AddLarMean()
*
* This is the inverse of WebRtcIsac_RemoveLarMean()
*
* Input:
* -data : pointer to mean-removed LAR:s.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -data : pointer to LARs.
*/
int16_t WebRtcIsac_AddLarMean(
double* data,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_DequantizeLpcParam()
*
* Get the quantized value of uncorrelated LARs given the quantization indices.
*
* Input:
* -idx : pointer to quantiztion indices.
* -bandwidth : indicates if the given LAR vectors belong
* to SWB-12kHz or SWB-16kHz.
*
* Output:
* -out : pointer to quantized values.
*/
int16_t WebRtcIsac_DequantizeLpcParam(
const int* idx,
double* out,
int16_t bandwidth);
/******************************************************************************
* WebRtcIsac_ToLogDomainRemoveMean()
*
* Transform the LPC gain to log domain then remove the mean value.
*
* Input:
* -lpcGain : pointer to LPC Gain, expecting 6 LPC gains
*
* Output:
* -lpcGain : mean-removed in log domain.
*/
int16_t WebRtcIsac_ToLogDomainRemoveMean(
double* lpGains);
/******************************************************************************
* WebRtcIsac_DecorrelateLPGain()
*
* Decorrelate LPC gains. There are 6 LPC Gains per frame. This is like
* multiplying gain vector with decorrelating matrix.
*
* Input:
* -data : LPC gain in log-domain with mean removed.
*
* Output:
* -out : decorrelated parameters.
*/
int16_t WebRtcIsac_DecorrelateLPGain(
const double* data,
double* out);
/******************************************************************************
* WebRtcIsac_QuantizeLpcGain()
*
* Quantize the decorrelated log-domain gains.
*
* Input:
* -lpcGain : uncorrelated LPC gains.
*
* Output:
* -idx : quantization indices
* -lpcGain : quantized value of the inpt.
*/
double WebRtcIsac_QuantizeLpcGain(
double* lpGains,
int* idx);
/******************************************************************************
* WebRtcIsac_DequantizeLpcGain()
*
* Get the quantized values given the quantization indices.
*
* Input:
* -idx : pointer to quantization indices.
*
* Output:
* -lpcGains : quantized values of the given parametes.
*/
int16_t WebRtcIsac_DequantizeLpcGain(
const int* idx,
double* lpGains);
/******************************************************************************
* WebRtcIsac_CorrelateLpcGain()
*
* This is the inverse of WebRtcIsac_DecorrelateLPGain().
*
* Input:
* -data : decorrelated parameters.
*
* Output:
* -out : correlated parameters.
*/
int16_t WebRtcIsac_CorrelateLpcGain(
const double* data,
double* out);
/******************************************************************************
* WebRtcIsac_AddMeanToLinearDomain()
*
* This is the inverse of WebRtcIsac_ToLogDomainRemoveMean().
*
* Input:
* -lpcGain : LPC gain in log-domain & mean removed
*
* Output:
* -lpcGain : LPC gain in normal domain.
*/
int16_t WebRtcIsac_AddMeanToLinearDomain(
double* lpcGains);
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENCODE_LPC_SWB_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,341 @@
/*
* Copyright (c) 2012 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.
*/
/*
* entropy_coding.h
*
* This header file declares all of the functions used to arithmetically
* encode the iSAC bistream
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_
#include "settings.h"
#include "structs.h"
/******************************************************************************
* WebRtcIsac_DecodeSpec()
* Decode real and imaginary part of the DFT coefficients, given a bit-stream.
* The decoded DFT coefficient can be transformed to time domain by
* WebRtcIsac_Time2Spec().
*
* Input:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
* - AvgPitchGain_Q12 : average pitch-gain of the frame. This is only
* relevant for 0-4 kHz band, and the input value is
* not used in other bands.
* - band : specifies which band's DFT should be decoded.
*
* Output:
* - *fr : pointer to a buffer where the real part of DFT
* coefficients are written to.
* - *fi : pointer to a buffer where the imaginary part
* of DFT coefficients are written to.
*
* Return value : < 0 if an error occures
* 0 if succeeded.
*/
int WebRtcIsac_DecodeSpec(Bitstr* streamdata, int16_t AvgPitchGain_Q12,
enum ISACBand band, double* fr, double* fi);
/******************************************************************************
* WebRtcIsac_EncodeSpec()
* Encode real and imaginary part of the DFT coefficients into the given
* bit-stream.
*
* Input:
* - *fr : pointer to a buffer where the real part of DFT
* coefficients are written to.
* - *fi : pointer to a buffer where the imaginary part
* of DFT coefficients are written to.
* - AvgPitchGain_Q12 : average pitch-gain of the frame. This is only
* relevant for 0-4 kHz band, and the input value is
* not used in other bands.
* - band : specifies which band's DFT should be decoded.
*
* Output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Return value : < 0 if an error occures
* 0 if succeeded.
*/
int WebRtcIsac_EncodeSpec(const int16_t* fr, const int16_t* fi,
int16_t AvgPitchGain_Q12, enum ISACBand band,
Bitstr* streamdata);
/* decode & dequantize LPC Coef */
int WebRtcIsac_DecodeLpcCoef(Bitstr* streamdata, double* LPCCoef);
int WebRtcIsac_DecodeLpcCoefUB(Bitstr* streamdata, double* lpcVecs,
double* percepFilterGains,
int16_t bandwidth);
int WebRtcIsac_DecodeLpc(Bitstr* streamdata, double* LPCCoef_lo,
double* LPCCoef_hi);
/* quantize & code LPC Coef */
void WebRtcIsac_EncodeLpcLb(double* LPCCoef_lo, double* LPCCoef_hi,
Bitstr* streamdata, ISAC_SaveEncData_t* encData);
void WebRtcIsac_EncodeLpcGainLb(double* LPCCoef_lo, double* LPCCoef_hi,
Bitstr* streamdata,
ISAC_SaveEncData_t* encData);
/******************************************************************************
* WebRtcIsac_EncodeLpcUB()
* Encode LPC parameters, given as A-polynomial, of upper-band. The encoding
* is performed in LAR domain.
* For the upper-band, we compute and encode LPC of some sub-frames, LPC of
* other sub-frames are computed by linear interpolation, in LAR domain. This
* function performs the interpolation and returns the LPC of all sub-frames.
*
* Inputs:
* - lpcCoef : a buffer containing A-polynomials of sub-frames
* (excluding first coefficient that is 1).
* - bandwidth : specifies if the codec is operating at 0-12 kHz
* or 0-16 kHz mode.
*
* Input/output:
* - streamdata : pointer to a structure containing the encoded
* data and the parameters needed for entropy
* coding.
*
* Output:
* - interpolLPCCoeff : Decoded and interpolated LPC (A-polynomial)
* of all sub-frames.
* If LP analysis is of order K, and there are N
* sub-frames then this is a buffer of size
* (k + 1) * N, each vector starts with the LPC gain
* of the corresponding sub-frame. The LPC gains
* are encoded and inserted after this function is
* called. The first A-coefficient which is 1 is not
* included.
*
* Return value : 0 if encoding is successful,
* <0 if failed to encode.
*/
int16_t WebRtcIsac_EncodeLpcUB(double* lpcCoeff, Bitstr* streamdata,
double* interpolLPCCoeff,
int16_t bandwidth,
ISACUBSaveEncDataStruct* encData);
/******************************************************************************
* WebRtcIsac_DecodeInterpolLpcUb()
* Decode LPC coefficients and interpolate to get the coefficients fo all
* sub-frmaes.
*
* Inputs:
* - bandwidth : spepecifies if the codec is in 0-12 kHz or
* 0-16 kHz mode.
*
* Input/output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Output:
* - percepFilterParam : Decoded and interpolated LPC (A-polynomial) of
* all sub-frames.
* If LP analysis is of order K, and there are N
* sub-frames then this is a buffer of size
* (k + 1) * N, each vector starts with the LPC gain
* of the corresponding sub-frame. The LPC gains
* are encoded and inserted after this function is
* called. The first A-coefficient which is 1 is not
* included.
*
* Return value : 0 if encoding is successful,
* <0 if failed to encode.
*/
int16_t WebRtcIsac_DecodeInterpolLpcUb(Bitstr* streamdata,
double* percepFilterParam,
int16_t bandwidth);
/* Decode & dequantize RC */
int WebRtcIsac_DecodeRc(Bitstr* streamdata, int16_t* RCQ15);
/* Quantize & code RC */
void WebRtcIsac_EncodeRc(int16_t* RCQ15, Bitstr* streamdata);
/* Decode & dequantize squared Gain */
int WebRtcIsac_DecodeGain2(Bitstr* streamdata, int32_t* Gain2);
/* Quantize & code squared Gain (input is squared gain) */
int WebRtcIsac_EncodeGain2(int32_t* gain2, Bitstr* streamdata);
void WebRtcIsac_EncodePitchGain(int16_t* PitchGains_Q12,
Bitstr* streamdata,
ISAC_SaveEncData_t* encData);
void WebRtcIsac_EncodePitchLag(double* PitchLags, int16_t* PitchGain_Q12,
Bitstr* streamdata, ISAC_SaveEncData_t* encData);
int WebRtcIsac_DecodePitchGain(Bitstr* streamdata,
int16_t* PitchGain_Q12);
int WebRtcIsac_DecodePitchLag(Bitstr* streamdata, int16_t* PitchGain_Q12,
double* PitchLag);
int WebRtcIsac_DecodeFrameLen(Bitstr* streamdata, int16_t* framelength);
int WebRtcIsac_EncodeFrameLen(int16_t framelength, Bitstr* streamdata);
int WebRtcIsac_DecodeSendBW(Bitstr* streamdata, int16_t* BWno);
void WebRtcIsac_EncodeReceiveBw(int* BWno, Bitstr* streamdata);
/* Step-down */
void WebRtcIsac_Poly2Rc(double* a, int N, double* RC);
/* Step-up */
void WebRtcIsac_Rc2Poly(double* RC, int N, double* a);
void WebRtcIsac_TranscodeLPCCoef(double* LPCCoef_lo, double* LPCCoef_hi,
int* index_g);
/******************************************************************************
* WebRtcIsac_EncodeLpcGainUb()
* Encode LPC gains of sub-Frames.
*
* Input/outputs:
* - lpGains : a buffer which contains 'SUBFRAME' number of
* LP gains to be encoded. The input values are
* overwritten by the quantized values.
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Output:
* - lpcGainIndex : quantization indices for lpc gains, these will
* be stored to be used for FEC.
*/
void WebRtcIsac_EncodeLpcGainUb(double* lpGains, Bitstr* streamdata,
int* lpcGainIndex);
/******************************************************************************
* WebRtcIsac_EncodeLpcGainUb()
* Store LPC gains of sub-Frames in 'streamdata'.
*
* Input:
* - lpGains : a buffer which contains 'SUBFRAME' number of
* LP gains to be encoded.
* Input/outputs:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
*/
void WebRtcIsac_StoreLpcGainUb(double* lpGains, Bitstr* streamdata);
/******************************************************************************
* WebRtcIsac_DecodeLpcGainUb()
* Decode the LPC gain of sub-frames.
*
* Input/output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Output:
* - lpGains : a buffer where decoded LPC gians will be stored.
*
* Return value : 0 if succeeded.
* <0 if failed.
*/
int16_t WebRtcIsac_DecodeLpcGainUb(double* lpGains, Bitstr* streamdata);
/******************************************************************************
* WebRtcIsac_EncodeBandwidth()
* Encode if the bandwidth of encoded audio is 0-12 kHz or 0-16 kHz.
*
* Input:
* - bandwidth : an enumerator specifying if the codec in is
* 0-12 kHz or 0-16 kHz mode.
*
* Input/output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Return value : 0 if succeeded.
* <0 if failed.
*/
int16_t WebRtcIsac_EncodeBandwidth(enum ISACBandwidth bandwidth,
Bitstr* streamData);
/******************************************************************************
* WebRtcIsac_DecodeBandwidth()
* Decode the bandwidth of the encoded audio, i.e. if the bandwidth is 0-12 kHz
* or 0-16 kHz.
*
* Input/output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Output:
* - bandwidth : an enumerator specifying if the codec is in
* 0-12 kHz or 0-16 kHz mode.
*
* Return value : 0 if succeeded.
* <0 if failed.
*/
int16_t WebRtcIsac_DecodeBandwidth(Bitstr* streamData,
enum ISACBandwidth* bandwidth);
/******************************************************************************
* WebRtcIsac_EncodeJitterInfo()
* Decode the jitter information.
*
* Input/output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Input:
* - jitterInfo : one bit of info specifying if the channel is
* in high/low jitter. Zero indicates low jitter
* and one indicates high jitter.
*
* Return value : 0 if succeeded.
* <0 if failed.
*/
int16_t WebRtcIsac_EncodeJitterInfo(int32_t jitterIndex,
Bitstr* streamData);
/******************************************************************************
* WebRtcIsac_DecodeJitterInfo()
* Decode the jitter information.
*
* Input/output:
* - streamdata : pointer to a stucture containg the encoded
* data and theparameters needed for entropy
* coding.
*
* Output:
* - jitterInfo : one bit of info specifying if the channel is
* in high/low jitter. Zero indicates low jitter
* and one indicates high jitter.
*
* Return value : 0 if succeeded.
* <0 if failed.
*/
int16_t WebRtcIsac_DecodeJitterInfo(Bitstr* streamData,
int32_t* jitterInfo);
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ */

View File

@@ -0,0 +1,943 @@
/*
* Copyright(c)1995,97 Mark Olesen <olesen@me.QueensU.CA>
* Queen's Univ at Kingston (Canada)
*
* Permission to use, copy, modify, and distribute this software for
* any purpose without fee is hereby granted, provided that this
* entire notice is included in all copies of any software which is
* or includes a copy or modification of this software and in all
* copies of the supporting documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR QUEEN'S
* UNIVERSITY AT KINGSTON MAKES ANY REPRESENTATION OR WARRANTY OF ANY
* KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* All of which is to say that you can do what you like with this
* source code provided you don't try to sell it as your own and you
* include an unaltered copy of this message (including the
* copyright).
*
* It is also implicitly understood that bug fixes and improvements
* should make their way back to the general Internet community so
* that everyone benefits.
*
* Changes:
* Trivial type modifications by the WebRTC authors.
*/
/*
* File:
* WebRtcIsac_Fftn.c
*
* Public:
* WebRtcIsac_Fftn / fftnf ();
*
* Private:
* WebRtcIsac_Fftradix / fftradixf ();
*
* Descript:
* multivariate complex Fourier transform, computed in place
* using mixed-radix Fast Fourier Transform algorithm.
*
* Fortran code by:
* RC Singleton, Stanford Research Institute, Sept. 1968
*
* translated by f2c (version 19950721).
*
* int WebRtcIsac_Fftn (int ndim, const int dims[], REAL Re[], REAL Im[],
* int iSign, double scaling);
*
* NDIM = the total number dimensions
* DIMS = a vector of array sizes
* if NDIM is zero then DIMS must be zero-terminated
*
* RE and IM hold the real and imaginary components of the data, and return
* the resulting real and imaginary Fourier coefficients. Multidimensional
* data *must* be allocated contiguously. There is no limit on the number
* of dimensions.
*
* ISIGN = the sign of the complex exponential (ie, forward or inverse FFT)
* the magnitude of ISIGN (normally 1) is used to determine the
* correct indexing increment (see below).
*
* SCALING = normalizing constant by which the final result is *divided*
* if SCALING == -1, normalize by total dimension of the transform
* if SCALING < -1, normalize by the square-root of the total dimension
*
* example:
* tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3]
*
* int dims[3] = {n1,n2,n3}
* WebRtcIsac_Fftn (3, dims, Re, Im, 1, scaling);
*
*-----------------------------------------------------------------------*
* int WebRtcIsac_Fftradix (REAL Re[], REAL Im[], size_t nTotal, size_t nPass,
* size_t nSpan, int iSign, size_t max_factors,
* size_t max_perm);
*
* RE, IM - see above documentation
*
* Although there is no limit on the number of dimensions, WebRtcIsac_Fftradix() must
* be called once for each dimension, but the calls may be in any order.
*
* NTOTAL = the total number of complex data values
* NPASS = the dimension of the current variable
* NSPAN/NPASS = the spacing of consecutive data values while indexing the
* current variable
* ISIGN - see above documentation
*
* example:
* tri-variate transform with Re[n1][n2][n3], Im[n1][n2][n3]
*
* WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n1, n1, 1, maxf, maxp);
* WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n2, n1*n2, 1, maxf, maxp);
* WebRtcIsac_Fftradix (Re, Im, n1*n2*n3, n3, n1*n2*n3, 1, maxf, maxp);
*
* single-variate transform,
* NTOTAL = N = NSPAN = (number of complex data values),
*
* WebRtcIsac_Fftradix (Re, Im, n, n, n, 1, maxf, maxp);
*
* The data can also be stored in a single array with alternating real and
* imaginary parts, the magnitude of ISIGN is changed to 2 to give correct
* indexing increment, and data [0] and data [1] used to pass the initial
* addresses for the sequences of real and imaginary values,
*
* example:
* REAL data [2*NTOTAL];
* WebRtcIsac_Fftradix ( &data[0], &data[1], NTOTAL, nPass, nSpan, 2, maxf, maxp);
*
* for temporary allocation:
*
* MAX_FACTORS >= the maximum prime factor of NPASS
* MAX_PERM >= the number of prime factors of NPASS. In addition,
* if the square-free portion K of NPASS has two or more prime
* factors, then MAX_PERM >= (K-1)
*
* storage in FACTOR for a maximum of 15 prime factors of NPASS. if NPASS
* has more than one square-free factor, the product of the square-free
* factors must be <= 210 array storage for maximum prime factor of 23 the
* following two constants should agree with the array dimensions.
*
*----------------------------------------------------------------------*/
#include "fft.h"
#include <stdlib.h>
#include <math.h>
/* double precision routine */
static int
WebRtcIsac_Fftradix (double Re[], double Im[],
size_t nTotal, size_t nPass, size_t nSpan, int isign,
int max_factors, unsigned int max_perm,
FFTstr *fftstate);
#ifndef M_PI
# define M_PI 3.14159265358979323846264338327950288
#endif
#ifndef SIN60
# define SIN60 0.86602540378443865 /* sin(60 deg) */
# define COS72 0.30901699437494742 /* cos(72 deg) */
# define SIN72 0.95105651629515357 /* sin(72 deg) */
#endif
# define REAL double
# define FFTN WebRtcIsac_Fftn
# define FFTNS "fftn"
# define FFTRADIX WebRtcIsac_Fftradix
# define FFTRADIXS "fftradix"
int WebRtcIsac_Fftns(unsigned int ndim, const int dims[],
double Re[],
double Im[],
int iSign,
double scaling,
FFTstr *fftstate)
{
size_t nSpan, nPass, nTotal;
unsigned int i;
int ret, max_factors, max_perm;
/*
* tally the number of elements in the data array
* and determine the number of dimensions
*/
nTotal = 1;
if (ndim && dims [0])
{
for (i = 0; i < ndim; i++)
{
if (dims [i] <= 0)
{
return -1;
}
nTotal *= dims [i];
}
}
else
{
ndim = 0;
for (i = 0; dims [i]; i++)
{
if (dims [i] <= 0)
{
return -1;
}
nTotal *= dims [i];
ndim++;
}
}
/* determine maximum number of factors and permuations */
#if 1
/*
* follow John Beale's example, just use the largest dimension and don't
* worry about excess allocation. May be someone else will do it?
*/
max_factors = max_perm = 1;
for (i = 0; i < ndim; i++)
{
nSpan = dims [i];
if ((int)nSpan > max_factors)
{
max_factors = (int)nSpan;
}
if ((int)nSpan > max_perm)
{
max_perm = (int)nSpan;
}
}
#else
/* use the constants used in the original Fortran code */
max_factors = 23;
max_perm = 209;
#endif
/* loop over the dimensions: */
nPass = 1;
for (i = 0; i < ndim; i++)
{
nSpan = dims [i];
nPass *= nSpan;
ret = FFTRADIX (Re, Im, nTotal, nSpan, nPass, iSign,
max_factors, max_perm, fftstate);
/* exit, clean-up already done */
if (ret)
return ret;
}
/* Divide through by the normalizing constant: */
if (scaling && scaling != 1.0)
{
if (iSign < 0) iSign = -iSign;
if (scaling < 0.0)
{
scaling = (double)nTotal;
if (scaling < -1.0)
scaling = sqrt (scaling);
}
scaling = 1.0 / scaling; /* multiply is often faster */
for (i = 0; i < nTotal; i += iSign)
{
Re [i] *= scaling;
Im [i] *= scaling;
}
}
return 0;
}
/*
* singleton's mixed radix routine
*
* could move allocation out to WebRtcIsac_Fftn(), but leave it here so that it's
* possible to make this a standalone function
*/
static int FFTRADIX (REAL Re[],
REAL Im[],
size_t nTotal,
size_t nPass,
size_t nSpan,
int iSign,
int max_factors,
unsigned int max_perm,
FFTstr *fftstate)
{
int ii, mfactor, kspan, ispan, inc;
int j, jc, jf, jj, k, k1, k2, k3, k4, kk, kt, nn, ns, nt;
REAL radf;
REAL c1, c2, c3, cd, aa, aj, ak, ajm, ajp, akm, akp;
REAL s1, s2, s3, sd, bb, bj, bk, bjm, bjp, bkm, bkp;
REAL *Rtmp = NULL; /* temp space for real part*/
REAL *Itmp = NULL; /* temp space for imaginary part */
REAL *Cos = NULL; /* Cosine values */
REAL *Sin = NULL; /* Sine values */
REAL s60 = SIN60; /* sin(60 deg) */
REAL c72 = COS72; /* cos(72 deg) */
REAL s72 = SIN72; /* sin(72 deg) */
REAL pi2 = M_PI; /* use PI first, 2 PI later */
fftstate->SpaceAlloced = 0;
fftstate->MaxPermAlloced = 0;
// initialize to avoid warnings
k3 = c2 = c3 = s2 = s3 = 0.0;
if (nPass < 2)
return 0;
/* allocate storage */
if (fftstate->SpaceAlloced < max_factors * sizeof (REAL))
{
#ifdef SUN_BROKEN_REALLOC
if (!fftstate->SpaceAlloced) /* first time */
{
fftstate->SpaceAlloced = max_factors * sizeof (REAL);
}
else
{
#endif
fftstate->SpaceAlloced = max_factors * sizeof (REAL);
#ifdef SUN_BROKEN_REALLOC
}
#endif
}
else
{
/* allow full use of alloc'd space */
max_factors = fftstate->SpaceAlloced / sizeof (REAL);
}
if (fftstate->MaxPermAlloced < max_perm)
{
#ifdef SUN_BROKEN_REALLOC
if (!fftstate->MaxPermAlloced) /* first time */
else
#endif
fftstate->MaxPermAlloced = max_perm;
}
else
{
/* allow full use of alloc'd space */
max_perm = fftstate->MaxPermAlloced;
}
/* assign pointers */
Rtmp = (REAL *) fftstate->Tmp0;
Itmp = (REAL *) fftstate->Tmp1;
Cos = (REAL *) fftstate->Tmp2;
Sin = (REAL *) fftstate->Tmp3;
/*
* Function Body
*/
inc = iSign;
if (iSign < 0) {
s72 = -s72;
s60 = -s60;
pi2 = -pi2;
inc = -inc; /* absolute value */
}
/* adjust for strange increments */
nt = inc * (int)nTotal;
ns = inc * (int)nSpan;
kspan = ns;
nn = nt - inc;
jc = ns / (int)nPass;
radf = pi2 * (double) jc;
pi2 *= 2.0; /* use 2 PI from here on */
ii = 0;
jf = 0;
/* determine the factors of n */
mfactor = 0;
k = (int)nPass;
while (k % 16 == 0) {
mfactor++;
fftstate->factor [mfactor - 1] = 4;
k /= 16;
}
j = 3;
jj = 9;
do {
while (k % jj == 0) {
mfactor++;
fftstate->factor [mfactor - 1] = j;
k /= jj;
}
j += 2;
jj = j * j;
} while (jj <= k);
if (k <= 4) {
kt = mfactor;
fftstate->factor [mfactor] = k;
if (k != 1)
mfactor++;
} else {
if (k - (k / 4 << 2) == 0) {
mfactor++;
fftstate->factor [mfactor - 1] = 2;
k /= 4;
}
kt = mfactor;
j = 2;
do {
if (k % j == 0) {
mfactor++;
fftstate->factor [mfactor - 1] = j;
k /= j;
}
j = ((j + 1) / 2 << 1) + 1;
} while (j <= k);
}
if (kt) {
j = kt;
do {
mfactor++;
fftstate->factor [mfactor - 1] = fftstate->factor [j - 1];
j--;
} while (j);
}
/* test that mfactors is in range */
if (mfactor > NFACTOR)
{
return -1;
}
/* compute fourier transform */
for (;;) {
sd = radf / (double) kspan;
cd = sin(sd);
cd = 2.0 * cd * cd;
sd = sin(sd + sd);
kk = 0;
ii++;
switch (fftstate->factor [ii - 1]) {
case 2:
/* transform for factor of 2 (including rotation factor) */
kspan /= 2;
k1 = kspan + 2;
do {
do {
k2 = kk + kspan;
ak = Re [k2];
bk = Im [k2];
Re [k2] = Re [kk] - ak;
Im [k2] = Im [kk] - bk;
Re [kk] += ak;
Im [kk] += bk;
kk = k2 + kspan;
} while (kk < nn);
kk -= nn;
} while (kk < jc);
if (kk >= kspan)
goto Permute_Results_Label; /* exit infinite loop */
do {
c1 = 1.0 - cd;
s1 = sd;
do {
do {
do {
k2 = kk + kspan;
ak = Re [kk] - Re [k2];
bk = Im [kk] - Im [k2];
Re [kk] += Re [k2];
Im [kk] += Im [k2];
Re [k2] = c1 * ak - s1 * bk;
Im [k2] = s1 * ak + c1 * bk;
kk = k2 + kspan;
} while (kk < (nt-1));
k2 = kk - nt;
c1 = -c1;
kk = k1 - k2;
} while (kk > k2);
ak = c1 - (cd * c1 + sd * s1);
s1 = sd * c1 - cd * s1 + s1;
c1 = 2.0 - (ak * ak + s1 * s1);
s1 *= c1;
c1 *= ak;
kk += jc;
} while (kk < k2);
k1 += inc + inc;
kk = (k1 - kspan + 1) / 2 + jc - 1;
} while (kk < (jc + jc));
break;
case 4: /* transform for factor of 4 */
ispan = kspan;
kspan /= 4;
do {
c1 = 1.0;
s1 = 0.0;
do {
do {
k1 = kk + kspan;
k2 = k1 + kspan;
k3 = k2 + kspan;
akp = Re [kk] + Re [k2];
akm = Re [kk] - Re [k2];
ajp = Re [k1] + Re [k3];
ajm = Re [k1] - Re [k3];
bkp = Im [kk] + Im [k2];
bkm = Im [kk] - Im [k2];
bjp = Im [k1] + Im [k3];
bjm = Im [k1] - Im [k3];
Re [kk] = akp + ajp;
Im [kk] = bkp + bjp;
ajp = akp - ajp;
bjp = bkp - bjp;
if (iSign < 0) {
akp = akm + bjm;
bkp = bkm - ajm;
akm -= bjm;
bkm += ajm;
} else {
akp = akm - bjm;
bkp = bkm + ajm;
akm += bjm;
bkm -= ajm;
}
/* avoid useless multiplies */
if (s1 == 0.0) {
Re [k1] = akp;
Re [k2] = ajp;
Re [k3] = akm;
Im [k1] = bkp;
Im [k2] = bjp;
Im [k3] = bkm;
} else {
Re [k1] = akp * c1 - bkp * s1;
Re [k2] = ajp * c2 - bjp * s2;
Re [k3] = akm * c3 - bkm * s3;
Im [k1] = akp * s1 + bkp * c1;
Im [k2] = ajp * s2 + bjp * c2;
Im [k3] = akm * s3 + bkm * c3;
}
kk = k3 + kspan;
} while (kk < nt);
c2 = c1 - (cd * c1 + sd * s1);
s1 = sd * c1 - cd * s1 + s1;
c1 = 2.0 - (c2 * c2 + s1 * s1);
s1 *= c1;
c1 *= c2;
/* values of c2, c3, s2, s3 that will get used next time */
c2 = c1 * c1 - s1 * s1;
s2 = 2.0 * c1 * s1;
c3 = c2 * c1 - s2 * s1;
s3 = c2 * s1 + s2 * c1;
kk = kk - nt + jc;
} while (kk < kspan);
kk = kk - kspan + inc;
} while (kk < jc);
if (kspan == jc)
goto Permute_Results_Label; /* exit infinite loop */
break;
default:
/* transform for odd factors */
#ifdef FFT_RADIX4
return -1;
break;
#else /* FFT_RADIX4 */
k = fftstate->factor [ii - 1];
ispan = kspan;
kspan /= k;
switch (k) {
case 3: /* transform for factor of 3 (optional code) */
do {
do {
k1 = kk + kspan;
k2 = k1 + kspan;
ak = Re [kk];
bk = Im [kk];
aj = Re [k1] + Re [k2];
bj = Im [k1] + Im [k2];
Re [kk] = ak + aj;
Im [kk] = bk + bj;
ak -= 0.5 * aj;
bk -= 0.5 * bj;
aj = (Re [k1] - Re [k2]) * s60;
bj = (Im [k1] - Im [k2]) * s60;
Re [k1] = ak - bj;
Re [k2] = ak + bj;
Im [k1] = bk + aj;
Im [k2] = bk - aj;
kk = k2 + kspan;
} while (kk < (nn - 1));
kk -= nn;
} while (kk < kspan);
break;
case 5: /* transform for factor of 5 (optional code) */
c2 = c72 * c72 - s72 * s72;
s2 = 2.0 * c72 * s72;
do {
do {
k1 = kk + kspan;
k2 = k1 + kspan;
k3 = k2 + kspan;
k4 = k3 + kspan;
akp = Re [k1] + Re [k4];
akm = Re [k1] - Re [k4];
bkp = Im [k1] + Im [k4];
bkm = Im [k1] - Im [k4];
ajp = Re [k2] + Re [k3];
ajm = Re [k2] - Re [k3];
bjp = Im [k2] + Im [k3];
bjm = Im [k2] - Im [k3];
aa = Re [kk];
bb = Im [kk];
Re [kk] = aa + akp + ajp;
Im [kk] = bb + bkp + bjp;
ak = akp * c72 + ajp * c2 + aa;
bk = bkp * c72 + bjp * c2 + bb;
aj = akm * s72 + ajm * s2;
bj = bkm * s72 + bjm * s2;
Re [k1] = ak - bj;
Re [k4] = ak + bj;
Im [k1] = bk + aj;
Im [k4] = bk - aj;
ak = akp * c2 + ajp * c72 + aa;
bk = bkp * c2 + bjp * c72 + bb;
aj = akm * s2 - ajm * s72;
bj = bkm * s2 - bjm * s72;
Re [k2] = ak - bj;
Re [k3] = ak + bj;
Im [k2] = bk + aj;
Im [k3] = bk - aj;
kk = k4 + kspan;
} while (kk < (nn-1));
kk -= nn;
} while (kk < kspan);
break;
default:
if (k != jf) {
jf = k;
s1 = pi2 / (double) k;
c1 = cos(s1);
s1 = sin(s1);
if (jf > max_factors){
return -1;
}
Cos [jf - 1] = 1.0;
Sin [jf - 1] = 0.0;
j = 1;
do {
Cos [j - 1] = Cos [k - 1] * c1 + Sin [k - 1] * s1;
Sin [j - 1] = Cos [k - 1] * s1 - Sin [k - 1] * c1;
k--;
Cos [k - 1] = Cos [j - 1];
Sin [k - 1] = -Sin [j - 1];
j++;
} while (j < k);
}
do {
do {
k1 = kk;
k2 = kk + ispan;
ak = aa = Re [kk];
bk = bb = Im [kk];
j = 1;
k1 += kspan;
do {
k2 -= kspan;
j++;
Rtmp [j - 1] = Re [k1] + Re [k2];
ak += Rtmp [j - 1];
Itmp [j - 1] = Im [k1] + Im [k2];
bk += Itmp [j - 1];
j++;
Rtmp [j - 1] = Re [k1] - Re [k2];
Itmp [j - 1] = Im [k1] - Im [k2];
k1 += kspan;
} while (k1 < k2);
Re [kk] = ak;
Im [kk] = bk;
k1 = kk;
k2 = kk + ispan;
j = 1;
do {
k1 += kspan;
k2 -= kspan;
jj = j;
ak = aa;
bk = bb;
aj = 0.0;
bj = 0.0;
k = 1;
do {
k++;
ak += Rtmp [k - 1] * Cos [jj - 1];
bk += Itmp [k - 1] * Cos [jj - 1];
k++;
aj += Rtmp [k - 1] * Sin [jj - 1];
bj += Itmp [k - 1] * Sin [jj - 1];
jj += j;
if (jj > jf) {
jj -= jf;
}
} while (k < jf);
k = jf - j;
Re [k1] = ak - bj;
Im [k1] = bk + aj;
Re [k2] = ak + bj;
Im [k2] = bk - aj;
j++;
} while (j < k);
kk += ispan;
} while (kk < nn);
kk -= nn;
} while (kk < kspan);
break;
}
/* multiply by rotation factor (except for factors of 2 and 4) */
if (ii == mfactor)
goto Permute_Results_Label; /* exit infinite loop */
kk = jc;
do {
c2 = 1.0 - cd;
s1 = sd;
do {
c1 = c2;
s2 = s1;
kk += kspan;
do {
do {
ak = Re [kk];
Re [kk] = c2 * ak - s2 * Im [kk];
Im [kk] = s2 * ak + c2 * Im [kk];
kk += ispan;
} while (kk < nt);
ak = s1 * s2;
s2 = s1 * c2 + c1 * s2;
c2 = c1 * c2 - ak;
kk = kk - nt + kspan;
} while (kk < ispan);
c2 = c1 - (cd * c1 + sd * s1);
s1 += sd * c1 - cd * s1;
c1 = 2.0 - (c2 * c2 + s1 * s1);
s1 *= c1;
c2 *= c1;
kk = kk - ispan + jc;
} while (kk < kspan);
kk = kk - kspan + jc + inc;
} while (kk < (jc + jc));
break;
#endif /* FFT_RADIX4 */
}
}
/* permute the results to normal order---done in two stages */
/* permutation for square factors of n */
Permute_Results_Label:
fftstate->Perm [0] = ns;
if (kt) {
k = kt + kt + 1;
if (mfactor < k)
k--;
j = 1;
fftstate->Perm [k] = jc;
do {
fftstate->Perm [j] = fftstate->Perm [j - 1] / fftstate->factor [j - 1];
fftstate->Perm [k - 1] = fftstate->Perm [k] * fftstate->factor [j - 1];
j++;
k--;
} while (j < k);
k3 = fftstate->Perm [k];
kspan = fftstate->Perm [1];
kk = jc;
k2 = kspan;
j = 1;
if (nPass != nTotal) {
/* permutation for multivariate transform */
Permute_Multi_Label:
do {
do {
k = kk + jc;
do {
/* swap Re [kk] <> Re [k2], Im [kk] <> Im [k2] */
ak = Re [kk]; Re [kk] = Re [k2]; Re [k2] = ak;
bk = Im [kk]; Im [kk] = Im [k2]; Im [k2] = bk;
kk += inc;
k2 += inc;
} while (kk < (k-1));
kk += ns - jc;
k2 += ns - jc;
} while (kk < (nt-1));
k2 = k2 - nt + kspan;
kk = kk - nt + jc;
} while (k2 < (ns-1));
do {
do {
k2 -= fftstate->Perm [j - 1];
j++;
k2 = fftstate->Perm [j] + k2;
} while (k2 > fftstate->Perm [j - 1]);
j = 1;
do {
if (kk < (k2-1))
goto Permute_Multi_Label;
kk += jc;
k2 += kspan;
} while (k2 < (ns-1));
} while (kk < (ns-1));
} else {
/* permutation for single-variate transform (optional code) */
Permute_Single_Label:
do {
/* swap Re [kk] <> Re [k2], Im [kk] <> Im [k2] */
ak = Re [kk]; Re [kk] = Re [k2]; Re [k2] = ak;
bk = Im [kk]; Im [kk] = Im [k2]; Im [k2] = bk;
kk += inc;
k2 += kspan;
} while (k2 < (ns-1));
do {
do {
k2 -= fftstate->Perm [j - 1];
j++;
k2 = fftstate->Perm [j] + k2;
} while (k2 >= fftstate->Perm [j - 1]);
j = 1;
do {
if (kk < k2)
goto Permute_Single_Label;
kk += inc;
k2 += kspan;
} while (k2 < (ns-1));
} while (kk < (ns-1));
}
jc = k3;
}
if ((kt << 1) + 1 >= mfactor)
return 0;
ispan = fftstate->Perm [kt];
/* permutation for square-free factors of n */
j = mfactor - kt;
fftstate->factor [j] = 1;
do {
fftstate->factor [j - 1] *= fftstate->factor [j];
j--;
} while (j != kt);
kt++;
nn = fftstate->factor [kt - 1] - 1;
if (nn > (int) max_perm) {
return -1;
}
j = jj = 0;
for (;;) {
k = kt + 1;
k2 = fftstate->factor [kt - 1];
kk = fftstate->factor [k - 1];
j++;
if (j > nn)
break; /* exit infinite loop */
jj += kk;
while (jj >= k2) {
jj -= k2;
k2 = kk;
k++;
kk = fftstate->factor [k - 1];
jj += kk;
}
fftstate->Perm [j - 1] = jj;
}
/* determine the permutation cycles of length greater than 1 */
j = 0;
for (;;) {
do {
j++;
kk = fftstate->Perm [j - 1];
} while (kk < 0);
if (kk != j) {
do {
k = kk;
kk = fftstate->Perm [k - 1];
fftstate->Perm [k - 1] = -kk;
} while (kk != j);
k3 = kk;
} else {
fftstate->Perm [j - 1] = -j;
if (j == nn)
break; /* exit infinite loop */
}
}
max_factors *= inc;
/* reorder a and b, following the permutation cycles */
for (;;) {
j = k3 + 1;
nt -= ispan;
ii = nt - inc + 1;
if (nt < 0)
break; /* exit infinite loop */
do {
do {
j--;
} while (fftstate->Perm [j - 1] < 0);
jj = jc;
do {
kspan = jj;
if (jj > max_factors) {
kspan = max_factors;
}
jj -= kspan;
k = fftstate->Perm [j - 1];
kk = jc * k + ii + jj;
k1 = kk + kspan - 1;
k2 = 0;
do {
k2++;
Rtmp [k2 - 1] = Re [k1];
Itmp [k2 - 1] = Im [k1];
k1 -= inc;
} while (k1 != (kk-1));
do {
k1 = kk + kspan - 1;
k2 = k1 - jc * (k + fftstate->Perm [k - 1]);
k = -fftstate->Perm [k - 1];
do {
Re [k1] = Re [k2];
Im [k1] = Im [k2];
k1 -= inc;
k2 -= inc;
} while (k1 != (kk-1));
kk = k2 + 1;
} while (k != j);
k1 = kk + kspan - 1;
k2 = 0;
do {
k2++;
Re [k1] = Rtmp [k2 - 1];
Im [k1] = Itmp [k2 - 1];
k1 -= inc;
} while (k1 != (kk-1));
} while (jj);
} while (j != 1);
}
return 0; /* exit point here */
}
/* ---------------------- end-of-file (c source) ---------------------- */

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
/*--------------------------------*-C-*---------------------------------*
* File:
* fftn.h
* ---------------------------------------------------------------------*
* Re[]: real value array
* Im[]: imaginary value array
* nTotal: total number of complex values
* nPass: number of elements involved in this pass of transform
* nSpan: nspan/nPass = number of bytes to increment pointer
* in Re[] and Im[]
* isign: exponent: +1 = forward -1 = reverse
* scaling: normalizing constant by which the final result is *divided*
* scaling == -1, normalize by total dimension of the transform
* scaling < -1, normalize by the square-root of the total dimension
*
* ----------------------------------------------------------------------
* See the comments in the code for correct usage!
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_
#include "structs.h"
/* double precision routine */
int WebRtcIsac_Fftns (unsigned int ndim, const int dims[], double Re[], double Im[],
int isign, double scaling, FFTstr *fftstate);
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_ */

View File

@@ -0,0 +1,271 @@
/*
* 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 <memory.h>
#ifdef WEBRTC_ANDROID
#include <stdlib.h>
#endif
#include "pitch_estimator.h"
#include "lpc_analysis.h"
#include "codec.h"
void WebRtcIsac_AllPoleFilter(double *InOut, double *Coef, int lengthInOut, int orderCoef){
/* the state of filter is assumed to be in InOut[-1] to InOut[-orderCoef] */
double scal;
double sum;
int n,k;
//if (fabs(Coef[0]-1.0)<0.001) {
if ( (Coef[0] > 0.9999) && (Coef[0] < 1.0001) )
{
for(n = 0; n < lengthInOut; n++)
{
sum = Coef[1] * InOut[-1];
for(k = 2; k <= orderCoef; k++){
sum += Coef[k] * InOut[-k];
}
*InOut++ -= sum;
}
}
else
{
scal = 1.0 / Coef[0];
for(n=0;n<lengthInOut;n++)
{
*InOut *= scal;
for(k=1;k<=orderCoef;k++){
*InOut -= scal*Coef[k]*InOut[-k];
}
InOut++;
}
}
}
void WebRtcIsac_AllZeroFilter(double *In, double *Coef, int lengthInOut, int orderCoef, double *Out){
/* the state of filter is assumed to be in In[-1] to In[-orderCoef] */
int n, k;
double tmp;
for(n = 0; n < lengthInOut; n++)
{
tmp = In[0] * Coef[0];
for(k = 1; k <= orderCoef; k++){
tmp += Coef[k] * In[-k];
}
*Out++ = tmp;
In++;
}
}
void WebRtcIsac_ZeroPoleFilter(double *In, double *ZeroCoef, double *PoleCoef, int lengthInOut, int orderCoef, double *Out){
/* the state of the zero section is assumed to be in In[-1] to In[-orderCoef] */
/* the state of the pole section is assumed to be in Out[-1] to Out[-orderCoef] */
WebRtcIsac_AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out);
WebRtcIsac_AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef);
}
void WebRtcIsac_AutoCorr(
double *r,
const double *x,
int N,
int order
)
{
int lag, n;
double sum, prod;
const double *x_lag;
for (lag = 0; lag <= order; lag++)
{
sum = 0.0f;
x_lag = &x[lag];
prod = x[0] * x_lag[0];
for (n = 1; n < N - lag; n++) {
sum += prod;
prod = x[n] * x_lag[n];
}
sum += prod;
r[lag] = sum;
}
}
void WebRtcIsac_BwExpand(double *out, double *in, double coef, short length) {
int i;
double chirp;
chirp = coef;
out[0] = in[0];
for (i = 1; i < length; i++) {
out[i] = chirp * in[i];
chirp *= coef;
}
}
void WebRtcIsac_WeightingFilter(const double *in, double *weiout, double *whiout, WeightFiltstr *wfdata) {
double tmpbuffer[PITCH_FRAME_LEN + PITCH_WLPCBUFLEN];
double corr[PITCH_WLPCORDER+1], rc[PITCH_WLPCORDER+1];
double apol[PITCH_WLPCORDER+1], apolr[PITCH_WLPCORDER+1];
double rho=0.9, *inp, *dp, *dp2;
double whoutbuf[PITCH_WLPCBUFLEN + PITCH_WLPCORDER];
double weoutbuf[PITCH_WLPCBUFLEN + PITCH_WLPCORDER];
double *weo, *who, opol[PITCH_WLPCORDER+1], ext[PITCH_WLPCWINLEN];
int k, n, endpos, start;
/* Set up buffer and states */
memcpy(tmpbuffer, wfdata->buffer, sizeof(double) * PITCH_WLPCBUFLEN);
memcpy(tmpbuffer+PITCH_WLPCBUFLEN, in, sizeof(double) * PITCH_FRAME_LEN);
memcpy(wfdata->buffer, tmpbuffer+PITCH_FRAME_LEN, sizeof(double) * PITCH_WLPCBUFLEN);
dp=weoutbuf;
dp2=whoutbuf;
for (k=0;k<PITCH_WLPCORDER;k++) {
*dp++ = wfdata->weostate[k];
*dp2++ = wfdata->whostate[k];
opol[k]=0.0;
}
opol[0]=1.0;
opol[PITCH_WLPCORDER]=0.0;
weo=dp;
who=dp2;
endpos=PITCH_WLPCBUFLEN + PITCH_SUBFRAME_LEN;
inp=tmpbuffer + PITCH_WLPCBUFLEN;
for (n=0; n<PITCH_SUBFRAMES; n++) {
/* Windowing */
start=endpos-PITCH_WLPCWINLEN;
for (k=0; k<PITCH_WLPCWINLEN; k++) {
ext[k]=wfdata->window[k]*tmpbuffer[start+k];
}
/* Get LPC polynomial */
WebRtcIsac_AutoCorr(corr, ext, PITCH_WLPCWINLEN, PITCH_WLPCORDER);
corr[0]=1.01*corr[0]+1.0; /* White noise correction */
WebRtcIsac_LevDurb(apol, rc, corr, PITCH_WLPCORDER);
WebRtcIsac_BwExpand(apolr, apol, rho, PITCH_WLPCORDER+1);
/* Filtering */
WebRtcIsac_ZeroPoleFilter(inp, apol, apolr, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, weo);
WebRtcIsac_ZeroPoleFilter(inp, apolr, opol, PITCH_SUBFRAME_LEN, PITCH_WLPCORDER, who);
inp+=PITCH_SUBFRAME_LEN;
endpos+=PITCH_SUBFRAME_LEN;
weo+=PITCH_SUBFRAME_LEN;
who+=PITCH_SUBFRAME_LEN;
}
/* Export filter states */
for (k=0;k<PITCH_WLPCORDER;k++) {
wfdata->weostate[k]=weoutbuf[PITCH_FRAME_LEN+k];
wfdata->whostate[k]=whoutbuf[PITCH_FRAME_LEN+k];
}
/* Export output data */
memcpy(weiout, weoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN);
memcpy(whiout, whoutbuf+PITCH_WLPCORDER, sizeof(double) * PITCH_FRAME_LEN);
}
static const double APupper[ALLPASSSECTIONS] = {0.0347, 0.3826};
static const double APlower[ALLPASSSECTIONS] = {0.1544, 0.744};
void WebRtcIsac_AllpassFilterForDec(double *InOut,
const double *APSectionFactors,
int lengthInOut,
double *FilterState)
{
//This performs all-pass filtering--a series of first order all-pass sections are used
//to filter the input in a cascade manner.
int n,j;
double temp;
for (j=0; j<ALLPASSSECTIONS; j++){
for (n=0;n<lengthInOut;n+=2){
temp = InOut[n]; //store input
InOut[n] = FilterState[j] + APSectionFactors[j]*temp;
FilterState[j] = -APSectionFactors[j]*InOut[n] + temp;
}
}
}
void WebRtcIsac_DecimateAllpass(const double *in,
double *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */
int N, /* number of input samples */
double *out) /* array of size N/2 */
{
int n;
double data_vec[PITCH_FRAME_LEN];
/* copy input */
memcpy(data_vec+1, in, sizeof(double) * (N-1));
data_vec[0] = state_in[2*ALLPASSSECTIONS]; //the z^(-1) state
state_in[2*ALLPASSSECTIONS] = in[N-1];
WebRtcIsac_AllpassFilterForDec(data_vec+1, APupper, N, state_in);
WebRtcIsac_AllpassFilterForDec(data_vec, APlower, N, state_in+ALLPASSSECTIONS);
for (n=0;n<N/2;n++)
out[n] = data_vec[2*n] + data_vec[2*n+1];
}
/* create high-pass filter ocefficients
* z = 0.998 * exp(j*2*pi*35/8000);
* p = 0.94 * exp(j*2*pi*140/8000);
* HP_b = [1, -2*real(z), abs(z)^2];
* HP_a = [1, -2*real(p), abs(p)^2]; */
static const double a_coef[2] = { 1.86864659625574, -0.88360000000000};
static const double b_coef[2] = {-1.99524591718270, 0.99600400000000};
static const float a_coef_float[2] = { 1.86864659625574f, -0.88360000000000f};
static const float b_coef_float[2] = {-1.99524591718270f, 0.99600400000000f};
/* second order high-pass filter */
void WebRtcIsac_Highpass(const double *in, double *out, double *state, int N)
{
int k;
for (k=0; k<N; k++) {
*out = *in + state[1];
state[1] = state[0] + b_coef[0] * *in + a_coef[0] * *out;
state[0] = b_coef[1] * *in++ + a_coef[1] * *out++;
}
}
void WebRtcIsac_Highpass_float(const float *in, double *out, double *state, int N)
{
int k;
for (k=0; k<N; k++) {
*out = (double)*in + state[1];
state[1] = state[0] + b_coef_float[0] * *in + a_coef_float[0] * *out;
state[0] = b_coef_float[1] * (double)*in++ + a_coef_float[1] * *out++;
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
/* filterbank_tables.c*/
/* This file contains variables that are used in filterbanks.c*/
#include "filterbank_tables.h"
#include "settings.h"
/* The composite all-pass filter factors */
const float WebRtcIsac_kCompositeApFactorsFloat[4] = {
0.03470000000000f, 0.15440000000000f, 0.38260000000000f, 0.74400000000000f};
/* The upper channel all-pass filter factors */
const float WebRtcIsac_kUpperApFactorsFloat[2] = {
0.03470000000000f, 0.38260000000000f};
/* The lower channel all-pass filter factors */
const float WebRtcIsac_kLowerApFactorsFloat[2] = {
0.15440000000000f, 0.74400000000000f};
/* The matrix for transforming the backward composite state to upper channel state */
const float WebRtcIsac_kTransform1Float[8] = {
-0.00158678506084f, 0.00127157815343f, -0.00104805672709f, 0.00084837248079f,
0.00134467983258f, -0.00107756549387f, 0.00088814793277f, -0.00071893072525f};
/* The matrix for transforming the backward composite state to lower channel state */
const float WebRtcIsac_kTransform2Float[8] = {
-0.00170686041697f, 0.00136780109829f, -0.00112736532350f, 0.00091257055385f,
0.00103094281812f, -0.00082615076557f, 0.00068092756088f, -0.00055119165484f};

View File

@@ -0,0 +1,46 @@
/*
* 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.
*/
/*
* filterbank_tables.h
*
* Header file for variables that are defined in
* filterbank_tables.c.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_
#include "structs.h"
/********************* Coefficient Tables ************************/
/* The number of composite all-pass filter factors */
#define NUMBEROFCOMPOSITEAPSECTIONS 4
/* The number of all-pass filter factors in an upper or lower channel*/
#define NUMBEROFCHANNELAPSECTIONS 2
/* The composite all-pass filter factors */
extern const float WebRtcIsac_kCompositeApFactorsFloat[4];
/* The upper channel all-pass filter factors */
extern const float WebRtcIsac_kUpperApFactorsFloat[2];
/* The lower channel all-pass filter factors */
extern const float WebRtcIsac_kLowerApFactorsFloat[2];
/* The matrix for transforming the backward composite state to upper channel state */
extern const float WebRtcIsac_kTransform1Float[8];
/* The matrix for transforming the backward composite state to lower channel state */
extern const float WebRtcIsac_kTransform2Float[8];
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FILTERBANK_TABLES_H_ */

View File

@@ -0,0 +1,346 @@
/*
* 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.
*/
/*
* filterbanks.c
*
* This file contains function WebRtcIsac_AllPassFilter2Float,
* WebRtcIsac_SplitAndFilter, and WebRtcIsac_FilterAndCombine
* which implement filterbanks that produce decimated lowpass and
* highpass versions of a signal, and performs reconstruction.
*
*/
#include "settings.h"
#include "filterbank_tables.h"
#include "codec.h"
/* This function performs all-pass filtering--a series of first order all-pass
* sections are used to filter the input in a cascade manner.
* The input is overwritten!!
*/
static void WebRtcIsac_AllPassFilter2Float(float *InOut, const float *APSectionFactors,
int lengthInOut, int NumberOfSections,
float *FilterState)
{
int n, j;
float temp;
for (j=0; j<NumberOfSections; j++){
for (n=0;n<lengthInOut;n++){
temp = FilterState[j] + APSectionFactors[j] * InOut[n];
FilterState[j] = -APSectionFactors[j] * temp + InOut[n];
InOut[n] = temp;
}
}
}
/* HPstcoeff_in = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
static const float kHpStCoefInFloat[4] =
{-1.94895953203325f, 0.94984516000000f, -0.05101826139794f, 0.05015484000000f};
/* Function WebRtcIsac_SplitAndFilter
* This function creates low-pass and high-pass decimated versions of part of
the input signal, and part of the signal in the input 'lookahead buffer'.
INPUTS:
in: a length FRAMESAMPLES array of input samples
prefiltdata: input data structure containing the filterbank states
and lookahead samples from the previous encoding
iteration.
OUTPUTS:
LP: a FRAMESAMPLES_HALF array of low-pass filtered samples that
have been phase equalized. The first QLOOKAHEAD samples are
based on the samples in the two prefiltdata->INLABUFx arrays
each of length QLOOKAHEAD.
The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
array in[].
HP: a FRAMESAMPLES_HALF array of high-pass filtered samples that
have been phase equalized. The first QLOOKAHEAD samples are
based on the samples in the two prefiltdata->INLABUFx arrays
each of length QLOOKAHEAD.
The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
array in[].
LP_la: a FRAMESAMPLES_HALF array of low-pass filtered samples.
These samples are not phase equalized. They are computed
from the samples in the in[] array.
HP_la: a FRAMESAMPLES_HALF array of high-pass filtered samples
that are not phase equalized. They are computed from
the in[] vector.
prefiltdata: this input data structure's filterbank state and
lookahead sample buffers are updated for the next
encoding iteration.
*/
void WebRtcIsac_SplitAndFilterFloat(float *pin, float *LP, float *HP,
double *LP_la, double *HP_la,
PreFiltBankstr *prefiltdata)
{
int k,n;
float CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
float ForTransform_CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
float ForTransform_CompositeAPFilterState2[NUMBEROFCOMPOSITEAPSECTIONS];
float tempinoutvec[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
float in[FRAMESAMPLES];
float ftmp;
/* High pass filter */
for (k=0;k<FRAMESAMPLES;k++) {
in[k] = pin[k] + kHpStCoefInFloat[2] * prefiltdata->HPstates_float[0] +
kHpStCoefInFloat[3] * prefiltdata->HPstates_float[1];
ftmp = pin[k] - kHpStCoefInFloat[0] * prefiltdata->HPstates_float[0] -
kHpStCoefInFloat[1] * prefiltdata->HPstates_float[1];
prefiltdata->HPstates_float[1] = prefiltdata->HPstates_float[0];
prefiltdata->HPstates_float[0] = ftmp;
}
/*
% backwards all-pass filtering to obtain zero-phase
[tmp1(N2+LA:-1:LA+1, 1), state1] = filter(Q.coef, Q.coef(end:-1:1), in(N:-2:2));
tmp1(LA:-1:1) = filter(Q.coef, Q.coef(end:-1:1), Q.LookAheadBuf1, state1);
Q.LookAheadBuf1 = in(N:-2:N-2*LA+2);
*/
/*Backwards all-pass filter the odd samples of the input (upper channel)
to eventually obtain zero phase. The composite all-pass filter (comprised of both
the upper and lower channel all-pass filsters in series) is used for the
filtering. */
/* First Channel */
/*initial state of composite filter is zero */
for (k=0;k<NUMBEROFCOMPOSITEAPSECTIONS;k++){
CompositeAPFilterState[k] = 0.0;
}
/* put every other sample of input into a temporary vector in reverse (backward) order*/
for (k=0;k<FRAMESAMPLES_HALF;k++) {
tempinoutvec[k] = in[FRAMESAMPLES-1-2*k];
}
/* now all-pass filter the backwards vector. Output values overwrite the input vector. */
WebRtcIsac_AllPassFilter2Float(tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
/* save the backwards filtered output for later forward filtering,
but write it in forward order*/
for (k=0;k<FRAMESAMPLES_HALF;k++) {
tempin_ch1[FRAMESAMPLES_HALF+QLOOKAHEAD-1-k] = tempinoutvec[k];
}
/* save the backwards filter state becaue it will be transformed
later into a forward state */
for (k=0; k<NUMBEROFCOMPOSITEAPSECTIONS; k++) {
ForTransform_CompositeAPFilterState[k] = CompositeAPFilterState[k];
}
/* now backwards filter the samples in the lookahead buffer. The samples were
placed there in the encoding of the previous frame. The output samples
overwrite the input samples */
WebRtcIsac_AllPassFilter2Float(prefiltdata->INLABUF1_float,
WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,
NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
/* save the output, but write it in forward order */
/* write the lookahead samples for the next encoding iteration. Every other
sample at the end of the input frame is written in reverse order for the
lookahead length. Exported in the prefiltdata structure. */
for (k=0;k<QLOOKAHEAD;k++) {
tempin_ch1[QLOOKAHEAD-1-k]=prefiltdata->INLABUF1_float[k];
prefiltdata->INLABUF1_float[k]=in[FRAMESAMPLES-1-2*k];
}
/* Second Channel. This is exactly like the first channel, except that the
even samples are now filtered instead (lower channel). */
for (k=0;k<NUMBEROFCOMPOSITEAPSECTIONS;k++){
CompositeAPFilterState[k] = 0.0;
}
for (k=0;k<FRAMESAMPLES_HALF;k++) {
tempinoutvec[k] = in[FRAMESAMPLES-2-2*k];
}
WebRtcIsac_AllPassFilter2Float(tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
for (k=0;k<FRAMESAMPLES_HALF;k++) {
tempin_ch2[FRAMESAMPLES_HALF+QLOOKAHEAD-1-k] = tempinoutvec[k];
}
for (k=0; k<NUMBEROFCOMPOSITEAPSECTIONS; k++) {
ForTransform_CompositeAPFilterState2[k] = CompositeAPFilterState[k];
}
WebRtcIsac_AllPassFilter2Float(prefiltdata->INLABUF2_float,
WebRtcIsac_kCompositeApFactorsFloat, QLOOKAHEAD,NUMBEROFCOMPOSITEAPSECTIONS,
CompositeAPFilterState);
for (k=0;k<QLOOKAHEAD;k++) {
tempin_ch2[QLOOKAHEAD-1-k]=prefiltdata->INLABUF2_float[k];
prefiltdata->INLABUF2_float[k]=in[FRAMESAMPLES-2-2*k];
}
/* Transform filter states from backward to forward */
/*At this point, each of the states of the backwards composite filters for the
two channels are transformed into forward filtering states for the corresponding
forward channel filters. Each channel's forward filtering state from the previous
encoding iteration is added to the transformed state to get a proper forward state */
/* So the existing NUMBEROFCOMPOSITEAPSECTIONS x 1 (4x1) state vector is multiplied by a
NUMBEROFCHANNELAPSECTIONSxNUMBEROFCOMPOSITEAPSECTIONS (2x4) transform matrix to get the
new state that is added to the previous 2x1 input state */
for (k=0;k<NUMBEROFCHANNELAPSECTIONS;k++){ /* k is row variable */
for (n=0; n<NUMBEROFCOMPOSITEAPSECTIONS;n++){/* n is column variable */
prefiltdata->INSTAT1_float[k] += ForTransform_CompositeAPFilterState[n]*
WebRtcIsac_kTransform1Float[k*NUMBEROFCHANNELAPSECTIONS+n];
prefiltdata->INSTAT2_float[k] += ForTransform_CompositeAPFilterState2[n]*
WebRtcIsac_kTransform2Float[k*NUMBEROFCHANNELAPSECTIONS+n];
}
}
/*obtain polyphase components by forward all-pass filtering through each channel */
/* the backward filtered samples are now forward filtered with the corresponding channel filters */
/* The all pass filtering automatically updates the filter states which are exported in the
prefiltdata structure */
WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_float);
WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_float);
/* Now Construct low-pass and high-pass signals as combinations of polyphase components */
for (k=0; k<FRAMESAMPLES_HALF; k++) {
LP[k] = 0.5f*(tempin_ch1[k] + tempin_ch2[k]);/* low pass signal*/
HP[k] = 0.5f*(tempin_ch1[k] - tempin_ch2[k]);/* high pass signal*/
}
/* Lookahead LP and HP signals */
/* now create low pass and high pass signals of the input vector. However, no
backwards filtering is performed, and hence no phase equalization is involved.
Also, the input contains some samples that are lookahead samples. The high pass
and low pass signals that are created are used outside this function for analysis
(not encoding) purposes */
/* set up input */
for (k=0; k<FRAMESAMPLES_HALF; k++) {
tempin_ch1[k]=in[2*k+1];
tempin_ch2[k]=in[2*k];
}
/* the input filter states are passed in and updated by the all-pass filtering routine and
exported in the prefiltdata structure*/
WebRtcIsac_AllPassFilter2Float(tempin_ch1,WebRtcIsac_kUpperApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA1_float);
WebRtcIsac_AllPassFilter2Float(tempin_ch2,WebRtcIsac_kLowerApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTATLA2_float);
for (k=0; k<FRAMESAMPLES_HALF; k++) {
LP_la[k] = (float)(0.5f*(tempin_ch1[k] + tempin_ch2[k])); /*low pass */
HP_la[k] = (double)(0.5f*(tempin_ch1[k] - tempin_ch2[k])); /* high pass */
}
}/*end of WebRtcIsac_SplitAndFilter */
/* Combining */
/* HPstcoeff_out_1 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
static const float kHpStCoefOut1Float[4] =
{-1.99701049409000f, 0.99714204490000f, 0.01701049409000f, -0.01704204490000f};
/* HPstcoeff_out_2 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
static const float kHpStCoefOut2Float[4] =
{-1.98645294509837f, 0.98672435560000f, 0.00645294509837f, -0.00662435560000f};
/* Function WebRtcIsac_FilterAndCombine */
/* This is a decoder function that takes the decimated
length FRAMESAMPLES_HALF input low-pass and
high-pass signals and creates a reconstructed fullband
output signal of length FRAMESAMPLES. WebRtcIsac_FilterAndCombine
is the sibling function of WebRtcIsac_SplitAndFilter */
/* INPUTS:
inLP: a length FRAMESAMPLES_HALF array of input low-pass
samples.
inHP: a length FRAMESAMPLES_HALF array of input high-pass
samples.
postfiltdata: input data structure containing the filterbank
states from the previous decoding iteration.
OUTPUTS:
Out: a length FRAMESAMPLES array of output reconstructed
samples (fullband) based on the input low-pass and
high-pass signals.
postfiltdata: the input data structure containing the filterbank
states is updated for the next decoding iteration */
void WebRtcIsac_FilterAndCombineFloat(float *InLP,
float *InHP,
float *Out,
PostFiltBankstr *postfiltdata)
{
int k;
float tempin_ch1[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
float tempin_ch2[FRAMESAMPLES+MAX_AR_MODEL_ORDER];
float ftmp, ftmp2;
/* Form the polyphase signals*/
for (k=0;k<FRAMESAMPLES_HALF;k++) {
tempin_ch1[k]=InLP[k]+InHP[k]; /* Construct a new upper channel signal*/
tempin_ch2[k]=InLP[k]-InHP[k]; /* Construct a new lower channel signal*/
}
/* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
that were used as a lower channel at the encoding side. So at the decoder, the
corresponding all-pass filter factors for each channel are swapped.*/
WebRtcIsac_AllPassFilter2Float(tempin_ch1, WebRtcIsac_kLowerApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_float);
/* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
at the decoder are swapped from the ones at the encoder, the 'upper' channel
all-pass filter factors (WebRtcIsac_kUpperApFactorsFloat) are used to filter this new
lower channel signal */
WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kUpperApFactorsFloat,
FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_float);
/* Merge outputs to form the full length output signal.*/
for (k=0;k<FRAMESAMPLES_HALF;k++) {
Out[2*k]=tempin_ch2[k];
Out[2*k+1]=tempin_ch1[k];
}
/* High pass filter */
for (k=0;k<FRAMESAMPLES;k++) {
ftmp2 = Out[k] + kHpStCoefOut1Float[2] * postfiltdata->HPstates1_float[0] +
kHpStCoefOut1Float[3] * postfiltdata->HPstates1_float[1];
ftmp = Out[k] - kHpStCoefOut1Float[0] * postfiltdata->HPstates1_float[0] -
kHpStCoefOut1Float[1] * postfiltdata->HPstates1_float[1];
postfiltdata->HPstates1_float[1] = postfiltdata->HPstates1_float[0];
postfiltdata->HPstates1_float[0] = ftmp;
Out[k] = ftmp2;
}
for (k=0;k<FRAMESAMPLES;k++) {
ftmp2 = Out[k] + kHpStCoefOut2Float[2] * postfiltdata->HPstates2_float[0] +
kHpStCoefOut2Float[3] * postfiltdata->HPstates2_float[1];
ftmp = Out[k] - kHpStCoefOut2Float[0] * postfiltdata->HPstates2_float[0] -
kHpStCoefOut2Float[1] * postfiltdata->HPstates2_float[1];
postfiltdata->HPstates2_float[1] = postfiltdata->HPstates2_float[0];
postfiltdata->HPstates2_float[0] = ftmp;
Out[k] = ftmp2;
}
}

View File

@@ -0,0 +1,175 @@
/*
* 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.
*/
/* encode.c - Encoding function for the iSAC coder */
#include "structs.h"
#include "codec.h"
#include "pitch_estimator.h"
#include <math.h>
void WebRtcIsac_InitMasking(MaskFiltstr *maskdata) {
int k;
for (k = 0; k < WINLEN; k++) {
maskdata->DataBufferLo[k] = 0.0;
maskdata->DataBufferHi[k] = 0.0;
}
for (k = 0; k < ORDERLO+1; k++) {
maskdata->CorrBufLo[k] = 0.0;
maskdata->PreStateLoF[k] = 0.0;
maskdata->PreStateLoG[k] = 0.0;
maskdata->PostStateLoF[k] = 0.0;
maskdata->PostStateLoG[k] = 0.0;
}
for (k = 0; k < ORDERHI+1; k++) {
maskdata->CorrBufHi[k] = 0.0;
maskdata->PreStateHiF[k] = 0.0;
maskdata->PreStateHiG[k] = 0.0;
maskdata->PostStateHiF[k] = 0.0;
maskdata->PostStateHiG[k] = 0.0;
}
maskdata->OldEnergy = 10.0;
/* fill tables for transforms */
WebRtcIsac_InitTransform();
return;
}
void WebRtcIsac_InitPreFilterbank(PreFiltBankstr *prefiltdata)
{
int k;
for (k = 0; k < QLOOKAHEAD; k++) {
prefiltdata->INLABUF1[k] = 0;
prefiltdata->INLABUF2[k] = 0;
prefiltdata->INLABUF1_float[k] = 0;
prefiltdata->INLABUF2_float[k] = 0;
}
for (k = 0; k < 2*(QORDER-1); k++) {
prefiltdata->INSTAT1[k] = 0;
prefiltdata->INSTAT2[k] = 0;
prefiltdata->INSTATLA1[k] = 0;
prefiltdata->INSTATLA2[k] = 0;
prefiltdata->INSTAT1_float[k] = 0;
prefiltdata->INSTAT2_float[k] = 0;
prefiltdata->INSTATLA1_float[k] = 0;
prefiltdata->INSTATLA2_float[k] = 0;
}
/* High pass filter states */
prefiltdata->HPstates[0] = 0.0;
prefiltdata->HPstates[1] = 0.0;
prefiltdata->HPstates_float[0] = 0.0f;
prefiltdata->HPstates_float[1] = 0.0f;
return;
}
void WebRtcIsac_InitPostFilterbank(PostFiltBankstr *postfiltdata)
{
int k;
for (k = 0; k < 2*POSTQORDER; k++) {
postfiltdata->STATE_0_LOWER[k] = 0;
postfiltdata->STATE_0_UPPER[k] = 0;
postfiltdata->STATE_0_LOWER_float[k] = 0;
postfiltdata->STATE_0_UPPER_float[k] = 0;
}
/* High pass filter states */
postfiltdata->HPstates1[0] = 0.0;
postfiltdata->HPstates1[1] = 0.0;
postfiltdata->HPstates2[0] = 0.0;
postfiltdata->HPstates2[1] = 0.0;
postfiltdata->HPstates1_float[0] = 0.0f;
postfiltdata->HPstates1_float[1] = 0.0f;
postfiltdata->HPstates2_float[0] = 0.0f;
postfiltdata->HPstates2_float[1] = 0.0f;
return;
}
void WebRtcIsac_InitPitchFilter(PitchFiltstr *pitchfiltdata)
{
int k;
for (k = 0; k < PITCH_BUFFSIZE; k++) {
pitchfiltdata->ubuf[k] = 0.0;
}
pitchfiltdata->ystate[0] = 0.0;
for (k = 1; k < (PITCH_DAMPORDER); k++) {
pitchfiltdata->ystate[k] = 0.0;
}
pitchfiltdata->oldlagp[0] = 50.0;
pitchfiltdata->oldgainp[0] = 0.0;
}
void WebRtcIsac_InitWeightingFilter(WeightFiltstr *wfdata)
{
int k;
double t, dtmp, dtmp2, denum, denum2;
for (k=0;k<PITCH_WLPCBUFLEN;k++)
wfdata->buffer[k]=0.0;
for (k=0;k<PITCH_WLPCORDER;k++) {
wfdata->istate[k]=0.0;
wfdata->weostate[k]=0.0;
wfdata->whostate[k]=0.0;
}
/* next part should be in Matlab, writing to a global table */
t = 0.5;
denum = 1.0 / ((double) PITCH_WLPCWINLEN);
denum2 = denum * denum;
for (k=0;k<PITCH_WLPCWINLEN;k++) {
dtmp = PITCH_WLPCASYM * t * denum + (1-PITCH_WLPCASYM) * t * t * denum2;
dtmp *= 3.14159265;
dtmp2 = sin(dtmp);
wfdata->window[k] = dtmp2 * dtmp2;
t++;
}
}
/* clear all buffers */
void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct *State)
{
int k;
for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++)
State->dec_buffer[k] = 0.0;
for (k = 0; k < 2*ALLPASSSECTIONS+1; k++)
State->decimator_state[k] = 0.0;
for (k = 0; k < 2; k++)
State->hp_state[k] = 0.0;
for (k = 0; k < QLOOKAHEAD; k++)
State->whitened_buf[k] = 0.0;
for (k = 0; k < QLOOKAHEAD; k++)
State->inbuf[k] = 0.0;
WebRtcIsac_InitPitchFilter(&(State->PFstr_wght));
WebRtcIsac_InitPitchFilter(&(State->PFstr));
WebRtcIsac_InitWeightingFilter(&(State->Wghtstr));
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
# 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.
{
'targets': [
{
'target_name': 'iSAC',
'type': 'static_library',
'dependencies': [
'<(webrtc_root)/common_audio/common_audio.gyp:common_audio',
],
'include_dirs': [
'../interface',
'<(webrtc_root)',
],
'direct_dependent_settings': {
'include_dirs': [
'../interface',
'<(webrtc_root)',
],
},
'sources': [
'../interface/isac.h',
'arith_routines.c',
'arith_routines_hist.c',
'arith_routines_logist.c',
'bandwidth_estimator.c',
'crc.c',
'decode.c',
'decode_bwe.c',
'encode.c',
'encode_lpc_swb.c',
'entropy_coding.c',
'fft.c',
'filter_functions.c',
'filterbank_tables.c',
'intialize.c',
'isac.c',
'filterbanks.c',
'pitch_lag_tables.c',
'lattice.c',
'lpc_gain_swb_tables.c',
'lpc_analysis.c',
'lpc_shape_swb12_tables.c',
'lpc_shape_swb16_tables.c',
'lpc_tables.c',
'pitch_estimator.c',
'pitch_filter.c',
'pitch_gain_tables.c',
'spectrum_ar_model_tables.c',
'transform.c',
'arith_routines.h',
'bandwidth_estimator.h',
'codec.h',
'crc.h',
'encode_lpc_swb.h',
'entropy_coding.h',
'fft.h',
'filterbank_tables.h',
'lpc_gain_swb_tables.h',
'lpc_analysis.h',
'lpc_shape_swb12_tables.h',
'lpc_shape_swb16_tables.h',
'lpc_tables.h',
'pitch_estimator.h',
'pitch_gain_tables.h',
'pitch_lag_tables.h',
'settings.h',
'spectrum_ar_model_tables.h',
'structs.h',
'os_specific_inline.h',
],
'conditions': [
['OS=="linux"', {
'link_settings': {
'libraries': ['-lm',],
},
}],
],
},
],
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2013 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 <string>
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
#include "webrtc/test/testsupport/fileutils.h"
struct WebRtcISACStruct;
namespace webrtc {
// Number of samples in a 60 ms, sampled at 32 kHz.
const int kIsacNumberOfSamples = 320 * 6;
// Maximum number of bytes in output bitstream.
const size_t kMaxBytes = 1000;
class IsacTest : public ::testing::Test {
protected:
IsacTest();
virtual void SetUp();
WebRtcISACStruct* isac_codec_;
int16_t speech_data_[kIsacNumberOfSamples];
int16_t output_data_[kIsacNumberOfSamples];
int16_t bitstream_[kMaxBytes / 2];
uint8_t bitstream_small_[7]; // Simulate sync packets.
};
IsacTest::IsacTest()
: isac_codec_(NULL) {
}
void IsacTest::SetUp() {
// Read some samples from a speech file, to be used in the encode test.
FILE* input_file;
const std::string file_name =
webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
input_file = fopen(file_name.c_str(), "rb");
ASSERT_TRUE(input_file != NULL);
ASSERT_EQ(kIsacNumberOfSamples,
static_cast<int32_t>(fread(speech_data_, sizeof(int16_t),
kIsacNumberOfSamples, input_file)));
fclose(input_file);
input_file = NULL;
}
// Test failing Create.
TEST_F(IsacTest, IsacCreateFail) {
// Test to see that an invalid pointer is caught.
EXPECT_EQ(-1, WebRtcIsac_Create(NULL));
}
// Test failing Free.
TEST_F(IsacTest, IsacFreeFail) {
// Test to see that free function doesn't crash.
EXPECT_EQ(0, WebRtcIsac_Free(NULL));
}
// Test normal Create and Free.
TEST_F(IsacTest, IsacCreateFree) {
EXPECT_EQ(0, WebRtcIsac_Create(&isac_codec_));
EXPECT_TRUE(isac_codec_ != NULL);
EXPECT_EQ(0, WebRtcIsac_Free(isac_codec_));}
TEST_F(IsacTest, IsacUpdateBWE) {
// Create encoder memory.
EXPECT_EQ(0, WebRtcIsac_Create(&isac_codec_));
// Init encoder (adaptive mode) and decoder.
WebRtcIsac_EncoderInit(isac_codec_, 0);
WebRtcIsac_DecoderInit(isac_codec_);
// Encode & decode.
int16_t encoded_bytes;
uint16_t* coded = reinterpret_cast<uint16_t*>(bitstream_);
uint16_t* coded_small = reinterpret_cast<uint16_t*>(bitstream_small_);
// Test with call with a small packet (sync packet).
EXPECT_EQ(-1, WebRtcIsac_UpdateBwEstimate(isac_codec_, coded_small, 7, 1,
12345, 56789));
// Encode 60 ms of data (needed to create a first packet).
encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_);
EXPECT_EQ(0, encoded_bytes);
encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_);
EXPECT_EQ(0, encoded_bytes);
encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_);
EXPECT_EQ(0, encoded_bytes);
encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_);
EXPECT_EQ(0, encoded_bytes);
encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_);
EXPECT_EQ(0, encoded_bytes);
encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_);
// Call to update bandwidth estimator with real data.
EXPECT_EQ(0, WebRtcIsac_UpdateBwEstimate(isac_codec_, coded, encoded_bytes, 1,
12345, 56789));
// Free memory.
EXPECT_EQ(0, WebRtcIsac_Free(isac_codec_));
}
} // namespace webrtc

View File

@@ -0,0 +1,217 @@
/*
* 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.
*/
/*
* lattice.c
*
* contains the normalized lattice filter routines (MA and AR) for iSAC codec
*
*/
#include "settings.h"
#include "codec.h"
#include <math.h>
#include <memory.h>
#ifdef WEBRTC_ANDROID
#include <stdlib.h>
#endif
/* filter the signal using normalized lattice filter */
/* MA filter */
void WebRtcIsac_NormLatticeFilterMa(int orderCoef,
float *stateF,
float *stateG,
float *lat_in,
double *filtcoeflo,
double *lat_out)
{
int n,k,i,u,temp1;
int ord_1 = orderCoef+1;
float sth[MAX_AR_MODEL_ORDER];
float cth[MAX_AR_MODEL_ORDER];
float inv_cth[MAX_AR_MODEL_ORDER];
double a[MAX_AR_MODEL_ORDER+1];
float f[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], g[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
float gain1;
for (u=0;u<SUBFRAMES;u++)
{
/* set the Direct Form coefficients */
temp1 = u*ord_1;
a[0] = 1;
memcpy(a+1, filtcoeflo+temp1+1, sizeof(double) * (ord_1-1));
/* compute lattice filter coefficients */
WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
/* compute the gain */
gain1 = (float)filtcoeflo[temp1];
for (k=0;k<orderCoef;k++)
{
gain1 *= cth[k];
inv_cth[k] = 1/cth[k];
}
/* normalized lattice filter */
/*****************************/
/* initial conditions */
for (i=0;i<HALF_SUBFRAMELEN;i++)
{
f[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
g[0][i] = lat_in[i + u * HALF_SUBFRAMELEN];
}
/* get the state of f&g for the first input, for all orders */
for (i=1;i<ord_1;i++)
{
f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]);
g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0];
}
/* filtering */
for(k=0;k<orderCoef;k++)
{
for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
{
f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]);
g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1];
}
}
for(n=0;n<HALF_SUBFRAMELEN;n++)
{
lat_out[n + u * HALF_SUBFRAMELEN] = gain1 * f[orderCoef][n];
}
/* save the states */
for (i=0;i<ord_1;i++)
{
stateF[i] = f[i][HALF_SUBFRAMELEN-1];
stateG[i] = g[i][HALF_SUBFRAMELEN-1];
}
/* process next frame */
}
return;
}
/*///////////////////AR filter ///////////////////////////////*/
/* filter the signal using normalized lattice filter */
void WebRtcIsac_NormLatticeFilterAr(int orderCoef,
float *stateF,
float *stateG,
double *lat_in,
double *lo_filt_coef,
float *lat_out)
{
int n,k,i,u,temp1;
int ord_1 = orderCoef+1;
float sth[MAX_AR_MODEL_ORDER];
float cth[MAX_AR_MODEL_ORDER];
double a[MAX_AR_MODEL_ORDER+1];
float ARf[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN], ARg[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
float gain1,inv_gain1;
for (u=0;u<SUBFRAMES;u++)
{
/* set the denominator and numerator of the Direct Form */
temp1 = u*ord_1;
a[0] = 1;
memcpy(a+1, lo_filt_coef+temp1+1, sizeof(double) * (ord_1-1));
WebRtcIsac_Dir2Lat(a,orderCoef,sth,cth);
gain1 = (float)lo_filt_coef[temp1];
for (k=0;k<orderCoef;k++)
{
gain1 = cth[k]*gain1;
}
/* initial conditions */
inv_gain1 = 1/gain1;
for (i=0;i<HALF_SUBFRAMELEN;i++)
{
ARf[orderCoef][i] = (float)lat_in[i + u * HALF_SUBFRAMELEN]*inv_gain1;
}
for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
{
ARf[i][0] = cth[i]*ARf[i+1][0] - sth[i]*stateG[i];
ARg[i+1][0] = sth[i]*ARf[i+1][0] + cth[i]* stateG[i];
}
ARg[0][0] = ARf[0][0];
for(n=0;n<(HALF_SUBFRAMELEN-1);n++)
{
for(k=orderCoef-1;k>=0;k--)
{
ARf[k][n+1] = cth[k]*ARf[k+1][n+1] - sth[k]*ARg[k][n];
ARg[k+1][n+1] = sth[k]*ARf[k+1][n+1] + cth[k]* ARg[k][n];
}
ARg[0][n+1] = ARf[0][n+1];
}
memcpy(lat_out+u * HALF_SUBFRAMELEN, &(ARf[0][0]), sizeof(float) * HALF_SUBFRAMELEN);
/* cannot use memcpy in the following */
for (i=0;i<ord_1;i++)
{
stateF[i] = ARf[i][HALF_SUBFRAMELEN-1];
stateG[i] = ARg[i][HALF_SUBFRAMELEN-1];
}
}
return;
}
/* compute the reflection coefficients using the step-down procedure*/
/* converts the direct form parameters to lattice form.*/
/* a and b are vectors which contain the direct form coefficients,
according to
A(z) = a(1) + a(2)*z + a(3)*z^2 + ... + a(M+1)*z^M
B(z) = b(1) + b(2)*z + b(3)*z^2 + ... + b(M+1)*z^M
*/
void WebRtcIsac_Dir2Lat(double *a,
int orderCoef,
float *sth,
float *cth)
{
int m, k;
float tmp[MAX_AR_MODEL_ORDER];
float tmp_inv, cth2;
sth[orderCoef-1] = (float)a[orderCoef];
cth2 = 1.0f - sth[orderCoef-1] * sth[orderCoef-1];
cth[orderCoef-1] = (float)sqrt(cth2);
for (m=orderCoef-1; m>0; m--)
{
tmp_inv = 1.0f / cth2;
for (k=1; k<=m; k++)
{
tmp[k] = ((float)a[k] - sth[m] * (float)a[m-k+1]) * tmp_inv;
}
for (k=1; k<m; k++)
{
a[k] = tmp[k];
}
sth[m-1] = tmp[m];
cth2 = 1 - sth[m-1] * sth[m-1];
cth[m-1] = (float)sqrt(cth2);
}
}

View File

@@ -0,0 +1,535 @@
/*
* 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 "lpc_analysis.h"
#include "settings.h"
#include "codec.h"
#include "entropy_coding.h"
#include <math.h>
#include <string.h>
#define LEVINSON_EPS 1.0e-10
/* window */
/* Matlab generation code:
* t = (1:256)/257; r = 1-(1-t).^.45; w = sin(r*pi).^3; w = w/sum(w); plot((1:256)/8, w); grid;
* for k=1:16, fprintf(1, '%.8f, ', w(k*16 + (-15:0))); fprintf(1, '\n'); end
*/
static const double kLpcCorrWindow[WINLEN] = {
0.00000000, 0.00000001, 0.00000004, 0.00000010, 0.00000020,
0.00000035, 0.00000055, 0.00000083, 0.00000118, 0.00000163,
0.00000218, 0.00000283, 0.00000361, 0.00000453, 0.00000558, 0.00000679,
0.00000817, 0.00000973, 0.00001147, 0.00001342, 0.00001558,
0.00001796, 0.00002058, 0.00002344, 0.00002657, 0.00002997,
0.00003365, 0.00003762, 0.00004190, 0.00004651, 0.00005144, 0.00005673,
0.00006236, 0.00006837, 0.00007476, 0.00008155, 0.00008875,
0.00009636, 0.00010441, 0.00011290, 0.00012186, 0.00013128,
0.00014119, 0.00015160, 0.00016252, 0.00017396, 0.00018594, 0.00019846,
0.00021155, 0.00022521, 0.00023946, 0.00025432, 0.00026978,
0.00028587, 0.00030260, 0.00031998, 0.00033802, 0.00035674,
0.00037615, 0.00039626, 0.00041708, 0.00043863, 0.00046092, 0.00048396,
0.00050775, 0.00053233, 0.00055768, 0.00058384, 0.00061080,
0.00063858, 0.00066720, 0.00069665, 0.00072696, 0.00075813,
0.00079017, 0.00082310, 0.00085692, 0.00089164, 0.00092728, 0.00096384,
0.00100133, 0.00103976, 0.00107914, 0.00111947, 0.00116077,
0.00120304, 0.00124630, 0.00129053, 0.00133577, 0.00138200,
0.00142924, 0.00147749, 0.00152676, 0.00157705, 0.00162836, 0.00168070,
0.00173408, 0.00178850, 0.00184395, 0.00190045, 0.00195799,
0.00201658, 0.00207621, 0.00213688, 0.00219860, 0.00226137,
0.00232518, 0.00239003, 0.00245591, 0.00252284, 0.00259079, 0.00265977,
0.00272977, 0.00280078, 0.00287280, 0.00294582, 0.00301984,
0.00309484, 0.00317081, 0.00324774, 0.00332563, 0.00340446,
0.00348421, 0.00356488, 0.00364644, 0.00372889, 0.00381220, 0.00389636,
0.00398135, 0.00406715, 0.00415374, 0.00424109, 0.00432920,
0.00441802, 0.00450754, 0.00459773, 0.00468857, 0.00478001,
0.00487205, 0.00496464, 0.00505775, 0.00515136, 0.00524542, 0.00533990,
0.00543476, 0.00552997, 0.00562548, 0.00572125, 0.00581725,
0.00591342, 0.00600973, 0.00610612, 0.00620254, 0.00629895,
0.00639530, 0.00649153, 0.00658758, 0.00668341, 0.00677894, 0.00687413,
0.00696891, 0.00706322, 0.00715699, 0.00725016, 0.00734266,
0.00743441, 0.00752535, 0.00761540, 0.00770449, 0.00779254,
0.00787947, 0.00796519, 0.00804963, 0.00813270, 0.00821431, 0.00829437,
0.00837280, 0.00844949, 0.00852436, 0.00859730, 0.00866822,
0.00873701, 0.00880358, 0.00886781, 0.00892960, 0.00898884,
0.00904542, 0.00909923, 0.00915014, 0.00919805, 0.00924283, 0.00928436,
0.00932252, 0.00935718, 0.00938821, 0.00941550, 0.00943890,
0.00945828, 0.00947351, 0.00948446, 0.00949098, 0.00949294,
0.00949020, 0.00948262, 0.00947005, 0.00945235, 0.00942938, 0.00940099,
0.00936704, 0.00932738, 0.00928186, 0.00923034, 0.00917268,
0.00910872, 0.00903832, 0.00896134, 0.00887763, 0.00878706,
0.00868949, 0.00858478, 0.00847280, 0.00835343, 0.00822653, 0.00809199,
0.00794970, 0.00779956, 0.00764145, 0.00747530, 0.00730103,
0.00711857, 0.00692787, 0.00672888, 0.00652158, 0.00630597,
0.00608208, 0.00584994, 0.00560962, 0.00536124, 0.00510493, 0.00484089,
0.00456935, 0.00429062, 0.00400505, 0.00371310, 0.00341532,
0.00311238, 0.00280511, 0.00249452, 0.00218184, 0.00186864,
0.00155690, 0.00124918, 0.00094895, 0.00066112, 0.00039320, 0.00015881
};
double WebRtcIsac_LevDurb(double *a, double *k, double *r, int order)
{
double sum, alpha;
int m, m_h, i;
alpha = 0; //warning -DH
a[0] = 1.0;
if (r[0] < LEVINSON_EPS) { /* if r[0] <= 0, set LPC coeff. to zero */
for (i = 0; i < order; i++) {
k[i] = 0;
a[i+1] = 0;
}
} else {
a[1] = k[0] = -r[1]/r[0];
alpha = r[0] + r[1] * k[0];
for (m = 1; m < order; m++){
sum = r[m + 1];
for (i = 0; i < m; i++){
sum += a[i+1] * r[m - i];
}
k[m] = -sum / alpha;
alpha += k[m] * sum;
m_h = (m + 1) >> 1;
for (i = 0; i < m_h; i++){
sum = a[i+1] + k[m] * a[m - i];
a[m - i] += k[m] * a[i+1];
a[i+1] = sum;
}
a[m+1] = k[m];
}
}
return alpha;
}
//was static before, but didn't work with MEX file
void WebRtcIsac_GetVars(const double *input, const int16_t *pitchGains_Q12,
double *oldEnergy, double *varscale)
{
double nrg[4], chng, pg;
int k;
double pitchGains[4]={0,0,0,0};;
/* Calculate energies of first and second frame halfs */
nrg[0] = 0.0001;
for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES_QUARTER + QLOOKAHEAD) / 2; k++) {
nrg[0] += input[k]*input[k];
}
nrg[1] = 0.0001;
for ( ; k < (FRAMESAMPLES_HALF + QLOOKAHEAD) / 2; k++) {
nrg[1] += input[k]*input[k];
}
nrg[2] = 0.0001;
for ( ; k < (FRAMESAMPLES*3/4 + QLOOKAHEAD) / 2; k++) {
nrg[2] += input[k]*input[k];
}
nrg[3] = 0.0001;
for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) {
nrg[3] += input[k]*input[k];
}
/* Calculate average level change */
chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) +
fabs(10.0 * log10(nrg[2] / nrg[1])) +
fabs(10.0 * log10(nrg[1] / nrg[0])) +
fabs(10.0 * log10(nrg[0] / *oldEnergy)));
/* Find average pitch gain */
pg = 0.0;
for (k=0; k<4; k++)
{
pitchGains[k] = ((float)pitchGains_Q12[k])/4096;
pg += pitchGains[k];
}
pg *= 0.25;
/* If pitch gain is low and energy constant - increase noise level*/
/* Matlab code:
pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) ))
*/
*varscale = 0.0 + 1.0 * exp( -1.4 * exp(-200.0 * pg*pg*pg) / (1.0 + 0.4 * chng) );
*oldEnergy = nrg[3];
}
void
WebRtcIsac_GetVarsUB(
const double* input,
double* oldEnergy,
double* varscale)
{
double nrg[4], chng;
int k;
/* Calculate energies of first and second frame halfs */
nrg[0] = 0.0001;
for (k = 0; k < (FRAMESAMPLES_QUARTER) / 2; k++) {
nrg[0] += input[k]*input[k];
}
nrg[1] = 0.0001;
for ( ; k < (FRAMESAMPLES_HALF) / 2; k++) {
nrg[1] += input[k]*input[k];
}
nrg[2] = 0.0001;
for ( ; k < (FRAMESAMPLES*3/4) / 2; k++) {
nrg[2] += input[k]*input[k];
}
nrg[3] = 0.0001;
for ( ; k < (FRAMESAMPLES) / 2; k++) {
nrg[3] += input[k]*input[k];
}
/* Calculate average level change */
chng = 0.25 * (fabs(10.0 * log10(nrg[3] / nrg[2])) +
fabs(10.0 * log10(nrg[2] / nrg[1])) +
fabs(10.0 * log10(nrg[1] / nrg[0])) +
fabs(10.0 * log10(nrg[0] / *oldEnergy)));
/* If pitch gain is low and energy constant - increase noise level*/
/* Matlab code:
pg = 0:.01:.45; plot(pg, 0.0 + 1.0 * exp( -1.0 * exp(-200.0 * pg.*pg.*pg) / (1.0 + 0.4 * 0) ))
*/
*varscale = exp( -1.4 / (1.0 + 0.4 * chng) );
*oldEnergy = nrg[3];
}
void WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata,
double signal_noise_ratio, const int16_t *pitchGains_Q12,
double *lo_coeff, double *hi_coeff)
{
int k, n, j, pos1, pos2;
double varscale;
double DataLo[WINLEN], DataHi[WINLEN];
double corrlo[ORDERLO+2], corrlo2[ORDERLO+1];
double corrhi[ORDERHI+1];
double k_veclo[ORDERLO], k_vechi[ORDERHI];
double a_LO[ORDERLO+1], a_HI[ORDERHI+1];
double tmp, res_nrg;
double FwdA, FwdB;
/* hearing threshold level in dB; higher value gives more noise */
const double HearThresOffset = -28.0;
/* bandwdith expansion factors for low- and high band */
const double gammaLo = 0.9;
const double gammaHi = 0.8;
/* less-noise-at-low-frequencies factor */
double aa;
/* convert from dB to signal level */
const double H_T_H = pow(10.0, 0.05 * HearThresOffset);
double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46; /* divide by sqrt(12) */
/* change quallevel depending on pitch gains and level fluctuations */
WebRtcIsac_GetVars(inLo, pitchGains_Q12, &(maskdata->OldEnergy), &varscale);
/* less-noise-at-low-frequencies factor */
aa = 0.35 * (0.5 + 0.5 * varscale);
/* replace data in buffer by new look-ahead data */
for (pos1 = 0; pos1 < QLOOKAHEAD; pos1++)
maskdata->DataBufferLo[pos1 + WINLEN - QLOOKAHEAD] = inLo[pos1];
for (k = 0; k < SUBFRAMES; k++) {
/* Update input buffer and multiply signal with window */
for (pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) {
maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 + UPDATE/2];
maskdata->DataBufferHi[pos1] = maskdata->DataBufferHi[pos1 + UPDATE/2];
DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1];
}
pos2 = k * UPDATE/2;
for (n = 0; n < UPDATE/2; n++, pos1++) {
maskdata->DataBufferLo[pos1] = inLo[QLOOKAHEAD + pos2];
maskdata->DataBufferHi[pos1] = inHi[pos2++];
DataLo[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
DataHi[pos1] = maskdata->DataBufferHi[pos1] * kLpcCorrWindow[pos1];
}
/* Get correlation coefficients */
WebRtcIsac_AutoCorr(corrlo, DataLo, WINLEN, ORDERLO+1); /* computing autocorrelation */
WebRtcIsac_AutoCorr(corrhi, DataHi, WINLEN, ORDERHI);
/* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */
corrlo2[0] = (1.0+aa*aa) * corrlo[0] - 2.0*aa * corrlo[1];
tmp = (1.0 + aa*aa);
for (n = 1; n <= ORDERLO; n++) {
corrlo2[n] = tmp * corrlo[n] - aa * (corrlo[n-1] + corrlo[n+1]);
}
tmp = (1.0+aa) * (1.0+aa);
for (n = 0; n <= ORDERHI; n++) {
corrhi[n] = tmp * corrhi[n];
}
/* add white noise floor */
corrlo2[0] += 1e-6;
corrhi[0] += 1e-6;
FwdA = 0.01;
FwdB = 0.01;
/* recursive filtering of correlation over subframes */
for (n = 0; n <= ORDERLO; n++) {
maskdata->CorrBufLo[n] = FwdA * maskdata->CorrBufLo[n] + corrlo2[n];
corrlo2[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufLo[n] + (1.0-FwdB) * corrlo2[n];
}
for (n = 0; n <= ORDERHI; n++) {
maskdata->CorrBufHi[n] = FwdA * maskdata->CorrBufHi[n] + corrhi[n];
corrhi[n] = ((1.0-FwdA)*FwdB) * maskdata->CorrBufHi[n] + (1.0-FwdB) * corrhi[n];
}
/* compute prediction coefficients */
WebRtcIsac_LevDurb(a_LO, k_veclo, corrlo2, ORDERLO);
WebRtcIsac_LevDurb(a_HI, k_vechi, corrhi, ORDERHI);
/* bandwidth expansion */
tmp = gammaLo;
for (n = 1; n <= ORDERLO; n++) {
a_LO[n] *= tmp;
tmp *= gammaLo;
}
/* residual energy */
res_nrg = 0.0;
for (j = 0; j <= ORDERLO; j++) {
for (n = 0; n <= j; n++) {
res_nrg += a_LO[j] * corrlo2[j-n] * a_LO[n];
}
for (n = j+1; n <= ORDERLO; n++) {
res_nrg += a_LO[j] * corrlo2[n-j] * a_LO[n];
}
}
/* add hearing threshold and compute the gain */
*lo_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H);
/* copy coefficients to output array */
for (n = 1; n <= ORDERLO; n++) {
*lo_coeff++ = a_LO[n];
}
/* bandwidth expansion */
tmp = gammaHi;
for (n = 1; n <= ORDERHI; n++) {
a_HI[n] *= tmp;
tmp *= gammaHi;
}
/* residual energy */
res_nrg = 0.0;
for (j = 0; j <= ORDERHI; j++) {
for (n = 0; n <= j; n++) {
res_nrg += a_HI[j] * corrhi[j-n] * a_HI[n];
}
for (n = j+1; n <= ORDERHI; n++) {
res_nrg += a_HI[j] * corrhi[n-j] * a_HI[n];
}
}
/* add hearing threshold and compute of the gain */
*hi_coeff++ = S_N_R / (sqrt(res_nrg) / varscale + H_T_H);
/* copy coefficients to output array */
for (n = 1; n <= ORDERHI; n++) {
*hi_coeff++ = a_HI[n];
}
}
}
/******************************************************************************
* WebRtcIsac_GetLpcCoefUb()
*
* Compute LP coefficients and correlation coefficients. At 12 kHz LP
* coefficients of the first and the last sub-frame is computed. At 16 kHz
* LP coefficients of 4th, 8th and 12th sub-frames are computed. We always
* compute correlation coefficients of all sub-frames.
*
* Inputs:
* -inSignal : Input signal
* -maskdata : a structure keeping signal from previous frame.
* -bandwidth : specifies if the codec is in 0-16 kHz mode or
* 0-12 kHz mode.
*
* Outputs:
* -lpCoeff : pointer to a buffer where A-polynomials are
* written to (first coeff is 1 and it is not
* written)
* -corrMat : a matrix where correlation coefficients of each
* sub-frame are written to one row.
* -varscale : a scale used to compute LPC gains.
*/
void
WebRtcIsac_GetLpcCoefUb(
double* inSignal,
MaskFiltstr* maskdata,
double* lpCoeff,
double corrMat[][UB_LPC_ORDER + 1],
double* varscale,
int16_t bandwidth)
{
int frameCntr, activeFrameCntr, n, pos1, pos2;
int16_t criterion1;
int16_t criterion2;
int16_t numSubFrames = SUBFRAMES * (1 + (bandwidth == isac16kHz));
double data[WINLEN];
double corrSubFrame[UB_LPC_ORDER+2];
double reflecCoeff[UB_LPC_ORDER];
double aPolynom[UB_LPC_ORDER+1];
double tmp;
/* bandwdith expansion factors */
const double gamma = 0.9;
/* change quallevel depending on pitch gains and level fluctuations */
WebRtcIsac_GetVarsUB(inSignal, &(maskdata->OldEnergy), varscale);
/* replace data in buffer by new look-ahead data */
for(frameCntr = 0, activeFrameCntr = 0; frameCntr < numSubFrames;
frameCntr++)
{
if(frameCntr == SUBFRAMES)
{
// we are in 16 kHz
varscale++;
WebRtcIsac_GetVarsUB(&inSignal[FRAMESAMPLES_HALF],
&(maskdata->OldEnergy), varscale);
}
/* Update input buffer and multiply signal with window */
for(pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++)
{
maskdata->DataBufferLo[pos1] = maskdata->DataBufferLo[pos1 +
UPDATE/2];
data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
}
pos2 = frameCntr * UPDATE/2;
for(n = 0; n < UPDATE/2; n++, pos1++, pos2++)
{
maskdata->DataBufferLo[pos1] = inSignal[pos2];
data[pos1] = maskdata->DataBufferLo[pos1] * kLpcCorrWindow[pos1];
}
/* Get correlation coefficients */
/* computing autocorrelation */
WebRtcIsac_AutoCorr(corrSubFrame, data, WINLEN, UB_LPC_ORDER+1);
memcpy(corrMat[frameCntr], corrSubFrame,
(UB_LPC_ORDER+1)*sizeof(double));
criterion1 = ((frameCntr == 0) || (frameCntr == (SUBFRAMES - 1))) &&
(bandwidth == isac12kHz);
criterion2 = (((frameCntr+1) % 4) == 0) &&
(bandwidth == isac16kHz);
if(criterion1 || criterion2)
{
/* add noise */
corrSubFrame[0] += 1e-6;
/* compute prediction coefficients */
WebRtcIsac_LevDurb(aPolynom, reflecCoeff, corrSubFrame,
UB_LPC_ORDER);
/* bandwidth expansion */
tmp = gamma;
for (n = 1; n <= UB_LPC_ORDER; n++)
{
*lpCoeff++ = aPolynom[n] * tmp;
tmp *= gamma;
}
activeFrameCntr++;
}
}
}
/******************************************************************************
* WebRtcIsac_GetLpcGain()
*
* Compute the LPC gains for each sub-frame, given the LPC of each sub-frame
* and the corresponding correlation coefficients.
*
* Inputs:
* -signal_noise_ratio : the desired SNR in dB.
* -numVecs : number of sub-frames
* -corrMat : a matrix of correlation coefficients where
* each row is a set of correlation coefficients of
* one sub-frame.
* -varscale : a scale computed when WebRtcIsac_GetLpcCoefUb()
* is called.
*
* Outputs:
* -gain : pointer to a buffer where LP gains are written.
*
*/
void
WebRtcIsac_GetLpcGain(
double signal_noise_ratio,
const double* filtCoeffVecs,
int numVecs,
double* gain,
double corrMat[][UB_LPC_ORDER + 1],
const double* varscale)
{
int16_t j, n;
int16_t subFrameCntr;
double aPolynom[ORDERLO + 1];
double res_nrg;
const double HearThresOffset = -28.0;
const double H_T_H = pow(10.0, 0.05 * HearThresOffset);
/* divide by sqrt(12) = 3.46 */
const double S_N_R = pow(10.0, 0.05 * signal_noise_ratio) / 3.46;
aPolynom[0] = 1;
for(subFrameCntr = 0; subFrameCntr < numVecs; subFrameCntr++)
{
if(subFrameCntr == SUBFRAMES)
{
// we are in second half of a SWB frame. use new varscale
varscale++;
}
memcpy(&aPolynom[1], &filtCoeffVecs[(subFrameCntr * (UB_LPC_ORDER + 1)) +
1], sizeof(double) * UB_LPC_ORDER);
/* residual energy */
res_nrg = 0.0;
for(j = 0; j <= UB_LPC_ORDER; j++)
{
for(n = 0; n <= j; n++)
{
res_nrg += aPolynom[j] * corrMat[subFrameCntr][j-n] *
aPolynom[n];
}
for(n = j+1; n <= UB_LPC_ORDER; n++)
{
res_nrg += aPolynom[j] * corrMat[subFrameCntr][n-j] *
aPolynom[n];
}
}
/* add hearing threshold and compute the gain */
gain[subFrameCntr] = S_N_R / (sqrt(res_nrg) / *varscale + H_T_H);
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.
*/
/*
* lpc_analysis.h
*
* LPC functions
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYSIS_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYSIS_H_
#include "settings.h"
#include "structs.h"
double WebRtcIsac_LevDurb(double *a, double *k, double *r, int order);
void WebRtcIsac_GetVars(const double *input, const int16_t *pitchGains_Q12,
double *oldEnergy, double *varscale);
void WebRtcIsac_GetLpcCoefLb(double *inLo, double *inHi, MaskFiltstr *maskdata,
double signal_noise_ratio, const int16_t *pitchGains_Q12,
double *lo_coeff, double *hi_coeff);
void WebRtcIsac_GetLpcGain(
double signal_noise_ratio,
const double* filtCoeffVecs,
int numVecs,
double* gain,
double corrLo[][UB_LPC_ORDER + 1],
const double* varscale);
void WebRtcIsac_GetLpcCoefUb(
double* inSignal,
MaskFiltstr* maskdata,
double* lpCoeff,
double corr[][UB_LPC_ORDER + 1],
double* varscale,
int16_t bandwidth);
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_ANALYIS_H_ */

View File

@@ -0,0 +1,137 @@
/*
* 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.
*/
/*
* SWB_KLT_Tables_LPCGain.c
*
* This file defines tables used for entropy coding of LPC Gain
* of upper-band.
*
*/
#include "lpc_gain_swb_tables.h"
#include "settings.h"
#include "typedefs.h"
const double WebRtcIsac_kQSizeLpcGain = 0.100000;
const double WebRtcIsac_kMeanLpcGain = -3.3822;
/*
* The smallest reconstruction points for quantiztion of
* LPC gains.
*/
const double WebRtcIsac_kLeftRecPointLpcGain[SUBFRAMES] =
{
-0.800000, -1.000000, -1.200000, -2.200000, -3.000000, -12.700000
};
/*
* Number of reconstruction points of quantizers for LPC Gains.
*/
const int16_t WebRtcIsac_kNumQCellLpcGain[SUBFRAMES] =
{
17, 20, 25, 45, 77, 170
};
/*
* Starting index for entropy decoder to search for the right interval,
* one entry per LAR coefficient
*/
const uint16_t WebRtcIsac_kLpcGainEntropySearch[SUBFRAMES] =
{
8, 10, 12, 22, 38, 85
};
/*
* The following 6 vectors define CDF of 6 decorrelated LPC
* gains.
*/
const uint16_t WebRtcIsac_kLpcGainCdfVec0[18] =
{
0, 10, 27, 83, 234, 568, 1601, 4683, 16830, 57534, 63437,
64767, 65229, 65408, 65483, 65514, 65527, 65535
};
const uint16_t WebRtcIsac_kLpcGainCdfVec1[21] =
{
0, 15, 33, 84, 185, 385, 807, 1619, 3529, 7850, 19488,
51365, 62437, 64548, 65088, 65304, 65409, 65484, 65507, 65522, 65535
};
const uint16_t WebRtcIsac_kLpcGainCdfVec2[26] =
{
0, 15, 29, 54, 89, 145, 228, 380, 652, 1493, 4260,
12359, 34133, 50749, 57224, 60814, 62927, 64078, 64742, 65103, 65311, 65418,
65473, 65509, 65521, 65535
};
const uint16_t WebRtcIsac_kLpcGainCdfVec3[46] =
{
0, 8, 12, 16, 26, 42, 56, 76, 111, 164, 247,
366, 508, 693, 1000, 1442, 2155, 3188, 4854, 7387, 11249, 17617,
30079, 46711, 56291, 60127, 62140, 63258, 63954, 64384, 64690, 64891, 65031,
65139, 65227, 65293, 65351, 65399, 65438, 65467, 65492, 65504, 65510, 65518,
65523, 65535
};
const uint16_t WebRtcIsac_kLpcGainCdfVec4[78] =
{
0, 17, 29, 39, 51, 70, 104, 154, 234, 324, 443,
590, 760, 971, 1202, 1494, 1845, 2274, 2797, 3366, 4088, 4905,
5899, 7142, 8683, 10625, 12983, 16095, 20637, 28216, 38859, 47237, 51537,
54150, 56066, 57583, 58756, 59685, 60458, 61103, 61659, 62144, 62550, 62886,
63186, 63480, 63743, 63954, 64148, 64320, 64467, 64600, 64719, 64837, 64939,
65014, 65098, 65160, 65211, 65250, 65290, 65325, 65344, 65366, 65391, 65410,
65430, 65447, 65460, 65474, 65487, 65494, 65501, 65509, 65513, 65518, 65520,
65535
};
const uint16_t WebRtcIsac_kLpcGainCdfVec5[171] =
{
0, 10, 12, 14, 16, 18, 23, 29, 35, 42, 51,
58, 65, 72, 78, 87, 96, 103, 111, 122, 134, 150,
167, 184, 202, 223, 244, 265, 289, 315, 346, 379, 414,
450, 491, 532, 572, 613, 656, 700, 751, 802, 853, 905,
957, 1021, 1098, 1174, 1250, 1331, 1413, 1490, 1565, 1647, 1730,
1821, 1913, 2004, 2100, 2207, 2314, 2420, 2532, 2652, 2783, 2921,
3056, 3189, 3327, 3468, 3640, 3817, 3993, 4171, 4362, 4554, 4751,
4948, 5142, 5346, 5566, 5799, 6044, 6301, 6565, 6852, 7150, 7470,
7797, 8143, 8492, 8835, 9181, 9547, 9919, 10315, 10718, 11136, 11566,
12015, 12482, 12967, 13458, 13953, 14432, 14903, 15416, 15936, 16452, 16967,
17492, 18024, 18600, 19173, 19736, 20311, 20911, 21490, 22041, 22597, 23157,
23768, 24405, 25034, 25660, 26280, 26899, 27614, 28331, 29015, 29702, 30403,
31107, 31817, 32566, 33381, 34224, 35099, 36112, 37222, 38375, 39549, 40801,
42074, 43350, 44626, 45982, 47354, 48860, 50361, 51845, 53312, 54739, 56026,
57116, 58104, 58996, 59842, 60658, 61488, 62324, 63057, 63769, 64285, 64779,
65076, 65344, 65430, 65500, 65517, 65535
};
/*
* An array of pointers to CDFs of decorrelated LPC Gains
*/
const uint16_t* WebRtcIsac_kLpcGainCdfMat[SUBFRAMES] =
{
WebRtcIsac_kLpcGainCdfVec0, WebRtcIsac_kLpcGainCdfVec1,
WebRtcIsac_kLpcGainCdfVec2, WebRtcIsac_kLpcGainCdfVec3,
WebRtcIsac_kLpcGainCdfVec4, WebRtcIsac_kLpcGainCdfVec5
};
/*
* A matrix to decorrellate LPC gains of subframes.
*/
const double WebRtcIsac_kLpcGainDecorrMat[SUBFRAMES][SUBFRAMES] =
{
{-0.150860, 0.327872, 0.367220, 0.504613, 0.559270, 0.409234},
{ 0.457128, -0.613591, -0.289283, -0.029734, 0.393760, 0.418240},
{-0.626043, 0.136489, -0.439118, -0.448323, 0.135987, 0.420869},
{ 0.526617, 0.480187, 0.242552, -0.488754, -0.158713, 0.411331},
{-0.302587, -0.494953, 0.588112, -0.063035, -0.404290, 0.387510},
{ 0.086378, 0.147714, -0.428875, 0.548300, -0.570121, 0.401391}
};

View File

@@ -0,0 +1,49 @@
/*
* 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.
*/
/*
* SWB_KLT_Tables_LPCGain.h
*
* This file declares tables used for entropy coding of LPC Gain
* of upper-band.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
#include "settings.h"
#include "typedefs.h"
extern const double WebRtcIsac_kQSizeLpcGain;
extern const double WebRtcIsac_kLeftRecPointLpcGain[SUBFRAMES];
extern const int16_t WebRtcIsac_kNumQCellLpcGain[SUBFRAMES];
extern const uint16_t WebRtcIsac_kLpcGainEntropySearch[SUBFRAMES];
extern const uint16_t WebRtcIsac_kLpcGainCdfVec0[18];
extern const uint16_t WebRtcIsac_kLpcGainCdfVec1[21];
extern const uint16_t WebRtcIsac_kLpcGainCdfVec2[26];
extern const uint16_t WebRtcIsac_kLpcGainCdfVec3[46];
extern const uint16_t WebRtcIsac_kLpcGainCdfVec4[78];
extern const uint16_t WebRtcIsac_kLpcGainCdfVec5[171];
extern const uint16_t* WebRtcIsac_kLpcGainCdfMat[SUBFRAMES];
extern const double WebRtcIsac_kLpcGainDecorrMat[SUBFRAMES][SUBFRAMES];
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_

View File

@@ -0,0 +1,159 @@
/*
* 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.
*/
/*
* SWB_KLT_Tables.c
*
* This file defines tables used for entropy coding of LPC shape of
* upper-band signal if the bandwidth is 12 kHz.
*
*/
#include "lpc_shape_swb12_tables.h"
#include "settings.h"
#include "typedefs.h"
/*
* Mean value of LAR
*/
const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER] =
{
0.03748928306641, 0.09453441192543, -0.01112522344398, 0.03800237516842
};
/*
* A rotation matrix to decorrelate intra-vector correlation,
* i.e. correlation among components of LAR vector.
*/
const double WebRtcIsac_kIntraVecDecorrMatUb12[UB_LPC_ORDER][UB_LPC_ORDER] =
{
{-0.00075365493856, -0.05809964887743, -0.23397966154116, 0.97050367376411},
{ 0.00625021257734, -0.17299965610679, 0.95977735920651, 0.22104179375008},
{ 0.20543384258374, -0.96202143495696, -0.15301870801552, -0.09432375099565},
{-0.97865075648479, -0.20300322280841, -0.02581111653779, -0.01913568980258}
};
/*
* A rotation matrix to remove correlation among LAR coefficients
* of different LAR vectors. One might guess that decorrelation matrix
* for the first component should differ from the second component
* but we haven't observed a significant benefit of having different
* decorrelation matrices for different components.
*/
const double WebRtcIsac_kInterVecDecorrMatUb12
[UB_LPC_VEC_PER_FRAME][UB_LPC_VEC_PER_FRAME] =
{
{ 0.70650597970460, -0.70770707262373},
{-0.70770707262373, -0.70650597970460}
};
/*
* LAR quantization step-size.
*/
const double WebRtcIsac_kLpcShapeQStepSizeUb12 = 0.150000;
/*
* The smallest reconstruction points for quantiztion of LAR coefficients.
*/
const double WebRtcIsac_kLpcShapeLeftRecPointUb12
[UB_LPC_ORDER*UB_LPC_VEC_PER_FRAME] =
{
-0.900000, -1.050000, -1.350000, -1.800000, -1.350000, -1.650000,
-2.250000, -3.450000
};
/*
* Number of reconstruction points of quantizers for LAR coefficients.
*/
const int16_t WebRtcIsac_kLpcShapeNumRecPointUb12
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] =
{
13, 15, 19, 27, 19, 24, 32, 48
};
/*
* Starting index for entropy decoder to search for the right interval,
* one entry per LAR coefficient
*/
const uint16_t WebRtcIsac_kLpcShapeEntropySearchUb12
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] =
{
6, 7, 9, 13, 9, 12, 16, 24
};
/*
* The following 8 vectors define CDF of 8 decorrelated LAR
* coefficients.
*/
const uint16_t WebRtcIsac_kLpcShapeCdfVec0Ub12[14] =
{
0, 13, 95, 418, 1687, 6498, 21317, 44200, 59029, 63849, 65147,
65449, 65525, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec1Ub12[16] =
{
0, 10, 59, 255, 858, 2667, 8200, 22609, 42988, 57202, 62947,
64743, 65308, 65476, 65522, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec2Ub12[20] =
{
0, 18, 40, 118, 332, 857, 2017, 4822, 11321, 24330, 41279,
54342, 60637, 63394, 64659, 65184, 65398, 65482, 65518, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec3Ub12[28] =
{
0, 21, 38, 90, 196, 398, 770, 1400, 2589, 4650, 8211,
14933, 26044, 39592, 50814, 57452, 60971, 62884, 63995, 64621, 65019, 65273,
65410, 65480, 65514, 65522, 65531, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec4Ub12[20] =
{
0, 7, 46, 141, 403, 969, 2132, 4649, 10633, 24902, 43254,
54665, 59928, 62674, 64173, 64938, 65293, 65464, 65523, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec5Ub12[25] =
{
0, 7, 22, 72, 174, 411, 854, 1737, 3545, 6774, 13165,
25221, 40980, 52821, 58714, 61706, 63472, 64437, 64989, 65287, 65430, 65503,
65525, 65529, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec6Ub12[33] =
{
0, 11, 21, 36, 65, 128, 228, 401, 707, 1241, 2126,
3589, 6060, 10517, 18853, 31114, 42477, 49770, 54271, 57467, 59838, 61569,
62831, 63772, 64433, 64833, 65123, 65306, 65419, 65466, 65499, 65519, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec7Ub12[49] =
{
0, 14, 34, 67, 107, 167, 245, 326, 449, 645, 861,
1155, 1508, 2003, 2669, 3544, 4592, 5961, 7583, 9887, 13256, 18765,
26519, 34077, 40034, 44349, 47795, 50663, 53262, 55473, 57458, 59122, 60592,
61742, 62690, 63391, 63997, 64463, 64794, 65045, 65207, 65309, 65394, 65443,
65478, 65504, 65514, 65523, 65535
};
/*
* An array of pointers to CDFs of decorrelated LARs
*/
const uint16_t* WebRtcIsac_kLpcShapeCdfMatUb12
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME] =
{
WebRtcIsac_kLpcShapeCdfVec0Ub12, WebRtcIsac_kLpcShapeCdfVec1Ub12,
WebRtcIsac_kLpcShapeCdfVec2Ub12, WebRtcIsac_kLpcShapeCdfVec3Ub12,
WebRtcIsac_kLpcShapeCdfVec4Ub12, WebRtcIsac_kLpcShapeCdfVec5Ub12,
WebRtcIsac_kLpcShapeCdfVec6Ub12, WebRtcIsac_kLpcShapeCdfVec7Ub12
};

View File

@@ -0,0 +1,65 @@
/*
* 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.
*/
/*
* lpc_shape_swb12_tables.h
*
* This file declares tables used for entropy coding of LPC shape of
* upper-band signal if the bandwidth is 12 kHz.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
#include "settings.h"
#include "typedefs.h"
extern const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER];
extern const double WebRtcIsac_kMeanLpcGain;
extern const double WebRtcIsac_kIntraVecDecorrMatUb12[UB_LPC_ORDER][UB_LPC_ORDER];
extern const double WebRtcIsac_kInterVecDecorrMatUb12
[UB_LPC_VEC_PER_FRAME][UB_LPC_VEC_PER_FRAME];
extern const double WebRtcIsac_kLpcShapeQStepSizeUb12;
extern const double WebRtcIsac_kLpcShapeLeftRecPointUb12
[UB_LPC_ORDER*UB_LPC_VEC_PER_FRAME];
extern const int16_t WebRtcIsac_kLpcShapeNumRecPointUb12
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
extern const uint16_t WebRtcIsac_kLpcShapeEntropySearchUb12
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec0Ub12[14];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec1Ub12[16];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec2Ub12[20];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec3Ub12[28];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec4Ub12[20];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec5Ub12[25];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec6Ub12[33];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec7Ub12[49];
extern const uint16_t* WebRtcIsac_kLpcShapeCdfMatUb12
[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_

View File

@@ -0,0 +1,248 @@
/*
* 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.
*/
/*
* SWB16_KLT_Tables.c
*
* This file defines tables used for entropy coding of LPC shape of
* upper-band signal if the bandwidth is 16 kHz.
*
*/
#include "lpc_shape_swb16_tables.h"
#include "settings.h"
#include "typedefs.h"
/*
* Mean value of LAR
*/
const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER] =
{
0.454978, 0.364747, 0.102999, 0.104523
};
/*
* A rotation matrix to decorrelate intra-vector correlation,
* i.e. correlation among components of LAR vector.
*/
const double WebRtcIsac_kIintraVecDecorrMatUb16[UB_LPC_ORDER][UB_LPC_ORDER] =
{
{-0.020528, -0.085858, -0.002431, 0.996093},
{-0.033155, 0.036102, 0.998786, 0.004866},
{ 0.202627, 0.974853, -0.028940, 0.088132},
{-0.978479, 0.202454, -0.039785, -0.002811}
};
/*
* A rotation matrix to remove correlation among LAR coefficients
* of different LAR vectors. One might guess that decorrelation matrix
* for the first component should differ from the second component
* but we haven't observed a significant benefit of having different
* decorrelation matrices for different components.
*/
const double WebRtcIsac_kInterVecDecorrMatUb16
[UB16_LPC_VEC_PER_FRAME][UB16_LPC_VEC_PER_FRAME] =
{
{ 0.291675, -0.515786, 0.644927, 0.482658},
{-0.647220, 0.479712, 0.289556, 0.516856},
{ 0.643084, 0.485489, -0.289307, 0.516763},
{-0.287185, -0.517823, -0.645389, 0.482553}
};
/*
* The following 16 vectors define CDF of 16 decorrelated LAR
* coefficients.
*/
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub16[14] =
{
0, 2, 20, 159, 1034, 5688, 20892, 44653,
59849, 64485, 65383, 65518, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec1Ub16[16] =
{
0, 1, 7, 43, 276, 1496, 6681, 21653,
43891, 58859, 64022, 65248, 65489, 65529, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec2Ub16[18] =
{
0, 1, 9, 54, 238, 933, 3192, 9461,
23226, 42146, 56138, 62413, 64623, 65300, 65473, 65521,
65533, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec3Ub16[30] =
{
0, 2, 4, 8, 17, 36, 75, 155,
329, 683, 1376, 2662, 5047, 9508, 17526, 29027,
40363, 48997, 55096, 59180, 61789, 63407, 64400, 64967,
65273, 65429, 65497, 65526, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec4Ub16[16] =
{
0, 1, 10, 63, 361, 1785, 7407, 22242,
43337, 58125, 63729, 65181, 65472, 65527, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec5Ub16[17] =
{
0, 1, 7, 29, 134, 599, 2443, 8590,
22962, 42635, 56911, 63060, 64940, 65408, 65513, 65531,
65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec6Ub16[21] =
{
0, 1, 5, 16, 57, 191, 611, 1808,
4847, 11755, 24612, 40910, 53789, 60698, 63729, 64924,
65346, 65486, 65523, 65532, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec7Ub16[36] =
{
0, 1, 4, 12, 25, 55, 104, 184,
314, 539, 926, 1550, 2479, 3861, 5892, 8845,
13281, 20018, 29019, 38029, 45581, 51557, 56057, 59284,
61517, 63047, 64030, 64648, 65031, 65261, 65402, 65480,
65518, 65530, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec8Ub16[21] =
{
0, 1, 2, 7, 26, 103, 351, 1149,
3583, 10204, 23846, 41711, 55361, 61917, 64382, 65186,
65433, 65506, 65528, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub160[21] =
{
0, 6, 19, 63, 205, 638, 1799, 4784,
11721, 24494, 40803, 53805, 60886, 63822, 64931, 65333,
65472, 65517, 65530, 65533, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub161[28] =
{
0, 1, 3, 11, 31, 86, 221, 506,
1101, 2296, 4486, 8477, 15356, 26079, 38941, 49952,
57165, 61257, 63426, 64549, 65097, 65351, 65463, 65510,
65526, 65532, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub162[55] =
{
0, 3, 12, 23, 42, 65, 89, 115,
150, 195, 248, 327, 430, 580, 784, 1099,
1586, 2358, 3651, 5899, 9568, 14312, 19158, 23776,
28267, 32663, 36991, 41153, 45098, 48680, 51870, 54729,
57141, 59158, 60772, 62029, 63000, 63761, 64322, 64728,
65000, 65192, 65321, 65411, 65463, 65496, 65514, 65523,
65527, 65529, 65531, 65532, 65533, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub163[26] =
{
0, 2, 4, 10, 21, 48, 114, 280,
701, 1765, 4555, 11270, 24267, 41213, 54285, 61003,
63767, 64840, 65254, 65421, 65489, 65514, 65526, 65532,
65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub164[28] =
{
0, 1, 3, 6, 15, 36, 82, 196,
453, 1087, 2557, 5923, 13016, 25366, 40449, 52582,
59539, 62896, 64389, 65033, 65316, 65442, 65494, 65519,
65529, 65533, 65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub165[34] =
{
0, 2, 4, 8, 18, 35, 73, 146,
279, 524, 980, 1789, 3235, 5784, 10040, 16998,
27070, 38543, 48499, 55421, 59712, 62257, 63748, 64591,
65041, 65278, 65410, 65474, 65508, 65522, 65530, 65533,
65534, 65535
};
const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub166[71] =
{
0, 1, 2, 6, 13, 26, 55, 92,
141, 191, 242, 296, 355, 429, 522, 636,
777, 947, 1162, 1428, 1753, 2137, 2605, 3140,
3743, 4409, 5164, 6016, 6982, 8118, 9451, 10993,
12754, 14810, 17130, 19780, 22864, 26424, 30547, 35222,
40140, 44716, 48698, 52056, 54850, 57162, 59068, 60643,
61877, 62827, 63561, 64113, 64519, 64807, 65019, 65167,
65272, 65343, 65399, 65440, 65471, 65487, 65500, 65509,
65518, 65524, 65527, 65531, 65533, 65534, 65535
};
/*
* An array of pointers to CDFs of decorrelated LARs
*/
const uint16_t* WebRtcIsac_kLpcShapeCdfMatUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] = {
WebRtcIsac_kLpcShapeCdfVec01Ub16,
WebRtcIsac_kLpcShapeCdfVec1Ub16,
WebRtcIsac_kLpcShapeCdfVec2Ub16,
WebRtcIsac_kLpcShapeCdfVec3Ub16,
WebRtcIsac_kLpcShapeCdfVec4Ub16,
WebRtcIsac_kLpcShapeCdfVec5Ub16,
WebRtcIsac_kLpcShapeCdfVec6Ub16,
WebRtcIsac_kLpcShapeCdfVec7Ub16,
WebRtcIsac_kLpcShapeCdfVec8Ub16,
WebRtcIsac_kLpcShapeCdfVec01Ub160,
WebRtcIsac_kLpcShapeCdfVec01Ub161,
WebRtcIsac_kLpcShapeCdfVec01Ub162,
WebRtcIsac_kLpcShapeCdfVec01Ub163,
WebRtcIsac_kLpcShapeCdfVec01Ub164,
WebRtcIsac_kLpcShapeCdfVec01Ub165,
WebRtcIsac_kLpcShapeCdfVec01Ub166
};
/*
* The smallest reconstruction points for quantiztion of LAR coefficients.
*/
const double WebRtcIsac_kLpcShapeLeftRecPointUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] =
{
-0.8250, -0.9750, -1.1250, -2.1750, -0.9750, -1.1250, -1.4250,
-2.6250, -1.4250, -1.2750, -1.8750, -3.6750, -1.7250, -1.8750,
-2.3250, -5.4750
};
/*
* Number of reconstruction points of quantizers for LAR coefficients.
*/
const int16_t WebRtcIsac_kLpcShapeNumRecPointUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] =
{
13, 15, 17, 29, 15, 16, 20, 35, 20,
20, 27, 54, 25, 27, 33, 70
};
/*
* Starting index for entropy decoder to search for the right interval,
* one entry per LAR coefficient
*/
const uint16_t WebRtcIsac_kLpcShapeEntropySearchUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME] =
{
6, 7, 8, 14, 7, 8, 10, 17, 10,
10, 13, 27, 12, 13, 16, 35
};
/*
* LAR quantization step-size.
*/
const double WebRtcIsac_kLpcShapeQStepSizeUb16 = 0.150000;

View File

@@ -0,0 +1,79 @@
/*
* 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.
*/
/*
* lpc_shape_swb16_tables.h
*
* This file declares tables used for entropy coding of LPC shape of
* upper-band signal if the bandwidth is 16 kHz.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
#include "settings.h"
#include "typedefs.h"
extern const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER];
extern const double WebRtcIsac_kIintraVecDecorrMatUb16[UB_LPC_ORDER][UB_LPC_ORDER];
extern const double WebRtcIsac_kInterVecDecorrMatUb16
[UB16_LPC_VEC_PER_FRAME][UB16_LPC_VEC_PER_FRAME];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub16[14];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec1Ub16[16];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec2Ub16[18];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec3Ub16[30];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec4Ub16[16];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec5Ub16[17];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec6Ub16[21];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec7Ub16[36];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec8Ub16[21];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub160[21];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub161[28];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub162[55];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub163[26];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub164[28];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub165[34];
extern const uint16_t WebRtcIsac_kLpcShapeCdfVec01Ub166[71];
extern const uint16_t* WebRtcIsac_kLpcShapeCdfMatUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
extern const double WebRtcIsac_kLpcShapeLeftRecPointUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
extern const int16_t WebRtcIsac_kLpcShapeNumRecPointUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
extern const uint16_t WebRtcIsac_kLpcShapeEntropySearchUb16
[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
extern const double WebRtcIsac_kLpcShapeQStepSizeUb16;
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_

View File

@@ -0,0 +1,601 @@
/*
* Copyright (c) 2012 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.
*/
/* coding tables for the KLT coefficients */
#include "lpc_tables.h"
#include "settings.h"
/* cdf array for model indicator */
const uint16_t WebRtcIsac_kQKltModelCdf[4] = {
0, 15434, 37548, 65535 };
/* pointer to cdf array for model indicator */
const uint16_t *WebRtcIsac_kQKltModelCdfPtr[1] = {
WebRtcIsac_kQKltModelCdf };
/* initial cdf index for decoder of model indicator */
const uint16_t WebRtcIsac_kQKltModelInitIndex[1] = { 1 };
/* offset to go from rounded value to quantization index */
const short WebRtcIsac_kQKltQuantMinGain[12] = {
3, 6, 4, 6, 6, 9, 5, 16, 11, 34, 32, 47 };
const short WebRtcIsac_kQKltQuantMinShape[108] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 2, 2, 2, 3, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 2, 2, 3, 0, 0, 0, 0,
1, 0, 1, 1, 1, 1, 1, 1, 1, 2,
2, 4, 3, 5, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 2, 1, 2, 2, 3, 4,
4, 7, 0, 0, 1, 1, 1, 1, 1, 1,
1, 2, 3, 2, 3, 4, 4, 5, 7, 13,
0, 1, 1, 2, 3, 2, 2, 2, 4, 4,
5, 6, 7, 11, 9, 13, 12, 26 };
/* maximum quantization index */
const uint16_t WebRtcIsac_kQKltMaxIndGain[12] = {
6, 12, 8, 14, 10, 19, 12, 31, 22, 56, 52, 138 };
const uint16_t WebRtcIsac_kQKltMaxIndShape[108] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
2, 2, 2, 2, 4, 4, 5, 6, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 2, 2,
2, 2, 3, 4, 5, 7, 0, 0, 0, 0,
2, 0, 2, 2, 2, 2, 3, 2, 2, 4,
4, 6, 6, 9, 0, 0, 0, 0, 2, 2,
2, 2, 2, 2, 3, 2, 4, 4, 7, 7,
9, 13, 0, 0, 2, 2, 2, 2, 2, 2,
3, 4, 5, 4, 6, 8, 8, 10, 16, 25,
0, 2, 2, 4, 5, 4, 4, 4, 7, 8,
9, 10, 13, 19, 17, 23, 25, 49 };
/* index offset */
const uint16_t WebRtcIsac_kQKltOffsetGain[12] = {
0, 7, 20, 29, 44, 55, 75, 88, 120, 143, 200, 253 };
const uint16_t WebRtcIsac_kQKltOffsetShape[108] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
11, 14, 17, 20, 23, 28, 33, 39, 46, 47,
48, 49, 50, 52, 53, 54, 55, 56, 58, 61,
64, 67, 70, 74, 79, 85, 93, 94, 95, 96,
97, 100, 101, 104, 107, 110, 113, 117, 120, 123,
128, 133, 140, 147, 157, 158, 159, 160, 161, 164,
167, 170, 173, 176, 179, 183, 186, 191, 196, 204,
212, 222, 236, 237, 238, 241, 244, 247, 250, 253,
256, 260, 265, 271, 276, 283, 292, 301, 312, 329,
355, 356, 359, 362, 367, 373, 378, 383, 388, 396,
405, 415, 426, 440, 460, 478, 502, 528 };
/* initial cdf index for KLT coefficients */
const uint16_t WebRtcIsac_kQKltInitIndexGain[12] = {
3, 6, 4, 7, 5, 10, 6, 16, 11, 28, 26, 69};
const uint16_t WebRtcIsac_kQKltInitIndexShape[108] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 2, 2, 3, 3, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 1, 1,
1, 1, 2, 2, 3, 4, 0, 0, 0, 0,
1, 0, 1, 1, 1, 1, 2, 1, 1, 2,
2, 3, 3, 5, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 2, 1, 2, 2, 4, 4,
5, 7, 0, 0, 1, 1, 1, 1, 1, 1,
2, 2, 3, 2, 3, 4, 4, 5, 8, 13,
0, 1, 1, 2, 3, 2, 2, 2, 4, 4,
5, 5, 7, 10, 9, 12, 13, 25 };
/* quantizer representation levels */
const double WebRtcIsac_kQKltLevelsGain[392] = {
-2.78127126, -1.76745590, -0.77913790, -0.00437329, 0.79961206,
1.81775776, 2.81389782, -5.78753143, -4.88384084, -3.89320940,
-2.88133610, -1.92859977, -0.86347396, 0.02003888, 0.86140400,
1.89667156, 2.97134967, 3.98781964, 4.91727277, 5.82865898,
-4.11195874, -2.80898424, -1.87547977, -0.80943825, -0.00679084,
0.79573851, 1.83953397, 2.67586037, 3.76274082, -6.10933968,
-4.93034581, -3.89281296, -2.91530625, -1.89684163, -0.85319130,
-0.02275767, 0.86862017, 1.91578276, 2.96107339, 3.96543056,
4.91369908, 5.91058154, 6.83848343, 8.07136925, -5.87470395,
-4.84703049, -3.84284597, -2.86168446, -1.89290192, -0.82798145,
-0.00080013, 0.82594974, 1.85754329, 2.88351798, 3.96172628,
-8.85684885, -7.87387461, -6.97811862, -5.93256270, -4.94301439,
-3.95513701, -2.96041544, -1.94031192, -0.87961478, -0.00456201,
0.89911505, 1.91723376, 2.94011511, 3.93302540, 4.97990967,
5.93133404, 7.02181199, 7.92407762, 8.80155440, 10.04665814,
-4.82396678, -3.85612158, -2.89482244, -1.89558408, -0.90036978,
-0.00677823, 0.90607989, 1.90937981, 2.91175777, 3.91637730,
4.97565723, 5.84771228, 7.11145863, -16.07879840, -15.03776309,
-13.93905670, -12.95671800, -11.89171202, -10.95820934, -9.95923714,
-8.94357334, -7.99068299, -6.97481009, -5.94826231, -4.96673988,
-3.97490466, -2.97846970, -1.95130435, -0.94215262, -0.01444043,
0.96770704, 1.95848598, 2.94107862, 3.95666119, 4.97253085,
5.97191122, 6.93277360, 7.96608727, 8.87958779, 10.00264269,
10.86560820, 12.07449071, 13.04491775, 13.97507061, 14.91845261,
-10.85696295, -9.83365357, -9.01245635, -7.95915145, -6.95625003,
-5.95362618, -4.93468444, -3.98760978, -2.95044407, -1.97041277,
-0.97701799, -0.00840234, 0.97834289, 1.98361415, 2.97802439,
3.96415871, 4.95369042, 5.94101770, 6.92756798, 7.94063998,
8.85951828, 9.97077022, 11.00068503, -33.92030406, -32.81426422,
-32.00000000, -31.13243639, -30.11886909, -29.06017570, -28.12598824,
-27.22045482, -25.81215858, -25.07849962, -23.93018013, -23.02097643,
-21.89529725, -20.99091085, -19.98889048, -18.94327044, -17.96562071,
-16.96126218, -15.95054062, -14.98516200, -13.97101012, -13.02106500,
-11.98438006, -11.03216748, -9.95930286, -8.97043946, -7.98085082,
-6.98360995, -5.98998802, -4.98668173, -4.00032906, -3.00420619,
-1.98701132, -0.99324682, -0.00609324, 0.98297834, 1.99483076,
3.00305044, 3.97142097, 4.97525759, 5.98612258, 6.97448236,
7.97575900, 9.01086211, 9.98665542, 11.00541438, 11.98078628,
12.92352471, 14.06849675, 14.99949430, 15.94904834, 16.97440321,
18.04040916, 18.88987609, 20.05312391, 21.00000000, 21.79443341,
-31.98578825, -31.00000000, -29.89060567, -28.98555686, -27.97114102,
-26.84935410, -26.02402230, -24.94195278, -23.92336849, -22.95552382,
-21.97932836, -20.96055470, -19.99649553, -19.03436122, -17.96706525,
-17.01139515, -16.01363516, -14.99154248, -14.00298333, -12.99630613,
-11.99955519, -10.99000421, -10.00819092, -8.99763648, -7.98431793,
-7.01769025, -5.99604690, -4.99980697, -3.99334671, -3.01748192,
-2.02051217, -1.00848371, -0.01942358, 1.00477757, 1.95477872,
2.98593031, 3.98779079, 4.96862849, 6.02694771, 6.93983733,
7.89874717, 8.99615862, 10.02367921, 10.96293452, 11.84351528,
12.92207187, 13.85122329, 15.05146877, 15.99371264, 17.00000000,
18.00000000, 19.00000000, 19.82763573, -47.00000000, -46.00000000,
-44.87138498, -44.00000000, -43.00000000, -42.00000000, -41.00000000,
-39.88966612, -38.98913239, -37.80306486, -37.23584325, -35.94200288,
-34.99881301, -34.11361858, -33.06507360, -32.13129135, -30.90891364,
-29.81511907, -28.99250380, -28.04535391, -26.99767800, -26.04418164,
-24.95687851, -24.04865595, -23.03392645, -21.89366707, -20.93517364,
-19.99388660, -18.91620943, -18.03749683, -16.99532379, -15.98683813,
-15.06421479, -13.99359211, -12.99714098, -11.97022520, -10.98500279,
-9.98834422, -8.95729330, -8.01232284, -7.00253661, -5.99681626,
-5.01207817, -3.95914904, -3.01232178, -1.96615919, -0.97687670,
0.01228030, 0.98412288, 2.01753544, 3.00580570, 3.97783510,
4.98846894, 6.01321400, 7.00867732, 8.00416375, 9.01771966,
9.98637729, 10.98255180, 11.99194163, 13.01807333, 14.00999545,
15.00118556, 16.00089224, 17.00584148, 17.98251763, 18.99942091,
19.96917690, 20.97839265, 21.98207297, 23.00171271, 23.99930737,
24.99746061, 26.00936304, 26.98240132, 28.01126868, 29.01395915,
29.98153507, 31.01376711, 31.99876818, 33.00475317, 33.99753994,
34.99493913, 35.98933585, 36.95620160, 37.98428461, 38.99317544,
40.01832073, 40.98048133, 41.95999283, 42.98232091, 43.96523612,
44.99574268, 45.99524194, 47.05464025, 48.03821548, 48.99354366,
49.96400411, 50.98017973, 51.95184408, 52.96291806, 54.00194392,
54.96603783, 55.95623778, 57.03076595, 58.05889901, 58.99081551,
59.97928121, 61.05071612, 62.03971580, 63.01286038, 64.01290338,
65.02074503, 65.99454594, 67.00399425, 67.96571257, 68.95305727,
69.92030664, 70.95594862, 71.98088567, 73.04764124, 74.00285480,
75.02696330, 75.89837673, 76.93459997, 78.16266309, 78.83317543,
80.00000000, 80.87251574, 82.09803524, 83.10671664, 84.00000000,
84.77023523, 86.00000000, 87.00000000, 87.92946897, 88.69159118,
90.00000000, 90.90535270 };
const double WebRtcIsac_kQKltLevelsShape[578] = {
0.00032397, 0.00008053, -0.00061202, -0.00012620, 0.00030437,
0.00054764, -0.00027902, 0.00069360, 0.00029449, -0.80219239,
0.00091089, -0.74514927, -0.00094283, 0.64030631, -0.60509119,
0.00035575, 0.61851665, -0.62129957, 0.00375219, 0.60054900,
-0.61554359, 0.00054977, 0.63362016, -1.73118727, -0.65422341,
0.00524568, 0.66165298, 1.76785515, -1.83182018, -0.65997434,
-0.00011887, 0.67524299, 1.79933938, -1.76344480, -0.72547708,
-0.00133017, 0.73104704, 1.75305377, 2.85164534, -2.80423916,
-1.71959639, -0.75419722, -0.00329945, 0.77196760, 1.72211069,
2.87339653, 0.00031089, -0.00015311, 0.00018201, -0.00035035,
-0.77357251, 0.00154647, -0.00047625, -0.00045299, 0.00086590,
0.00044762, -0.83383829, 0.00024787, -0.68526258, -0.00122472,
0.64643255, -0.60904942, -0.00448987, 0.62309184, -0.59626442,
-0.00574132, 0.62296546, -0.63222115, 0.00013441, 0.63609545,
-0.66911055, -0.00369971, 0.66346095, 2.07281301, -1.77184694,
-0.67640425, -0.00010145, 0.64818392, 1.74948973, -1.69420224,
-0.71943894, -0.00004680, 0.75303493, 1.81075983, 2.80610041,
-2.80005755, -1.79866753, -0.77409777, -0.00084220, 0.80141293,
1.78291081, 2.73954236, 3.82994169, 0.00015140, -0.00012766,
-0.00034241, -0.00119125, -0.76113497, 0.00069246, 0.76722027,
0.00132862, -0.69107530, 0.00010656, 0.77061578, -0.78012970,
0.00095947, 0.77828502, -0.64787758, 0.00217168, 0.63050167,
-0.58601125, 0.00306596, 0.59466308, -0.58603410, 0.00059779,
0.64257970, 1.76512766, -0.61193600, -0.00259517, 0.59767574,
-0.61026273, 0.00315811, 0.61725479, -1.69169719, -0.65816029,
0.00067575, 0.65576890, 2.00000000, -1.72689193, -0.69780808,
-0.00040990, 0.70668487, 1.74198458, -3.79028154, -3.00000000,
-1.73194459, -0.70179341, -0.00106695, 0.71302629, 1.76849782,
-2.89332364, -1.78585007, -0.78731491, -0.00132610, 0.79692976,
1.75247009, 2.97828682, -5.26238694, -3.69559829, -2.87286122,
-1.84908818, -0.84434577, -0.01167975, 0.84641753, 1.84087672,
2.87628156, 3.83556679, -0.00190204, 0.00092642, 0.00354385,
-0.00012982, -0.67742785, 0.00229509, 0.64935672, -0.58444751,
0.00470733, 0.57299534, -0.58456202, -0.00097715, 0.64593607,
-0.64060330, -0.00638534, 0.59680157, -0.59287537, 0.00490772,
0.58919707, -0.60306173, -0.00417464, 0.60562100, -1.75218757,
-0.63018569, -0.00225922, 0.63863300, -0.63949939, -0.00126421,
0.64268914, -1.75851182, -0.68318060, 0.00510418, 0.69049211,
1.88178506, -1.71136148, -0.72710534, -0.00815559, 0.73412917,
1.79996711, -2.77111145, -1.73940498, -0.78212945, 0.01074476,
0.77688916, 1.76873972, 2.87281379, 3.77554698, -3.75832725,
-2.95463235, -1.80451491, -0.80017226, 0.00149902, 0.80729206,
1.78265046, 2.89391793, -3.78236148, -2.83640598, -1.82532067,
-0.88844327, -0.00620952, 0.88208030, 1.85757631, 2.81712391,
3.88430176, 5.16179367, -7.00000000, -5.93805408, -4.87172597,
-3.87524433, -2.89399744, -1.92359563, -0.92136341, -0.00172725,
0.93087018, 1.90528280, 2.89809686, 3.88085708, 4.89147740,
5.89078692, -0.00239502, 0.00312564, -1.00000000, 0.00178325,
1.00000000, -0.62198029, 0.00143254, 0.65344051, -0.59851220,
-0.00676987, 0.61510140, -0.58894151, 0.00385055, 0.59794203,
-0.59808568, -0.00038214, 0.57625703, -0.63009713, -0.01107985,
0.61278758, -0.64206758, -0.00154369, 0.65480598, 1.80604162,
-1.80909286, -0.67810514, 0.00205762, 0.68571097, 1.79453891,
-3.22682422, -1.73808453, -0.71870305, -0.00738594, 0.71486172,
1.73005326, -1.66891897, -0.73689615, -0.00616203, 0.74262409,
1.73807899, -2.92417482, -1.73866741, -0.78133871, 0.00764425,
0.80027264, 1.78668732, 2.74992588, -4.00000000, -2.75578740,
-1.83697516, -0.83117035, -0.00355191, 0.83527172, 1.82814700,
2.77377675, 3.80718693, -3.81667698, -2.83575471, -1.83372350,
-0.86579471, 0.00547578, 0.87582281, 1.82858793, 2.87265007,
3.91405377, -4.87521600, -3.78999094, -2.86437014, -1.86964365,
-0.90618018, 0.00128243, 0.91497811, 1.87374952, 2.83199819,
3.91519130, 4.76632822, -6.68713448, -6.01252467, -4.94587936,
-3.88795368, -2.91299088, -1.92592211, -0.95504570, -0.00089980,
0.94565200, 1.93239633, 2.91832808, 3.91363475, 4.88920034,
5.96471415, 6.83905252, 7.86195009, 8.81571018,-12.96141759,
-11.73039516,-10.96459719, -9.97382433, -9.04414433, -7.89460619,
-6.96628608, -5.93236595, -4.93337924, -3.95479990, -2.96451499,
-1.96635876, -0.97271229, -0.00402238, 0.98343930, 1.98348291,
2.96641164, 3.95456471, 4.95517089, 5.98975714, 6.90322073,
7.90468849, 8.85639467, 9.97255498, 10.79006309, 11.81988596,
0.04950500, -1.00000000, -0.01226628, 1.00000000, -0.59479469,
-0.10438305, 0.59822144, -2.00000000, -0.67109149, -0.09256692,
0.65171621, 2.00000000, -3.00000000, -1.68391999, -0.76681039,
-0.03354151, 0.71509146, 1.77615472, -2.00000000, -0.68661511,
-0.02497881, 0.66478398, 2.00000000, -2.00000000, -0.67032784,
-0.00920582, 0.64892756, 2.00000000, -2.00000000, -0.68561894,
0.03641869, 0.73021611, 1.68293863, -4.00000000, -2.72024184,
-1.80096059, -0.81696185, 0.03604685, 0.79232033, 1.70070730,
3.00000000, -4.00000000, -2.71795670, -1.80482986, -0.86001162,
0.03764903, 0.87723968, 1.79970771, 2.72685932, 3.67589143,
-5.00000000, -4.00000000, -2.85492548, -1.78996365, -0.83250358,
-0.01376828, 0.84195506, 1.78161105, 2.76754458, 4.00000000,
-6.00000000, -5.00000000, -3.82268811, -2.77563624, -1.82608163,
-0.86486114, -0.02671886, 0.86693165, 1.88422879, 2.86248347,
3.95632216, -7.00000000, -6.00000000, -5.00000000, -3.77533988,
-2.86391432, -1.87052039, -0.90513658, 0.06271236, 0.91083620,
1.85734756, 2.86031688, 3.82019418, 4.94420394, 6.00000000,
-11.00000000,-10.00000000, -9.00000000, -8.00000000, -6.91952415,
-6.00000000, -4.92044374, -3.87845165, -2.87392362, -1.88413020,
-0.91915740, 0.00318517, 0.91602800, 1.89664838, 2.88925058,
3.84123856, 4.78988651, 5.94526812, 6.81953917, 8.00000000,
-9.00000000, -8.00000000, -7.03319143, -5.94530963, -4.86669720,
-3.92438007, -2.88620396, -1.92848070, -0.94365985, 0.01671855,
0.97349410, 1.93419878, 2.89740109, 3.89662823, 4.83235583,
5.88106535, 6.80328232, 8.00000000,-13.00000000,-12.00000000,
-11.00000000,-10.00000000, -9.00000000, -7.86033489, -6.83344055,
-5.89844215, -4.90811454, -3.94841298, -2.95820490, -1.98627966,
-0.99161468, -0.02286136, 0.96055651, 1.95052433, 2.93969396,
3.94304346, 4.88522624, 5.87434241, 6.78309433, 7.87244101,
9.00000000, 10.00000000,-12.09117356,-11.00000000,-10.00000000,
-8.84766108, -7.86934236, -6.98544896, -5.94233429, -4.95583292,
-3.95575986, -2.97085529, -1.98955811, -0.99359873, -0.00485413,
0.98298870, 1.98093258, 2.96430203, 3.95540216, 4.96915010,
5.96775124, 6.99236918, 7.96503302, 8.99864542, 9.85857723,
10.96541926, 11.91647197, 12.71060069,-26.00000000,-25.00000000,
-24.00585596,-23.11642573,-22.14271284,-20.89800711,-19.87815799,
-19.05036354,-17.88555651,-16.86471209,-15.97711073,-14.94012359,
-14.02661226,-12.98243228,-11.97489256,-10.97402777, -9.96425624,
-9.01085220, -7.97372506, -6.98795002, -5.97271328, -5.00191694,
-3.98055849, -2.98458048, -1.99470442, -0.99656768, -0.00825666,
1.00272004, 1.99922218, 2.99357669, 4.01407905, 5.01003897,
5.98115528, 7.00018958, 8.00338125, 8.98981046, 9.98990318,
10.96341479, 11.96866930, 12.99175139, 13.94580443, 14.95745083,
15.98992869, 16.97484646, 17.99630043, 18.93396897, 19.88347741,
20.96532482, 21.92191032, 23.22314702 };
/* cdf tables for quantizer indices */
const uint16_t WebRtcIsac_kQKltCdfGain[404] = {
0, 13, 301, 3730, 61784, 65167, 65489, 65535, 0, 17,
142, 314, 929, 2466, 7678, 56450, 63463, 64740, 65204, 65426,
65527, 65535, 0, 8, 100, 724, 6301, 60105, 65125, 65510,
65531, 65535, 0, 13, 117, 368, 1068, 3010, 11928, 53603,
61177, 63404, 64505, 65108, 65422, 65502, 65531, 65535, 0, 4,
17, 96, 410, 1859, 12125, 54361, 64103, 65305, 65497, 65535,
0, 4, 88, 230, 469, 950, 1746, 3228, 6092, 16592,
44756, 56848, 61256, 63308, 64325, 64920, 65309, 65460, 65502,
65522, 65535, 0, 88, 352, 1675, 6339, 20749, 46686, 59284, 63525,
64949, 65359, 65502, 65527, 65535, 0, 13, 38, 63, 117,
234, 381, 641, 929, 1407, 2043, 2809, 4032, 5753, 8792,
14407, 24308, 38941, 48947, 55403, 59293, 61411, 62688, 63630,
64329, 64840, 65188, 65376, 65472, 65506, 65527, 65531, 65535,
0, 8, 29, 75, 222, 615, 1327, 2801, 5623, 9931, 16094, 24966,
34419, 43458, 50676, 56186, 60055, 62500, 63936, 64765, 65225,
65435, 65514, 65535, 0, 8, 13, 15, 17, 21, 33, 59,
71, 92, 151, 243, 360, 456, 674, 934, 1223, 1583,
1989, 2504, 3031, 3617, 4354, 5154, 6163, 7411, 8780, 10747,
12874, 15591, 18974, 23027, 27436, 32020, 36948, 41830, 46205,
49797, 53042, 56094, 58418, 60360, 61763, 62818, 63559, 64103,
64509, 64798, 65045, 65162, 65288, 65363, 65447, 65506, 65522,
65531, 65533, 65535, 0, 4, 6, 25, 38, 71, 138, 264, 519, 808,
1227, 1825, 2516, 3408, 4279, 5560, 7092, 9197, 11420, 14108,
16947, 20300, 23926, 27459, 31164, 34827, 38575, 42178, 45540,
48747, 51444, 54090, 56426, 58460, 60080, 61595, 62734, 63668,
64275, 64673, 64936, 65112, 65217, 65334, 65426, 65464, 65477,
65489, 65518, 65527, 65529, 65531, 65533, 65535, 0, 2, 4, 8, 10,
12, 14, 16, 21, 33, 50, 71, 84, 92, 105, 138, 180, 255, 318,
377, 435, 473, 511, 590, 682, 758, 913, 1097, 1256, 1449, 1671,
1884, 2169, 2445, 2772, 3157, 3563, 3944, 4375, 4848, 5334, 5820,
6448, 7101, 7716, 8378, 9102, 9956, 10752, 11648, 12707, 13670,
14758, 15910, 17187, 18472, 19627, 20649, 21951, 23169, 24283,
25552, 26862, 28227, 29391, 30764, 31882, 33213, 34432, 35600,
36910, 38116, 39464, 40729, 41872, 43144, 44371, 45514, 46762,
47813, 48968, 50069, 51032, 51974, 52908, 53737, 54603, 55445,
56282, 56990, 57572, 58191, 58840, 59410, 59887, 60264, 60607,
60946, 61269, 61516, 61771, 61960, 62198, 62408, 62558, 62776,
62985, 63207, 63408, 63546, 63739, 63906, 64070, 64237, 64371,
64551, 64677, 64836, 64999, 65095, 65213, 65284, 65338, 65380,
65426, 65447, 65472, 65485, 65487, 65489, 65502, 65510, 65512,
65514, 65516, 65518, 65522, 65531, 65533, 65535 };
const uint16_t WebRtcIsac_kQKltCdfShape[686] = {
0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535,
0, 65535, 0, 65535, 0, 65535, 0, 65535, 0, 4,
65535, 0, 8, 65514, 65535, 0, 29, 65481, 65535, 0,
121, 65439, 65535, 0, 239, 65284, 65535, 0, 8, 779,
64999, 65527, 65535, 0, 8, 888, 64693, 65522, 65535, 0,
29, 2604, 62843, 65497, 65531, 65535, 0, 25, 176, 4576,
61164, 65275, 65527, 65535, 0, 65535, 0, 65535, 0, 65535,
0, 65535, 0, 4, 65535, 0, 65535, 0, 65535, 0,
65535, 0, 65535, 0, 4, 65535, 0, 33, 65502, 65535,
0, 54, 65481, 65535, 0, 251, 65309, 65535, 0, 611,
65074, 65535, 0, 1273, 64292, 65527, 65535, 0, 4, 1809,
63940, 65518, 65535, 0, 88, 4392, 60603, 65426, 65531, 65535,
0, 25, 419, 7046, 57756, 64961, 65514, 65531, 65535, 0,
65535, 0, 65535, 0, 65535, 0, 65535, 0, 4, 65531,
65535, 0, 65535, 0, 8, 65531, 65535, 0, 4, 65527,
65535, 0, 17, 65510, 65535, 0, 42, 65481, 65535, 0,
197, 65342, 65531, 65535, 0, 385, 65154, 65535, 0, 1005,
64522, 65535, 0, 8, 1985, 63469, 65533, 65535, 0, 38,
3119, 61884, 65514, 65535, 0, 4, 6, 67, 4961, 60804,
65472, 65535, 0, 17, 565, 9182, 56538, 65087, 65514, 65535,
0, 8, 63, 327, 2118, 14490, 52774, 63839, 65376, 65522,
65535, 0, 65535, 0, 65535, 0, 65535, 0, 65535, 0,
17, 65522, 65535, 0, 59, 65489, 65535, 0, 50, 65522,
65535, 0, 54, 65489, 65535, 0, 310, 65179, 65535, 0,
615, 64836, 65535, 0, 4, 1503, 63965, 65535, 0, 2780,
63383, 65535, 0, 21, 3919, 61051, 65527, 65535, 0, 84,
6674, 59929, 65435, 65535, 0, 4, 255, 7976, 55784, 65150,
65518, 65531, 65535, 0, 4, 8, 582, 10726, 53465, 64949,
65518, 65535, 0, 29, 339, 3006, 17555, 49517, 62956, 65200,
65497, 65531, 65535, 0, 2, 33, 138, 565, 2324, 7670,
22089, 45966, 58949, 63479, 64966, 65380, 65518, 65535, 0, 65535,
0, 65535, 0, 2, 65533, 65535, 0, 46, 65514, 65535,
0, 414, 65091, 65535, 0, 540, 64911, 65535, 0, 419,
65162, 65535, 0, 976, 64790, 65535, 0, 2977, 62495, 65531,
65535, 0, 4, 3852, 61034, 65527, 65535, 0, 4, 29,
6021, 60243, 65468, 65535, 0, 84, 6711, 58066, 65418, 65535,
0, 13, 281, 9550, 54917, 65125, 65506, 65535, 0, 2,
63, 984, 12108, 52644, 64342, 65435, 65527, 65535, 0, 29,
251, 2014, 14871, 47553, 62881, 65229, 65518, 65535, 0, 13,
142, 749, 4220, 18497, 45200, 60913, 64823, 65426, 65527, 65535,
0, 13, 71, 264, 1176, 3789, 10500, 24480, 43488, 56324,
62315, 64493, 65242, 65464, 65514, 65522, 65531, 65535, 0, 4,
13, 38, 109, 205, 448, 850, 1708, 3429, 6276, 11371,
19221, 29734, 40955, 49391, 55411, 59460, 62102, 63793, 64656,
65150, 65401, 65485, 65522, 65531, 65535, 0, 65535, 0, 2, 65533,
65535, 0, 1160, 65476, 65535, 0, 2, 6640, 64763, 65533,
65535, 0, 2, 38, 9923, 61009, 65527, 65535, 0, 2,
4949, 63092, 65533, 65535, 0, 2, 3090, 63398, 65533, 65535,
0, 2, 2520, 58744, 65510, 65535, 0, 2, 13, 544,
8784, 51403, 65148, 65533, 65535, 0, 2, 25, 1017, 10412,
43550, 63651, 65489, 65527, 65535, 0, 2, 4, 29, 783,
13377, 52462, 64524, 65495, 65533, 65535, 0, 2, 4, 6,
100, 1817, 18451, 52590, 63559, 65376, 65531, 65535, 0, 2,
4, 6, 46, 385, 2562, 11225, 37416, 60488, 65026, 65487,
65529, 65533, 65535, 0, 2, 4, 6, 8, 10, 12,
42, 222, 971, 5221, 19811, 45048, 60312, 64486, 65294, 65474,
65525, 65529, 65533, 65535, 0, 2, 4, 8, 71, 167,
666, 2533, 7875, 19622, 38082, 54359, 62108, 64633, 65290, 65495,
65529, 65533, 65535, 0, 2, 4, 6, 8, 10, 13,
109, 586, 1930, 4949, 11600, 22641, 36125, 48312, 56899, 61495,
63927, 64932, 65389, 65489, 65518, 65531, 65533, 65535, 0, 4,
6, 8, 67, 209, 712, 1838, 4195, 8432, 14432, 22834,
31723, 40523, 48139, 53929, 57865, 60657, 62403, 63584, 64363,
64907, 65167, 65372, 65472, 65514, 65535, 0, 2, 4, 13, 25,
42, 46, 50, 75, 113, 147, 281, 448, 657, 909,
1185, 1591, 1976, 2600, 3676, 5317, 7398, 9914, 12941, 16169,
19477, 22885, 26464, 29851, 33360, 37228, 41139, 44802, 48654,
52058, 55181, 57676, 59581, 61022, 62190, 63107, 63676, 64199,
64547, 64924, 65158, 65313, 65430, 65481, 65518, 65535 };
/* pointers to cdf tables for quantizer indices */
const uint16_t *WebRtcIsac_kQKltCdfPtrGain[12] = {
WebRtcIsac_kQKltCdfGain +0 +0, WebRtcIsac_kQKltCdfGain +0 +8,
WebRtcIsac_kQKltCdfGain +0 +22, WebRtcIsac_kQKltCdfGain +0 +32,
WebRtcIsac_kQKltCdfGain +0 +48, WebRtcIsac_kQKltCdfGain +0 +60,
WebRtcIsac_kQKltCdfGain +0 +81, WebRtcIsac_kQKltCdfGain +0 +95,
WebRtcIsac_kQKltCdfGain +0 +128, WebRtcIsac_kQKltCdfGain +0 +152,
WebRtcIsac_kQKltCdfGain +0 +210, WebRtcIsac_kQKltCdfGain +0 +264 };
const uint16_t *WebRtcIsac_kQKltCdfPtrShape[108] = {
WebRtcIsac_kQKltCdfShape +0 +0, WebRtcIsac_kQKltCdfShape +0 +2,
WebRtcIsac_kQKltCdfShape +0 +4, WebRtcIsac_kQKltCdfShape +0 +6,
WebRtcIsac_kQKltCdfShape +0 +8, WebRtcIsac_kQKltCdfShape +0 +10,
WebRtcIsac_kQKltCdfShape +0 +12, WebRtcIsac_kQKltCdfShape +0 +14,
WebRtcIsac_kQKltCdfShape +0 +16, WebRtcIsac_kQKltCdfShape +0 +18,
WebRtcIsac_kQKltCdfShape +0 +21, WebRtcIsac_kQKltCdfShape +0 +25,
WebRtcIsac_kQKltCdfShape +0 +29, WebRtcIsac_kQKltCdfShape +0 +33,
WebRtcIsac_kQKltCdfShape +0 +37, WebRtcIsac_kQKltCdfShape +0 +43,
WebRtcIsac_kQKltCdfShape +0 +49, WebRtcIsac_kQKltCdfShape +0 +56,
WebRtcIsac_kQKltCdfShape +0 +64, WebRtcIsac_kQKltCdfShape +0 +66,
WebRtcIsac_kQKltCdfShape +0 +68, WebRtcIsac_kQKltCdfShape +0 +70,
WebRtcIsac_kQKltCdfShape +0 +72, WebRtcIsac_kQKltCdfShape +0 +75,
WebRtcIsac_kQKltCdfShape +0 +77, WebRtcIsac_kQKltCdfShape +0 +79,
WebRtcIsac_kQKltCdfShape +0 +81, WebRtcIsac_kQKltCdfShape +0 +83,
WebRtcIsac_kQKltCdfShape +0 +86, WebRtcIsac_kQKltCdfShape +0 +90,
WebRtcIsac_kQKltCdfShape +0 +94, WebRtcIsac_kQKltCdfShape +0 +98,
WebRtcIsac_kQKltCdfShape +0 +102, WebRtcIsac_kQKltCdfShape +0 +107,
WebRtcIsac_kQKltCdfShape +0 +113, WebRtcIsac_kQKltCdfShape +0 +120,
WebRtcIsac_kQKltCdfShape +0 +129, WebRtcIsac_kQKltCdfShape +0 +131,
WebRtcIsac_kQKltCdfShape +0 +133, WebRtcIsac_kQKltCdfShape +0 +135,
WebRtcIsac_kQKltCdfShape +0 +137, WebRtcIsac_kQKltCdfShape +0 +141,
WebRtcIsac_kQKltCdfShape +0 +143, WebRtcIsac_kQKltCdfShape +0 +147,
WebRtcIsac_kQKltCdfShape +0 +151, WebRtcIsac_kQKltCdfShape +0 +155,
WebRtcIsac_kQKltCdfShape +0 +159, WebRtcIsac_kQKltCdfShape +0 +164,
WebRtcIsac_kQKltCdfShape +0 +168, WebRtcIsac_kQKltCdfShape +0 +172,
WebRtcIsac_kQKltCdfShape +0 +178, WebRtcIsac_kQKltCdfShape +0 +184,
WebRtcIsac_kQKltCdfShape +0 +192, WebRtcIsac_kQKltCdfShape +0 +200,
WebRtcIsac_kQKltCdfShape +0 +211, WebRtcIsac_kQKltCdfShape +0 +213,
WebRtcIsac_kQKltCdfShape +0 +215, WebRtcIsac_kQKltCdfShape +0 +217,
WebRtcIsac_kQKltCdfShape +0 +219, WebRtcIsac_kQKltCdfShape +0 +223,
WebRtcIsac_kQKltCdfShape +0 +227, WebRtcIsac_kQKltCdfShape +0 +231,
WebRtcIsac_kQKltCdfShape +0 +235, WebRtcIsac_kQKltCdfShape +0 +239,
WebRtcIsac_kQKltCdfShape +0 +243, WebRtcIsac_kQKltCdfShape +0 +248,
WebRtcIsac_kQKltCdfShape +0 +252, WebRtcIsac_kQKltCdfShape +0 +258,
WebRtcIsac_kQKltCdfShape +0 +264, WebRtcIsac_kQKltCdfShape +0 +273,
WebRtcIsac_kQKltCdfShape +0 +282, WebRtcIsac_kQKltCdfShape +0 +293,
WebRtcIsac_kQKltCdfShape +0 +308, WebRtcIsac_kQKltCdfShape +0 +310,
WebRtcIsac_kQKltCdfShape +0 +312, WebRtcIsac_kQKltCdfShape +0 +316,
WebRtcIsac_kQKltCdfShape +0 +320, WebRtcIsac_kQKltCdfShape +0 +324,
WebRtcIsac_kQKltCdfShape +0 +328, WebRtcIsac_kQKltCdfShape +0 +332,
WebRtcIsac_kQKltCdfShape +0 +336, WebRtcIsac_kQKltCdfShape +0 +341,
WebRtcIsac_kQKltCdfShape +0 +347, WebRtcIsac_kQKltCdfShape +0 +354,
WebRtcIsac_kQKltCdfShape +0 +360, WebRtcIsac_kQKltCdfShape +0 +368,
WebRtcIsac_kQKltCdfShape +0 +378, WebRtcIsac_kQKltCdfShape +0 +388,
WebRtcIsac_kQKltCdfShape +0 +400, WebRtcIsac_kQKltCdfShape +0 +418,
WebRtcIsac_kQKltCdfShape +0 +445, WebRtcIsac_kQKltCdfShape +0 +447,
WebRtcIsac_kQKltCdfShape +0 +451, WebRtcIsac_kQKltCdfShape +0 +455,
WebRtcIsac_kQKltCdfShape +0 +461, WebRtcIsac_kQKltCdfShape +0 +468,
WebRtcIsac_kQKltCdfShape +0 +474, WebRtcIsac_kQKltCdfShape +0 +480,
WebRtcIsac_kQKltCdfShape +0 +486, WebRtcIsac_kQKltCdfShape +0 +495,
WebRtcIsac_kQKltCdfShape +0 +505, WebRtcIsac_kQKltCdfShape +0 +516,
WebRtcIsac_kQKltCdfShape +0 +528, WebRtcIsac_kQKltCdfShape +0 +543,
WebRtcIsac_kQKltCdfShape +0 +564, WebRtcIsac_kQKltCdfShape +0 +583,
WebRtcIsac_kQKltCdfShape +0 +608, WebRtcIsac_kQKltCdfShape +0 +635 };
/* left KLT transforms */
const double WebRtcIsac_kKltT1Gain[4] = {
-0.79742827, 0.60341375, 0.60341375, 0.79742827 };
const double WebRtcIsac_kKltT1Shape[324] = {
0.00159597, 0.00049320, 0.00513821, 0.00021066, 0.01338581,
-0.00422367, -0.00272072, 0.00935107, 0.02047622, 0.02691189,
0.00478236, 0.03969702, 0.00886698, 0.04877604, -0.10898362,
-0.05930891, -0.03415047, 0.98889721, 0.00293558, -0.00035282,
0.01156321, -0.00195341, -0.00937631, 0.01052213, -0.02551163,
0.01644059, 0.03189927, 0.07754773, -0.08742313, -0.03026338,
0.05136248, -0.14395974, 0.17725040, 0.22664856, 0.93380230,
0.07076411, 0.00557890, -0.00222834, 0.01377569, 0.01466808,
0.02847361, -0.00603178, 0.02382480, -0.01210452, 0.03797267,
-0.02371480, 0.11260335, -0.07366682, 0.00453436, -0.04136941,
-0.07912843, -0.95031418, 0.25295337, -0.05302216, -0.00617554,
-0.00044040, -0.00653778, 0.01097838, 0.01529174, 0.01374431,
-0.00748512, -0.00020034, 0.02432713, 0.11101570, -0.08556891,
0.09282249, -0.01029446, 0.67556443, -0.67454300, 0.06910063,
0.20866865, -0.10318050, 0.00932175, 0.00524058, 0.00803610,
-0.00594676, -0.01082578, 0.01069906, 0.00546768, 0.01565291,
0.06816200, 0.10201227, 0.16812734, 0.22984074, 0.58213170,
-0.54138651, -0.51379962, 0.06847390, -0.01920037, -0.04592324,
-0.00467394, 0.00328858, 0.00377424, -0.00987448, 0.08222096,
-0.00377301, 0.04551941, -0.02592517, 0.16317082, 0.13077530,
0.22702921, -0.31215289, -0.69645962, -0.38047101, -0.39339411,
0.11124777, 0.02508035, -0.00708074, 0.00400344, 0.00040331,
0.01142402, 0.01725406, 0.01635170, 0.14285366, 0.03949233,
-0.05905676, 0.05877154, -0.17497577, -0.32479440, 0.80754464,
-0.38085603, -0.17055430, -0.03168622, -0.07531451, 0.02942002,
-0.02148095, -0.00754114, -0.00322372, 0.00567812, -0.01701521,
-0.12358320, 0.11473564, 0.09070136, 0.06533068, -0.22560802,
0.19209022, 0.81605094, 0.36592275, -0.09919829, 0.16667122,
0.16300725, 0.04803807, 0.06739263, -0.00156752, -0.01685302,
-0.00905240, -0.02297836, -0.00469939, 0.06310613, -0.16391930,
0.10919511, 0.12529293, 0.85581322, -0.32145522, 0.24539076,
0.07181839, 0.07289591, 0.14066759, 0.10406711, 0.05815518,
0.01072680, -0.00759339, 0.00053486, -0.00044865, 0.03407361,
0.01645348, 0.08758579, 0.27722240, 0.53665485, -0.74853376,
-0.01118192, -0.19805430, 0.06130619, -0.09675299, 0.08978480,
0.03405255, -0.00706867, 0.05102045, 0.03250746, 0.01849966,
-0.01216314, -0.01184187, -0.01579288, 0.00114807, 0.11376166,
0.88342114, -0.36425379, 0.13863190, 0.12524180, -0.13553892,
0.04715856, -0.12341103, 0.04531568, 0.01899360, -0.00206897,
0.00567768, -0.01444163, 0.00411946, -0.00855896, 0.00381663,
-0.01664861, -0.05534280, 0.21328278, 0.20161162, 0.72360394,
0.59130708, -0.08043791, 0.08757349, -0.13893918, -0.05147377,
0.02680690, -0.01144070, 0.00625162, -0.00634215, -0.01248947,
-0.00329455, -0.00609625, -0.00136305, -0.05097048, -0.01029851,
0.25065384, -0.16856837, -0.07123372, 0.15992623, -0.39487617,
-0.79972301, 0.18118185, -0.04826639, -0.01805578, -0.02927253,
-0.16400618, 0.07472763, 0.10376449, 0.01705406, 0.01065801,
-0.01500498, 0.02039914, 0.37776349, -0.84484186, 0.10434286,
0.15616990, 0.13474456, -0.00906238, -0.25238368, -0.03820885,
-0.10650905, -0.03880833, -0.03660028, -0.09640894, 0.00583314,
0.01922097, 0.01489911, -0.02431117, -0.09372217, 0.39404721,
-0.84786223, -0.31277121, 0.03193850, 0.01974060, 0.01887901,
0.00337911, -0.11359599, -0.02792521, -0.03220184, -0.01533311,
0.00015962, -0.04225043, -0.00933965, 0.00675311, 0.00206060,
0.15926771, 0.40199829, -0.80792558, -0.35591604, -0.17169764,
0.02830436, 0.02459982, -0.03438589, 0.00718705, -0.01798329,
-0.01594508, -0.00702430, -0.00952419, -0.00962701, -0.01307212,
-0.01749740, 0.01299602, 0.00587270, -0.36103108, -0.82039266,
-0.43092844, -0.08500097, -0.04361674, -0.00333482, 0.01250434,
-0.02538295, -0.00921797, 0.01645071, -0.01400872, 0.00317607,
0.00003277, -0.01617646, -0.00616863, -0.00882661, 0.00466157,
0.00353237, 0.91803104, -0.39503305, -0.02048964, 0.00060125,
0.01980634, 0.00300109, 0.00313880, 0.00657337, 0.00715163,
0.00000261, 0.00854276, -0.00154825, -0.00516128, 0.00909527,
0.00095609, 0.00701196, -0.00221867, -0.00156741 };
/* right KLT transforms */
const double WebRtcIsac_kKltT2Gain[36] = {
0.14572837, -0.45446306, 0.61990621, -0.52197033, 0.32145074,
-0.11026900, -0.20698282, 0.48962182, -0.27127933, -0.33627476,
0.65094037, -0.32715751, 0.40262573, -0.47844405, -0.33876075,
0.44130653, 0.37383966, -0.39964662, -0.51730480, 0.06611973,
0.49030187, 0.47512886, -0.02141226, -0.51129451, -0.58578569,
-0.39132064, -0.13187771, 0.15649421, 0.40735596, 0.54396897,
0.40381276, 0.40904942, 0.41179766, 0.41167576, 0.40840251,
0.40468132 };
const double WebRtcIsac_kKltT2Shape[36] = {
0.13427386, -0.35132558, 0.52506528, -0.59419077, 0.45075085,
-0.16312057, 0.29857439, -0.58660147, 0.34265431, 0.20879510,
-0.56063262, 0.30238345, 0.43308283, -0.41186999, -0.35288681,
0.42768996, 0.36094634, -0.45284910, -0.47116680, 0.02893449,
0.54326135, 0.45249040, -0.06264420, -0.52283830, 0.57137758,
0.44298139, 0.12617554, -0.20819946, -0.42324603, -0.48876443,
0.39597050, 0.40713935, 0.41389880, 0.41512486, 0.41130400,
0.40575001 };
/* means of log gains and LAR coefficients*/
const double WebRtcIsac_kLpcMeansGain[12] = {
-6.86881911, -5.35075273, -6.86792680, -5.36200897, -6.86401538,
-5.36921533, -6.86802969, -5.36893966, -6.86538097, -5.36315063,
-6.85535304, -5.35155315 };
const double WebRtcIsac_kLpcMeansShape[108] = {
-0.91232981, 0.26258634, -0.33716701, 0.08477430, -0.03378426,
0.14423909, 0.07036185, 0.06155019, 0.01490385, 0.04138740,
0.01427317, 0.01288970, 0.83872106, 0.25750199, 0.07988929,
-0.01957923, 0.00831390, 0.01770300, -0.90957164, 0.25732216,
-0.33385344, 0.08735740, -0.03715332, 0.14584917, 0.06998990,
0.06131968, 0.01504379, 0.04067339, 0.01428039, 0.01406460,
0.83846243, 0.26169862, 0.08109025, -0.01767055, 0.00970539,
0.01954310, -0.90490803, 0.24656405, -0.33578607, 0.08843286,
-0.03749139, 0.14443959, 0.07214669, 0.06170993, 0.01449947,
0.04134309, 0.01314762, 0.01413471, 0.83895203, 0.26748062,
0.08197507, -0.01781298, 0.00885967, 0.01922394, -0.90922472,
0.24495889, -0.33921540, 0.08877169, -0.03581332, 0.14199172,
0.07444032, 0.06185940, 0.01502054, 0.04185113, 0.01276579,
0.01355457, 0.83645358, 0.26631720, 0.08119697, -0.01835449,
0.00788512, 0.01846446, -0.90482253, 0.24658310, -0.34019734,
0.08281090, -0.03486038, 0.14359248, 0.07401336, 0.06001471,
0.01528421, 0.04254560, 0.01321472, 0.01240799, 0.83857127,
0.26281654, 0.08174380, -0.02099842, 0.00755176, 0.01699448,
-0.90132307, 0.25174308, -0.33838268, 0.07883863, -0.02877906,
0.14105407, 0.07220290, 0.06000352, 0.01684879, 0.04226844,
0.01331331, 0.01269244, 0.83832138, 0.25467485, 0.08118028,
-0.02120528, 0.00747832, 0.01567212 };

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 2012 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.
*/
/*
* lpc_tables.h
*
* header file for coding tables for the LPC coefficients
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_
#include "structs.h"
#include "settings.h"
#define KLT_STEPSIZE 1.00000000
#define KLT_NUM_AVG_GAIN 0
#define KLT_NUM_AVG_SHAPE 0
#define KLT_NUM_MODELS 3
#define LPC_GAIN_SCALE 4.000f
#define LPC_LOBAND_SCALE 2.100f
#define LPC_LOBAND_ORDER ORDERLO
#define LPC_HIBAND_SCALE 0.450f
#define LPC_HIBAND_ORDER ORDERHI
#define LPC_GAIN_ORDER 2
#define LPC_SHAPE_ORDER (LPC_LOBAND_ORDER + LPC_HIBAND_ORDER)
#define KLT_ORDER_GAIN (LPC_GAIN_ORDER * SUBFRAMES)
#define KLT_ORDER_SHAPE (LPC_SHAPE_ORDER * SUBFRAMES)
/* cdf array for model indicator */
extern const uint16_t WebRtcIsac_kQKltModelCdf[KLT_NUM_MODELS+1];
/* pointer to cdf array for model indicator */
extern const uint16_t *WebRtcIsac_kQKltModelCdfPtr[1];
/* initial cdf index for decoder of model indicator */
extern const uint16_t WebRtcIsac_kQKltModelInitIndex[1];
/* offset to go from rounded value to quantization index */
extern const short WebRtcIsac_kQKltQuantMinGain[12];
extern const short WebRtcIsac_kQKltQuantMinShape[108];
/* maximum quantization index */
extern const uint16_t WebRtcIsac_kQKltMaxIndGain[12];
extern const uint16_t WebRtcIsac_kQKltMaxIndShape[108];
/* index offset */
extern const uint16_t WebRtcIsac_kQKltOffsetGain[12];
extern const uint16_t WebRtcIsac_kQKltOffsetShape[108];
/* initial cdf index for KLT coefficients */
extern const uint16_t WebRtcIsac_kQKltInitIndexGain[12];
extern const uint16_t WebRtcIsac_kQKltInitIndexShape[108];
/* quantizer representation levels */
extern const double WebRtcIsac_kQKltLevelsGain[392];
extern const double WebRtcIsac_kQKltLevelsShape[578];
/* cdf tables for quantizer indices */
extern const uint16_t WebRtcIsac_kQKltCdfGain[404];
extern const uint16_t WebRtcIsac_kQKltCdfShape[686];
/* pointers to cdf tables for quantizer indices */
extern const uint16_t *WebRtcIsac_kQKltCdfPtrGain[12];
extern const uint16_t *WebRtcIsac_kQKltCdfPtrShape[108];
/* left KLT transforms */
extern const double WebRtcIsac_kKltT1Gain[4];
extern const double WebRtcIsac_kKltT1Shape[324];
/* right KLT transforms */
extern const double WebRtcIsac_kKltT2Gain[36];
extern const double WebRtcIsac_kKltT2Shape[36];
/* means of log gains and LAR coefficients */
extern const double WebRtcIsac_kLpcMeansGain[12];
extern const double WebRtcIsac_kLpcMeansShape[108];
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_TABLES_H_ */

View File

@@ -0,0 +1,41 @@
/*
* 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.
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_
#include <math.h>
#include "typedefs.h"
#if defined(WEBRTC_POSIX)
#define WebRtcIsac_lrint lrint
#elif (defined(WEBRTC_ARCH_X86) && defined(WIN32))
static __inline long int WebRtcIsac_lrint(double x_dbl) {
long int x_int;
__asm {
fld x_dbl
fistp x_int
};
return x_int;
}
#else // Do a slow but correct implementation of lrint
static __inline long int WebRtcIsac_lrint(double x_dbl) {
long int x_int;
x_int = (long int)floor(x_dbl + 0.499999999999);
return x_int;
}
#endif
#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_

View File

@@ -0,0 +1,622 @@
/*
* 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 "pitch_estimator.h"
#include <math.h>
#include <memory.h>
#ifdef WEBRTC_ANDROID
#include <stdlib.h>
#endif
static const double kInterpolWin[8] = {-0.00067556028640, 0.02184247643159, -0.12203175715679, 0.60086484101160,
0.60086484101160, -0.12203175715679, 0.02184247643159, -0.00067556028640};
/* interpolation filter */
__inline static void IntrepolFilter(double *data_ptr, double *intrp)
{
*intrp = kInterpolWin[0] * data_ptr[-3];
*intrp += kInterpolWin[1] * data_ptr[-2];
*intrp += kInterpolWin[2] * data_ptr[-1];
*intrp += kInterpolWin[3] * data_ptr[0];
*intrp += kInterpolWin[4] * data_ptr[1];
*intrp += kInterpolWin[5] * data_ptr[2];
*intrp += kInterpolWin[6] * data_ptr[3];
*intrp += kInterpolWin[7] * data_ptr[4];
}
/* 2D parabolic interpolation */
/* probably some 0.5 factors can be eliminated, and the square-roots can be removed from the Cholesky fact. */
__inline static void Intrpol2D(double T[3][3], double *x, double *y, double *peak_val)
{
double c, b[2], A[2][2];
double t1, t2, d;
double delta1, delta2;
// double T[3][3] = {{-1.25, -.25,-.25}, {-.25, .75, .75}, {-.25, .75, .75}};
// should result in: delta1 = 0.5; delta2 = 0.0; peak_val = 1.0
c = T[1][1];
b[0] = 0.5 * (T[1][2] + T[2][1] - T[0][1] - T[1][0]);
b[1] = 0.5 * (T[1][0] + T[2][1] - T[0][1] - T[1][2]);
A[0][1] = -0.5 * (T[0][1] + T[2][1] - T[1][0] - T[1][2]);
t1 = 0.5 * (T[0][0] + T[2][2]) - c;
t2 = 0.5 * (T[2][0] + T[0][2]) - c;
d = (T[0][1] + T[1][2] + T[1][0] + T[2][1]) - 4.0 * c - t1 - t2;
A[0][0] = -t1 - 0.5 * d;
A[1][1] = -t2 - 0.5 * d;
/* deal with singularities or ill-conditioned cases */
if ( (A[0][0] < 1e-7) || ((A[0][0] * A[1][1] - A[0][1] * A[0][1]) < 1e-7) ) {
*peak_val = T[1][1];
return;
}
/* Cholesky decomposition: replace A by upper-triangular factor */
A[0][0] = sqrt(A[0][0]);
A[0][1] = A[0][1] / A[0][0];
A[1][1] = sqrt(A[1][1] - A[0][1] * A[0][1]);
/* compute [x; y] = -0.5 * inv(A) * b */
t1 = b[0] / A[0][0];
t2 = (b[1] - t1 * A[0][1]) / A[1][1];
delta2 = t2 / A[1][1];
delta1 = 0.5 * (t1 - delta2 * A[0][1]) / A[0][0];
delta2 *= 0.5;
/* limit norm */
t1 = delta1 * delta1 + delta2 * delta2;
if (t1 > 1.0) {
delta1 /= t1;
delta2 /= t1;
}
*peak_val = 0.5 * (b[0] * delta1 + b[1] * delta2) + c;
*x += delta1;
*y += delta2;
}
static void PCorr(const double *in, double *outcorr)
{
double sum, ysum, prod;
const double *x, *inptr;
int k, n;
//ysum = 1e-6; /* use this with float (i.s.o. double)! */
ysum = 1e-13;
sum = 0.0;
x = in + PITCH_MAX_LAG/2 + 2;
for (n = 0; n < PITCH_CORR_LEN2; n++) {
ysum += in[n] * in[n];
sum += x[n] * in[n];
}
outcorr += PITCH_LAG_SPAN2 - 1; /* index of last element in array */
*outcorr = sum / sqrt(ysum);
for (k = 1; k < PITCH_LAG_SPAN2; k++) {
ysum -= in[k-1] * in[k-1];
ysum += in[PITCH_CORR_LEN2 + k - 1] * in[PITCH_CORR_LEN2 + k - 1];
sum = 0.0;
inptr = &in[k];
prod = x[0] * inptr[0];
for (n = 1; n < PITCH_CORR_LEN2; n++) {
sum += prod;
prod = x[n] * inptr[n];
}
sum += prod;
outcorr--;
*outcorr = sum / sqrt(ysum);
}
}
void WebRtcIsac_InitializePitch(const double *in,
const double old_lag,
const double old_gain,
PitchAnalysisStruct *State,
double *lags)
{
double buf_dec[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2];
double ratio, log_lag, gain_bias;
double bias;
double corrvec1[PITCH_LAG_SPAN2];
double corrvec2[PITCH_LAG_SPAN2];
int m, k;
// Allocating 10 extra entries at the begining of the CorrSurf
double corrSurfBuff[10 + (2*PITCH_BW+3)*(PITCH_LAG_SPAN2+4)];
double* CorrSurf[2*PITCH_BW+3];
double *CorrSurfPtr1, *CorrSurfPtr2;
double LagWin[3] = {0.2, 0.5, 0.98};
int ind1, ind2, peaks_ind, peak, max_ind;
int peaks[PITCH_MAX_NUM_PEAKS];
double adj, gain_tmp;
double corr, corr_max;
double intrp_a, intrp_b, intrp_c, intrp_d;
double peak_vals[PITCH_MAX_NUM_PEAKS];
double lags1[PITCH_MAX_NUM_PEAKS];
double lags2[PITCH_MAX_NUM_PEAKS];
double T[3][3];
int row;
for(k = 0; k < 2*PITCH_BW+3; k++)
{
CorrSurf[k] = &corrSurfBuff[10 + k * (PITCH_LAG_SPAN2+4)];
}
/* reset CorrSurf matrix */
memset(corrSurfBuff, 0, sizeof(double) * (10 + (2*PITCH_BW+3) * (PITCH_LAG_SPAN2+4)));
//warnings -DH
max_ind = 0;
peak = 0;
/* copy old values from state buffer */
memcpy(buf_dec, State->dec_buffer, sizeof(double) * (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2));
/* decimation; put result after the old values */
WebRtcIsac_DecimateAllpass(in, State->decimator_state, PITCH_FRAME_LEN,
&buf_dec[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]);
/* low-pass filtering */
for (k = PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2; k++)
buf_dec[k] += 0.75 * buf_dec[k-1] - 0.25 * buf_dec[k-2];
/* copy end part back into state buffer */
memcpy(State->dec_buffer, buf_dec+PITCH_FRAME_LEN/2, sizeof(double) * (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2));
/* compute correlation for first and second half of the frame */
PCorr(buf_dec, corrvec1);
PCorr(buf_dec + PITCH_CORR_STEP2, corrvec2);
/* bias towards pitch lag of previous frame */
log_lag = log(0.5 * old_lag);
gain_bias = 4.0 * old_gain * old_gain;
if (gain_bias > 0.8) gain_bias = 0.8;
for (k = 0; k < PITCH_LAG_SPAN2; k++)
{
ratio = log((double) (k + (PITCH_MIN_LAG/2-2))) - log_lag;
bias = 1.0 + gain_bias * exp(-5.0 * ratio * ratio);
corrvec1[k] *= bias;
}
/* taper correlation functions */
for (k = 0; k < 3; k++) {
gain_tmp = LagWin[k];
corrvec1[k] *= gain_tmp;
corrvec2[k] *= gain_tmp;
corrvec1[PITCH_LAG_SPAN2-1-k] *= gain_tmp;
corrvec2[PITCH_LAG_SPAN2-1-k] *= gain_tmp;
}
corr_max = 0.0;
/* fill middle row of correlation surface */
ind1 = 0;
ind2 = 0;
CorrSurfPtr1 = &CorrSurf[PITCH_BW][2];
for (k = 0; k < PITCH_LAG_SPAN2; k++) {
corr = corrvec1[ind1++] + corrvec2[ind2++];
CorrSurfPtr1[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
}
}
/* fill first and last rows of correlation surface */
ind1 = 0;
ind2 = PITCH_BW;
CorrSurfPtr1 = &CorrSurf[0][2];
CorrSurfPtr2 = &CorrSurf[2*PITCH_BW][PITCH_BW+2];
for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW; k++) {
ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12));
adj = 0.2 * ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */
corr = adj * (corrvec1[ind1] + corrvec2[ind2]);
CorrSurfPtr1[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
}
corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]);
CorrSurfPtr2[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]);
}
}
/* fill second and next to last rows of correlation surface */
ind1 = 0;
ind2 = PITCH_BW-1;
CorrSurfPtr1 = &CorrSurf[1][2];
CorrSurfPtr2 = &CorrSurf[2*PITCH_BW-1][PITCH_BW+1];
for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW+1; k++) {
ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12));
adj = 0.9 * ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */
corr = adj * (corrvec1[ind1] + corrvec2[ind2]);
CorrSurfPtr1[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
}
corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]);
CorrSurfPtr2[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]);
}
}
/* fill remainder of correlation surface */
for (m = 2; m < PITCH_BW; m++) {
ind1 = 0;
ind2 = PITCH_BW - m; /* always larger than ind1 */
CorrSurfPtr1 = &CorrSurf[m][2];
CorrSurfPtr2 = &CorrSurf[2*PITCH_BW-m][PITCH_BW+2-m];
for (k = 0; k < PITCH_LAG_SPAN2-PITCH_BW+m; k++) {
ratio = ((double) (ind1 + 12)) / ((double) (ind2 + 12));
adj = ratio * (2.0 - ratio); /* adjustment factor; inverse parabola as a function of ratio */
corr = adj * (corrvec1[ind1] + corrvec2[ind2]);
CorrSurfPtr1[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
}
corr = adj * (corrvec1[ind2++] + corrvec2[ind1++]);
CorrSurfPtr2[k] = corr;
if (corr > corr_max) {
corr_max = corr; /* update maximum */
max_ind = (int)(&CorrSurfPtr2[k] - &CorrSurf[0][0]);
}
}
}
/* threshold value to qualify as a peak */
corr_max *= 0.6;
peaks_ind = 0;
/* find peaks */
for (m = 1; m < PITCH_BW+1; m++) {
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
CorrSurfPtr1 = &CorrSurf[m][2];
for (k = 2; k < PITCH_LAG_SPAN2-PITCH_BW-2+m; k++) {
corr = CorrSurfPtr1[k];
if (corr > corr_max) {
if ( (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+5)]) && (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+4)]) ) {
if ( (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+4)]) && (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+5)]) ) {
/* found a peak; store index into matrix */
peaks[peaks_ind++] = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
}
}
}
}
}
for (m = PITCH_BW+1; m < 2*PITCH_BW; m++) {
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
CorrSurfPtr1 = &CorrSurf[m][2];
for (k = 2+m-PITCH_BW; k < PITCH_LAG_SPAN2-2; k++) {
corr = CorrSurfPtr1[k];
if (corr > corr_max) {
if ( (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+5)]) && (corr > CorrSurfPtr1[k - (PITCH_LAG_SPAN2+4)]) ) {
if ( (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+4)]) && (corr > CorrSurfPtr1[k + (PITCH_LAG_SPAN2+5)]) ) {
/* found a peak; store index into matrix */
peaks[peaks_ind++] = (int)(&CorrSurfPtr1[k] - &CorrSurf[0][0]);
if (peaks_ind == PITCH_MAX_NUM_PEAKS) break;
}
}
}
}
}
if (peaks_ind > 0) {
/* examine each peak */
CorrSurfPtr1 = &CorrSurf[0][0];
for (k = 0; k < peaks_ind; k++) {
peak = peaks[k];
/* compute four interpolated values around current peak */
IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)], &intrp_a);
IntrepolFilter(&CorrSurfPtr1[peak - 1 ], &intrp_b);
IntrepolFilter(&CorrSurfPtr1[peak ], &intrp_c);
IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)], &intrp_d);
/* determine maximum of the interpolated values */
corr = CorrSurfPtr1[peak];
corr_max = intrp_a;
if (intrp_b > corr_max) corr_max = intrp_b;
if (intrp_c > corr_max) corr_max = intrp_c;
if (intrp_d > corr_max) corr_max = intrp_d;
/* determine where the peak sits and fill a 3x3 matrix around it */
row = peak / (PITCH_LAG_SPAN2+4);
lags1[k] = (double) ((peak - row * (PITCH_LAG_SPAN2+4)) + PITCH_MIN_LAG/2 - 4);
lags2[k] = (double) (lags1[k] + PITCH_BW - row);
if ( corr > corr_max ) {
T[0][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)];
T[2][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)];
T[1][1] = corr;
T[0][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)];
T[2][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)];
T[1][0] = intrp_a;
T[0][1] = intrp_b;
T[2][1] = intrp_c;
T[1][2] = intrp_d;
} else {
if (intrp_a == corr_max) {
lags1[k] -= 0.5;
lags2[k] += 0.5;
IntrepolFilter(&CorrSurfPtr1[peak - 2*(PITCH_LAG_SPAN2+5)], &T[0][0]);
IntrepolFilter(&CorrSurfPtr1[peak - (2*PITCH_LAG_SPAN2+9)], &T[2][0]);
T[1][1] = intrp_a;
T[0][2] = intrp_b;
T[2][2] = intrp_c;
T[1][0] = CorrSurfPtr1[peak - (2*PITCH_LAG_SPAN2+9)];
T[0][1] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)];
T[2][1] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)];
T[1][2] = corr;
} else if (intrp_b == corr_max) {
lags1[k] -= 0.5;
lags2[k] -= 0.5;
IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+6)], &T[0][0]);
T[2][0] = intrp_a;
T[1][1] = intrp_b;
IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+3)], &T[0][2]);
T[2][2] = intrp_d;
T[1][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+5)];
T[0][1] = CorrSurfPtr1[peak - 1];
T[2][1] = corr;
T[1][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)];
} else if (intrp_c == corr_max) {
lags1[k] += 0.5;
lags2[k] += 0.5;
T[0][0] = intrp_a;
IntrepolFilter(&CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)], &T[2][0]);
T[1][1] = intrp_c;
T[0][2] = intrp_d;
IntrepolFilter(&CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)], &T[2][2]);
T[1][0] = CorrSurfPtr1[peak - (PITCH_LAG_SPAN2+4)];
T[0][1] = corr;
T[2][1] = CorrSurfPtr1[peak + 1];
T[1][2] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)];
} else {
lags1[k] += 0.5;
lags2[k] -= 0.5;
T[0][0] = intrp_b;
T[2][0] = intrp_c;
T[1][1] = intrp_d;
IntrepolFilter(&CorrSurfPtr1[peak + 2*(PITCH_LAG_SPAN2+4)], &T[0][2]);
IntrepolFilter(&CorrSurfPtr1[peak + (2*PITCH_LAG_SPAN2+9)], &T[2][2]);
T[1][0] = corr;
T[0][1] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+4)];
T[2][1] = CorrSurfPtr1[peak + (PITCH_LAG_SPAN2+5)];
T[1][2] = CorrSurfPtr1[peak + (2*PITCH_LAG_SPAN2+9)];
}
}
/* 2D parabolic interpolation gives more accurate lags and peak value */
Intrpol2D(T, &lags1[k], &lags2[k], &peak_vals[k]);
}
/* determine the highest peak, after applying a bias towards short lags */
corr_max = 0.0;
for (k = 0; k < peaks_ind; k++) {
corr = peak_vals[k] * pow(PITCH_PEAK_DECAY, log(lags1[k] + lags2[k]));
if (corr > corr_max) {
corr_max = corr;
peak = k;
}
}
lags1[peak] *= 2.0;
lags2[peak] *= 2.0;
if (lags1[peak] < (double) PITCH_MIN_LAG) lags1[peak] = (double) PITCH_MIN_LAG;
if (lags2[peak] < (double) PITCH_MIN_LAG) lags2[peak] = (double) PITCH_MIN_LAG;
if (lags1[peak] > (double) PITCH_MAX_LAG) lags1[peak] = (double) PITCH_MAX_LAG;
if (lags2[peak] > (double) PITCH_MAX_LAG) lags2[peak] = (double) PITCH_MAX_LAG;
/* store lags of highest peak in output array */
lags[0] = lags1[peak];
lags[1] = lags1[peak];
lags[2] = lags2[peak];
lags[3] = lags2[peak];
}
else
{
row = max_ind / (PITCH_LAG_SPAN2+4);
lags1[0] = (double) ((max_ind - row * (PITCH_LAG_SPAN2+4)) + PITCH_MIN_LAG/2 - 4);
lags2[0] = (double) (lags1[0] + PITCH_BW - row);
if (lags1[0] < (double) PITCH_MIN_LAG) lags1[0] = (double) PITCH_MIN_LAG;
if (lags2[0] < (double) PITCH_MIN_LAG) lags2[0] = (double) PITCH_MIN_LAG;
if (lags1[0] > (double) PITCH_MAX_LAG) lags1[0] = (double) PITCH_MAX_LAG;
if (lags2[0] > (double) PITCH_MAX_LAG) lags2[0] = (double) PITCH_MAX_LAG;
/* store lags of highest peak in output array */
lags[0] = lags1[0];
lags[1] = lags1[0];
lags[2] = lags2[0];
lags[3] = lags2[0];
}
}
/* create weighting matrix by orthogonalizing a basis of polynomials of increasing order
* t = (0:4)';
* A = [t.^0, t.^1, t.^2, t.^3, t.^4];
* [Q, dummy] = qr(A);
* P.Weight = Q * diag([0, .1, .5, 1, 1]) * Q'; */
static const double kWeight[5][5] = {
{ 0.29714285714286, -0.30857142857143, -0.05714285714286, 0.05142857142857, 0.01714285714286},
{-0.30857142857143, 0.67428571428571, -0.27142857142857, -0.14571428571429, 0.05142857142857},
{-0.05714285714286, -0.27142857142857, 0.65714285714286, -0.27142857142857, -0.05714285714286},
{ 0.05142857142857, -0.14571428571429, -0.27142857142857, 0.67428571428571, -0.30857142857143},
{ 0.01714285714286, 0.05142857142857, -0.05714285714286, -0.30857142857143, 0.29714285714286}
};
void WebRtcIsac_PitchAnalysis(const double *in, /* PITCH_FRAME_LEN samples */
double *out, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
PitchAnalysisStruct *State,
double *lags,
double *gains)
{
double HPin[PITCH_FRAME_LEN];
double Weighted[PITCH_FRAME_LEN];
double Whitened[PITCH_FRAME_LEN + QLOOKAHEAD];
double inbuf[PITCH_FRAME_LEN + QLOOKAHEAD];
double out_G[PITCH_FRAME_LEN + QLOOKAHEAD]; // could be removed by using out instead
double out_dG[4][PITCH_FRAME_LEN + QLOOKAHEAD];
double old_lag, old_gain;
double nrg_wht, tmp;
double Wnrg, Wfluct, Wgain;
double H[4][4];
double grad[4];
double dG[4];
int k, m, n, iter;
/* high pass filtering using second order pole-zero filter */
WebRtcIsac_Highpass(in, HPin, State->hp_state, PITCH_FRAME_LEN);
/* copy from state into buffer */
memcpy(Whitened, State->whitened_buf, sizeof(double) * QLOOKAHEAD);
/* compute weighted and whitened signals */
WebRtcIsac_WeightingFilter(HPin, &Weighted[0], &Whitened[QLOOKAHEAD], &(State->Wghtstr));
/* copy from buffer into state */
memcpy(State->whitened_buf, Whitened+PITCH_FRAME_LEN, sizeof(double) * QLOOKAHEAD);
old_lag = State->PFstr_wght.oldlagp[0];
old_gain = State->PFstr_wght.oldgainp[0];
/* inital pitch estimate */
WebRtcIsac_InitializePitch(Weighted, old_lag, old_gain, State, lags);
/* Iterative optimization of lags - to be done */
/* compute energy of whitened signal */
nrg_wht = 0.0;
for (k = 0; k < PITCH_FRAME_LEN + QLOOKAHEAD; k++)
nrg_wht += Whitened[k] * Whitened[k];
/* Iterative optimization of gains */
/* set weights for energy, gain fluctiation, and spectral gain penalty functions */
Wnrg = 1.0 / nrg_wht;
Wgain = 0.005;
Wfluct = 3.0;
/* set initial gains */
for (k = 0; k < 4; k++)
gains[k] = PITCH_MAX_GAIN_06;
/* two iterations should be enough */
for (iter = 0; iter < 2; iter++) {
/* compute Jacobian of pre-filter output towards gains */
WebRtcIsac_PitchfilterPre_gains(Whitened, out_G, out_dG, &(State->PFstr_wght), lags, gains);
/* gradient and approximate Hessian (lower triangle) for minimizing the filter's output power */
for (k = 0; k < 4; k++) {
tmp = 0.0;
for (n = 0; n < PITCH_FRAME_LEN + QLOOKAHEAD; n++)
tmp += out_G[n] * out_dG[k][n];
grad[k] = tmp * Wnrg;
}
for (k = 0; k < 4; k++) {
for (m = 0; m <= k; m++) {
tmp = 0.0;
for (n = 0; n < PITCH_FRAME_LEN + QLOOKAHEAD; n++)
tmp += out_dG[m][n] * out_dG[k][n];
H[k][m] = tmp * Wnrg;
}
}
/* add gradient and Hessian (lower triangle) for dampening fast gain changes */
for (k = 0; k < 4; k++) {
tmp = kWeight[k+1][0] * old_gain;
for (m = 0; m < 4; m++)
tmp += kWeight[k+1][m+1] * gains[m];
grad[k] += tmp * Wfluct;
}
for (k = 0; k < 4; k++) {
for (m = 0; m <= k; m++) {
H[k][m] += kWeight[k+1][m+1] * Wfluct;
}
}
/* add gradient and Hessian for dampening gain */
for (k = 0; k < 3; k++) {
tmp = 1.0 / (1 - gains[k]);
grad[k] += tmp * tmp * Wgain;
H[k][k] += 2.0 * tmp * (tmp * tmp * Wgain);
}
tmp = 1.0 / (1 - gains[3]);
grad[3] += 1.33 * (tmp * tmp * Wgain);
H[3][3] += 2.66 * tmp * (tmp * tmp * Wgain);
/* compute Cholesky factorization of Hessian
* by overwritting the upper triangle; scale factors on diagonal
* (for non pc-platforms store the inverse of the diagonals seperately to minimize divisions) */
H[0][1] = H[1][0] / H[0][0];
H[0][2] = H[2][0] / H[0][0];
H[0][3] = H[3][0] / H[0][0];
H[1][1] -= H[0][0] * H[0][1] * H[0][1];
H[1][2] = (H[2][1] - H[0][1] * H[2][0]) / H[1][1];
H[1][3] = (H[3][1] - H[0][1] * H[3][0]) / H[1][1];
H[2][2] -= H[0][0] * H[0][2] * H[0][2] + H[1][1] * H[1][2] * H[1][2];
H[2][3] = (H[3][2] - H[0][2] * H[3][0] - H[1][2] * H[1][1] * H[1][3]) / H[2][2];
H[3][3] -= H[0][0] * H[0][3] * H[0][3] + H[1][1] * H[1][3] * H[1][3] + H[2][2] * H[2][3] * H[2][3];
/* Compute update as delta_gains = -inv(H) * grad */
/* copy and negate */
for (k = 0; k < 4; k++)
dG[k] = -grad[k];
/* back substitution */
dG[1] -= dG[0] * H[0][1];
dG[2] -= dG[0] * H[0][2] + dG[1] * H[1][2];
dG[3] -= dG[0] * H[0][3] + dG[1] * H[1][3] + dG[2] * H[2][3];
/* scale */
for (k = 0; k < 4; k++)
dG[k] /= H[k][k];
/* back substitution */
dG[2] -= dG[3] * H[2][3];
dG[1] -= dG[3] * H[1][3] + dG[2] * H[1][2];
dG[0] -= dG[3] * H[0][3] + dG[2] * H[0][2] + dG[1] * H[0][1];
/* update gains and check range */
for (k = 0; k < 4; k++) {
gains[k] += dG[k];
if (gains[k] > PITCH_MAX_GAIN)
gains[k] = PITCH_MAX_GAIN;
else if (gains[k] < 0.0)
gains[k] = 0.0;
}
}
/* update state for next frame */
WebRtcIsac_PitchfilterPre(Whitened, out, &(State->PFstr_wght), lags, gains);
/* concatenate previous input's end and current input */
memcpy(inbuf, State->inbuf, sizeof(double) * QLOOKAHEAD);
memcpy(inbuf+QLOOKAHEAD, in, sizeof(double) * PITCH_FRAME_LEN);
/* lookahead pitch filtering for masking analysis */
WebRtcIsac_PitchfilterPre_la(inbuf, out, &(State->PFstr), lags, gains);
/* store last part of input */
for (k = 0; k < QLOOKAHEAD; k++)
State->inbuf[k] = inbuf[k + PITCH_FRAME_LEN];
}

View File

@@ -0,0 +1,71 @@
/*
* 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.
*/
/*
* pitch_estimator.h
*
* Pitch functions
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_
#include "structs.h"
void WebRtcIsac_PitchAnalysis(const double *in, /* PITCH_FRAME_LEN samples */
double *out, /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
PitchAnalysisStruct *State,
double *lags,
double *gains);
void WebRtcIsac_InitializePitch(const double *in,
const double old_lag,
const double old_gain,
PitchAnalysisStruct *State,
double *lags);
void WebRtcIsac_PitchfilterPre(double *indat,
double *outdat,
PitchFiltstr *pfp,
double *lags,
double *gains);
void WebRtcIsac_PitchfilterPost(double *indat,
double *outdat,
PitchFiltstr *pfp,
double *lags,
double *gains);
void WebRtcIsac_PitchfilterPre_la(double *indat,
double *outdat,
PitchFiltstr *pfp,
double *lags,
double *gains);
void WebRtcIsac_PitchfilterPre_gains(double *indat,
double *outdat,
double out_dG[][PITCH_FRAME_LEN + QLOOKAHEAD],
PitchFiltstr *pfp,
double *lags,
double *gains);
void WebRtcIsac_WeightingFilter(const double *in, double *weiout, double *whiout, WeightFiltstr *wfdata);
void WebRtcIsac_Highpass(const double *in, double *out, double *state, int N);
void WebRtcIsac_DecimateAllpass(const double *in,
double *state_in, /* array of size: 2*ALLPASSSECTIONS+1 */
int N, /* number of input samples */
double *out); /* array of size N/2 */
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_ESTIMATOR_H_ */

View File

@@ -0,0 +1,383 @@
/*
* Copyright (c) 2012 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 "pitch_estimator.h"
#include <math.h>
#include <memory.h>
#include <stdlib.h>
#include "os_specific_inline.h"
/*
* We are implementing the following filters;
*
* Pre-filtering:
* y(z) = x(z) + damper(z) * gain * (x(z) + y(z)) * z ^ (-lag);
*
* Post-filtering:
* y(z) = x(z) - damper(z) * gain * (x(z) + y(z)) * z ^ (-lag);
*
* Note that |lag| is a floating number so we perform an interpolation to
* obtain the correct |lag|.
*
*/
static const double kDampFilter[PITCH_DAMPORDER] = {-0.07, 0.25, 0.64, 0.25,
-0.07};
/* interpolation coefficients; generated by design_pitch_filter.m */
static const double kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
{-0.02239172458614, 0.06653315052934, -0.16515880017569, 0.60701333734125,
0.64671399919202, -0.20249000396417, 0.09926548334755, -0.04765933793109,
0.01754159521746},
{-0.01985640750434, 0.05816126837866, -0.13991265473714, 0.44560418147643,
0.79117042386876, -0.20266133815188, 0.09585268418555, -0.04533310458084,
0.01654127246314},
{-0.01463300534216, 0.04229888475060, -0.09897034715253, 0.28284326017787,
0.90385267956632, -0.16976950138649, 0.07704272393639, -0.03584218578311,
0.01295781500709},
{-0.00764851320885, 0.02184035544377, -0.04985561057281, 0.13083306574393,
0.97545011664662, -0.10177807997561, 0.04400901776474, -0.02010737175166,
0.00719783432422},
{-0.00000000000000, 0.00000000000000, -0.00000000000001, 0.00000000000001,
0.99999999999999, 0.00000000000001, -0.00000000000001, 0.00000000000000,
-0.00000000000000},
{0.00719783432422, -0.02010737175166, 0.04400901776474, -0.10177807997562,
0.97545011664663, 0.13083306574393, -0.04985561057280, 0.02184035544377,
-0.00764851320885},
{0.01295781500710, -0.03584218578312, 0.07704272393640, -0.16976950138650,
0.90385267956634, 0.28284326017785, -0.09897034715252, 0.04229888475059,
-0.01463300534216},
{0.01654127246315, -0.04533310458085, 0.09585268418557, -0.20266133815190,
0.79117042386878, 0.44560418147640, -0.13991265473712, 0.05816126837865,
-0.01985640750433}
};
/*
* Enumerating the operation of the filter.
* iSAC has 4 different pitch-filter which are very similar in their structure.
*
* kPitchFilterPre : In this mode the filter is operating as pitch
* pre-filter. This is used at the encoder.
* kPitchFilterPost : In this mode the filter is operating as pitch
* post-filter. This is the inverse of pre-filter and used
* in the decoder.
* kPitchFilterPreLa : This is, in structure, similar to pre-filtering but
* utilizing 3 millisecond lookahead. It is used to
* obtain the signal for LPC analysis.
* kPitchFilterPreGain : This is, in structure, similar to pre-filtering but
* differential changes in gain is considered. This is
* used to find the optimal gain.
*/
typedef enum {
kPitchFilterPre, kPitchFilterPost, kPitchFilterPreLa, kPitchFilterPreGain
} PitchFilterOperation;
/*
* Structure with parameters used for pitch-filtering.
* buffer : a buffer where the sum of previous inputs and outputs
* are stored.
* damper_state : the state of the damping filter. The filter is defined by
* |kDampFilter|.
* interpol_coeff : pointer to a set of coefficient which are used to utilize
* fractional pitch by interpolation.
* gain : pitch-gain to be applied to the current segment of input.
* lag : pitch-lag for the current segment of input.
* lag_offset : the offset of lag w.r.t. current sample.
* sub_frame : sub-frame index, there are 4 pitch sub-frames in an iSAC
* frame.
* This specifies the usage of the filter. See
* 'PitchFilterOperation' for operational modes.
* num_samples : number of samples to be processed in each segment.
* index : index of the input and output sample.
* damper_state_dg : state of damping filter for different trial gains.
* gain_mult : differential changes to gain.
*/
typedef struct {
double buffer[PITCH_INTBUFFSIZE + QLOOKAHEAD];
double damper_state[PITCH_DAMPORDER];
const double *interpol_coeff;
double gain;
double lag;
int lag_offset;
int sub_frame;
PitchFilterOperation mode;
int num_samples;
int index;
double damper_state_dg[4][PITCH_DAMPORDER];
double gain_mult[4];
} PitchFilterParam;
/**********************************************************************
* FilterSegment()
* Filter one segment, a quarter of a frame.
*
* Inputs
* in_data : pointer to the input signal of 30 ms at 8 kHz sample-rate.
* filter_param : pitch filter parameters.
*
* Outputs
* out_data : pointer to a buffer where the filtered signal is written to.
* out_dg : [only used in kPitchFilterPreGain] pointer to a buffer
* where the output of different gain values (differential
* change to gain) is written.
*/
static void FilterSegment(const double* in_data, PitchFilterParam* parameters,
double* out_data,
double out_dg[][PITCH_FRAME_LEN + QLOOKAHEAD]) {
int n;
int m;
int j;
double sum;
double sum2;
/* Index of |parameters->buffer| where the output is written to. */
int pos = parameters->index + PITCH_BUFFSIZE;
/* Index of |parameters->buffer| where samples are read for fractional-lag
* computation. */
int pos_lag = pos - parameters->lag_offset;
for (n = 0; n < parameters->num_samples; ++n) {
/* Shift low pass filter states. */
for (m = PITCH_DAMPORDER - 1; m > 0; --m) {
parameters->damper_state[m] = parameters->damper_state[m - 1];
}
/* Filter to get fractional pitch. */
sum = 0.0;
for (m = 0; m < PITCH_FRACORDER; ++m) {
sum += parameters->buffer[pos_lag + m] * parameters->interpol_coeff[m];
}
/* Multiply with gain. */
parameters->damper_state[0] = parameters->gain * sum;
if (parameters->mode == kPitchFilterPreGain) {
int lag_index = parameters->index - parameters->lag_offset;
int m_tmp = (lag_index < 0) ? -lag_index : 0;
/* Update the damper state for the new sample. */
for (m = PITCH_DAMPORDER - 1; m > 0; --m) {
for (j = 0; j < 4; ++j) {
parameters->damper_state_dg[j][m] =
parameters->damper_state_dg[j][m - 1];
}
}
for (j = 0; j < parameters->sub_frame + 1; ++j) {
/* Filter for fractional pitch. */
sum2 = 0.0;
for (m = PITCH_FRACORDER-1; m >= m_tmp; --m) {
/* |lag_index + m| is always larger than or equal to zero, see how
* m_tmp is computed. This is equivalent to assume samples outside
* |out_dg[j]| are zero. */
sum2 += out_dg[j][lag_index + m] * parameters->interpol_coeff[m];
}
/* Add the contribution of differential gain change. */
parameters->damper_state_dg[j][0] = parameters->gain_mult[j] * sum +
parameters->gain * sum2;
}
/* Filter with damping filter, and store the results. */
for (j = 0; j < parameters->sub_frame + 1; ++j) {
sum = 0.0;
for (m = 0; m < PITCH_DAMPORDER; ++m) {
sum -= parameters->damper_state_dg[j][m] * kDampFilter[m];
}
out_dg[j][parameters->index] = sum;
}
}
/* Filter with damping filter. */
sum = 0.0;
for (m = 0; m < PITCH_DAMPORDER; ++m) {
sum += parameters->damper_state[m] * kDampFilter[m];
}
/* Subtract from input and update buffer. */
out_data[parameters->index] = in_data[parameters->index] - sum;
parameters->buffer[pos] = in_data[parameters->index] +
out_data[parameters->index];
++parameters->index;
++pos;
++pos_lag;
}
return;
}
/* Update filter parameters based on the pitch-gains and pitch-lags. */
static void Update(PitchFilterParam* parameters) {
double fraction;
int fraction_index;
/* Compute integer lag-offset. */
parameters->lag_offset = WebRtcIsac_lrint(parameters->lag + PITCH_FILTDELAY +
0.5);
/* Find correct set of coefficients for computing fractional pitch. */
fraction = parameters->lag_offset - (parameters->lag + PITCH_FILTDELAY);
fraction_index = WebRtcIsac_lrint(PITCH_FRACS * fraction - 0.5);
parameters->interpol_coeff = kIntrpCoef[fraction_index];
if (parameters->mode == kPitchFilterPreGain) {
/* If in this mode make a differential change to pitch gain. */
parameters->gain_mult[parameters->sub_frame] += 0.2;
if (parameters->gain_mult[parameters->sub_frame] > 1.0) {
parameters->gain_mult[parameters->sub_frame] = 1.0;
}
if (parameters->sub_frame > 0) {
parameters->gain_mult[parameters->sub_frame - 1] -= 0.2;
}
}
}
/******************************************************************************
* FilterFrame()
* Filter a frame of 30 millisecond, given pitch-lags and pitch-gains.
*
* Inputs
* in_data : pointer to the input signal of 30 ms at 8 kHz sample-rate.
* lags : pointer to pitch-lags, 4 lags per frame.
* gains : pointer to pitch-gians, 4 gains per frame.
* mode : defining the functionality of the filter. It takes the
* following values.
* kPitchFilterPre: Pitch pre-filter, used at encoder.
* kPitchFilterPost: Pitch post-filter, used at decoder.
* kPitchFilterPreLa: Pitch pre-filter with lookahead.
* kPitchFilterPreGain: Pitch pre-filter used to otain optimal
* pitch-gains.
*
* Outputs
* out_data : pointer to a buffer where the filtered signal is written to.
* out_dg : [only used in kPitchFilterPreGain] pointer to a buffer
* where the output of different gain values (differential
* change to gain) is written.
*/
static void FilterFrame(const double* in_data, PitchFiltstr* filter_state,
double* lags, double* gains, PitchFilterOperation mode,
double* out_data,
double out_dg[][PITCH_FRAME_LEN + QLOOKAHEAD]) {
PitchFilterParam filter_parameters;
double gain_delta, lag_delta;
double old_lag, old_gain;
int n;
int m;
const double kEnhancer = 1.3;
/* Set up buffer and states. */
filter_parameters.index = 0;
filter_parameters.lag_offset = 0;
filter_parameters.mode = mode;
/* Copy states to local variables. */
memcpy(filter_parameters.buffer, filter_state->ubuf,
sizeof(filter_state->ubuf));
memcpy(filter_parameters.damper_state, filter_state->ystate,
sizeof(filter_state->ystate));
if (mode == kPitchFilterPreGain) {
/* Clear buffers. */
memset(filter_parameters.gain_mult, 0, sizeof(filter_parameters.gain_mult));
memset(filter_parameters.damper_state_dg, 0,
sizeof(filter_parameters.damper_state_dg));
for (n = 0; n < PITCH_SUBFRAMES; ++n) {
//memset(out_dg[n], 0, sizeof(double) * (PITCH_FRAME_LEN + QLOOKAHEAD));
memset(out_dg[n], 0, sizeof(out_dg[n]));
}
} else if (mode == kPitchFilterPost) {
/* Make output more periodic. Negative sign is to change the structure
* of the filter. */
for (n = 0; n < PITCH_SUBFRAMES; ++n) {
gains[n] *= -kEnhancer;
}
}
old_lag = *filter_state->oldlagp;
old_gain = *filter_state->oldgainp;
/* No interpolation if pitch lag step is big. */
if ((lags[0] > (PITCH_UPSTEP * old_lag)) ||
(lags[0] < (PITCH_DOWNSTEP * old_lag))) {
old_lag = lags[0];
old_gain = gains[0];
if (mode == kPitchFilterPreGain) {
filter_parameters.gain_mult[0] = 1.0;
}
}
filter_parameters.num_samples = PITCH_UPDATE;
for (m = 0; m < PITCH_SUBFRAMES; ++m) {
/* Set the sub-frame value. */
filter_parameters.sub_frame = m;
/* Calculate interpolation steps for pitch-lag and pitch-gain. */
lag_delta = (lags[m] - old_lag) / PITCH_GRAN_PER_SUBFRAME;
filter_parameters.lag = old_lag;
gain_delta = (gains[m] - old_gain) / PITCH_GRAN_PER_SUBFRAME;
filter_parameters.gain = old_gain;
/* Store for the next sub-frame. */
old_lag = lags[m];
old_gain = gains[m];
for (n = 0; n < PITCH_GRAN_PER_SUBFRAME; ++n) {
/* Step-wise interpolation of pitch gains and lags. As pitch-lag changes,
* some parameters of filter need to be update. */
filter_parameters.gain += gain_delta;
filter_parameters.lag += lag_delta;
/* Update parameters according to new lag value. */
Update(&filter_parameters);
/* Filter a segment of input. */
FilterSegment(in_data, &filter_parameters, out_data, out_dg);
}
}
if (mode != kPitchFilterPreGain) {
/* Export buffer and states. */
memcpy(filter_state->ubuf, &filter_parameters.buffer[PITCH_FRAME_LEN],
sizeof(filter_state->ubuf));
memcpy(filter_state->ystate, filter_parameters.damper_state,
sizeof(filter_state->ystate));
/* Store for the next frame. */
*filter_state->oldlagp = old_lag;
*filter_state->oldgainp = old_gain;
}
if ((mode == kPitchFilterPreGain) || (mode == kPitchFilterPreLa)) {
/* Filter the lookahead segment, this is treated as the last sub-frame. So
* set |pf_param| to last sub-frame. */
filter_parameters.sub_frame = PITCH_SUBFRAMES - 1;
filter_parameters.num_samples = QLOOKAHEAD;
FilterSegment(in_data, &filter_parameters, out_data, out_dg);
}
}
void WebRtcIsac_PitchfilterPre(double* in_data, double* out_data,
PitchFiltstr* pf_state, double* lags,
double* gains) {
FilterFrame(in_data, pf_state, lags, gains, kPitchFilterPre, out_data, NULL);
}
void WebRtcIsac_PitchfilterPre_la(double* in_data, double* out_data,
PitchFiltstr* pf_state, double* lags,
double* gains) {
FilterFrame(in_data, pf_state, lags, gains, kPitchFilterPreLa, out_data,
NULL);
}
void WebRtcIsac_PitchfilterPre_gains(
double* in_data, double* out_data,
double out_dg[][PITCH_FRAME_LEN + QLOOKAHEAD], PitchFiltstr *pf_state,
double* lags, double* gains) {
FilterFrame(in_data, pf_state, lags, gains, kPitchFilterPreGain, out_data,
out_dg);
}
void WebRtcIsac_PitchfilterPost(double* in_data, double* out_data,
PitchFiltstr* pf_state, double* lags,
double* gains) {
FilterFrame(in_data, pf_state, lags, gains, kPitchFilterPost, out_data, NULL);
}

View File

@@ -0,0 +1,105 @@
/*
* 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 "pitch_gain_tables.h"
#include "settings.h"
/* header file for coding tables for the pitch filter side-info in the entropy coder */
/********************* Pitch Filter Gain Coefficient Tables ************************/
/* cdf for quantized pitch filter gains */
const uint16_t WebRtcIsac_kQPitchGainCdf[255] = {
0, 2, 4, 6, 64, 901, 903, 905, 16954, 16956,
16961, 17360, 17362, 17364, 17366, 17368, 17370, 17372, 17374, 17411,
17514, 17516, 17583, 18790, 18796, 18802, 20760, 20777, 20782, 21722,
21724, 21728, 21738, 21740, 21742, 21744, 21746, 21748, 22224, 22227,
22230, 23214, 23229, 23239, 25086, 25108, 25120, 26088, 26094, 26098,
26175, 26177, 26179, 26181, 26183, 26185, 26484, 26507, 26522, 27705,
27731, 27750, 29767, 29799, 29817, 30866, 30883, 30885, 31025, 31029,
31031, 31033, 31035, 31037, 31114, 31126, 31134, 32687, 32722, 32767,
35718, 35742, 35757, 36943, 36952, 36954, 37115, 37128, 37130, 37132,
37134, 37136, 37143, 37145, 37152, 38843, 38863, 38897, 47458, 47467,
47474, 49040, 49061, 49063, 49145, 49157, 49159, 49161, 49163, 49165,
49167, 49169, 49171, 49757, 49770, 49782, 61333, 61344, 61346, 62860,
62883, 62885, 62887, 62889, 62891, 62893, 62895, 62897, 62899, 62901,
62903, 62905, 62907, 62909, 65496, 65498, 65500, 65521, 65523, 65525,
65527, 65529, 65531, 65533, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535};
/* index limits and ranges */
const int16_t WebRtcIsac_kIndexLowerLimitGain[3] = {
-7, -2, -1};
const int16_t WebRtcIsac_kIndexUpperLimitGain[3] = {
0, 3, 1};
const uint16_t WebRtcIsac_kIndexMultsGain[2] = {
18, 3};
/* size of cdf table */
const uint16_t WebRtcIsac_kQCdfTableSizeGain[1] = {
256};
///////////////////////////FIXED POINT
/* mean values of pitch filter gains in FIXED point */
const int16_t WebRtcIsac_kQMeanGain1Q12[144] = {
843, 1092, 1336, 1222, 1405, 1656, 1500, 1815, 1843, 1838, 1839, 1843, 1843, 1843, 1843, 1843,
1843, 1843, 814, 846, 1092, 1013, 1174, 1383, 1391, 1511, 1584, 1734, 1753, 1843, 1843, 1843,
1843, 1843, 1843, 1843, 524, 689, 777, 845, 947, 1069, 1090, 1263, 1380, 1447, 1559, 1676,
1645, 1749, 1843, 1843, 1843, 1843, 81, 477, 563, 611, 706, 806, 849, 1012, 1192, 1128,
1330, 1489, 1425, 1576, 1826, 1741, 1843, 1843, 0, 290, 305, 356, 488, 575, 602, 741,
890, 835, 1079, 1196, 1182, 1376, 1519, 1506, 1680, 1843, 0, 47, 97, 69, 289, 381,
385, 474, 617, 664, 803, 1079, 935, 1160, 1269, 1265, 1506, 1741, 0, 0, 0, 0,
112, 120, 190, 283, 442, 343, 526, 809, 684, 935, 1134, 1020, 1265, 1506, 0, 0,
0, 0, 0, 0, 0, 111, 256, 87, 373, 597, 430, 684, 935, 770, 1020, 1265};
const int16_t WebRtcIsac_kQMeanGain2Q12[144] = {
1760, 1525, 1285, 1747, 1671, 1393, 1843, 1826, 1555, 1843, 1784, 1606, 1843, 1843, 1711, 1843,
1843, 1814, 1389, 1275, 1040, 1564, 1414, 1252, 1610, 1495, 1343, 1753, 1592, 1405, 1804, 1720,
1475, 1843, 1814, 1581, 1208, 1061, 856, 1349, 1148, 994, 1390, 1253, 1111, 1495, 1343, 1178,
1770, 1465, 1234, 1814, 1581, 1342, 1040, 793, 713, 1053, 895, 737, 1128, 1003, 861, 1277,
1094, 981, 1475, 1192, 1019, 1581, 1342, 1098, 855, 570, 483, 833, 648, 540, 948, 744,
572, 1009, 844, 636, 1234, 934, 685, 1342, 1217, 984, 537, 318, 124, 603, 423, 350,
687, 479, 322, 791, 581, 430, 987, 671, 488, 1098, 849, 597, 283, 27, 0, 397,
222, 38, 513, 271, 124, 624, 325, 157, 737, 484, 233, 849, 597, 343, 27, 0,
0, 141, 0, 0, 256, 69, 0, 370, 87, 0, 484, 229, 0, 597, 343, 87};
const int16_t WebRtcIsac_kQMeanGain3Q12[144] = {
1843, 1843, 1711, 1843, 1818, 1606, 1843, 1827, 1511, 1814, 1639, 1393, 1760, 1525, 1285, 1656,
1419, 1176, 1835, 1718, 1475, 1841, 1650, 1387, 1648, 1498, 1287, 1600, 1411, 1176, 1522, 1299,
1040, 1419, 1176, 928, 1773, 1461, 1128, 1532, 1355, 1202, 1429, 1260, 1115, 1398, 1151, 1025,
1172, 1080, 790, 1176, 928, 677, 1475, 1147, 1019, 1276, 1096, 922, 1214, 1010, 901, 1057,
893, 800, 1040, 796, 734, 928, 677, 424, 1137, 897, 753, 1120, 830, 710, 875, 751,
601, 795, 642, 583, 790, 544, 475, 677, 474, 140, 987, 750, 482, 697, 573, 450,
691, 487, 303, 661, 394, 332, 537, 303, 220, 424, 168, 0, 737, 484, 229, 624,
348, 153, 441, 261, 136, 397, 166, 51, 283, 27, 0, 168, 0, 0, 484, 229,
0, 370, 57, 0, 256, 43, 0, 141, 0, 0, 27, 0, 0, 0, 0, 0};
const int16_t WebRtcIsac_kQMeanGain4Q12[144] = {
1843, 1843, 1843, 1843, 1841, 1843, 1500, 1821, 1843, 1222, 1434, 1656, 843, 1092, 1336, 504,
757, 1007, 1843, 1843, 1843, 1838, 1791, 1843, 1265, 1505, 1599, 965, 1219, 1425, 730, 821,
1092, 249, 504, 757, 1783, 1819, 1843, 1351, 1567, 1727, 1096, 1268, 1409, 805, 961, 1131,
444, 670, 843, 0, 249, 504, 1425, 1655, 1743, 1096, 1324, 1448, 822, 1019, 1199, 490,
704, 867, 81, 450, 555, 0, 0, 249, 1247, 1428, 1530, 881, 1073, 1283, 610, 759,
939, 278, 464, 645, 0, 200, 270, 0, 0, 0, 935, 1163, 1410, 528, 790, 1068,
377, 499, 717, 173, 240, 274, 0, 43, 62, 0, 0, 0, 684, 935, 1182, 343,
551, 735, 161, 262, 423, 0, 55, 27, 0, 0, 0, 0, 0, 0, 430, 684,
935, 87, 377, 597, 0, 46, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0};

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
/*
* pitch_gain_tables.h
*
* This file contains tables for the pitch filter side-info in the entropy coder.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_
#include "typedefs.h"
/* header file for coding tables for the pitch filter side-info in the entropy coder */
/********************* Pitch Filter Gain Coefficient Tables ************************/
/* cdf for quantized pitch filter gains */
extern const uint16_t WebRtcIsac_kQPitchGainCdf[255];
/* index limits and ranges */
extern const int16_t WebRtcIsac_kIndexLowerLimitGain[3];
extern const int16_t WebRtcIsac_kIndexUpperLimitGain[3];
extern const uint16_t WebRtcIsac_kIndexMultsGain[2];
/* mean values of pitch filter gains */
//(Y)
extern const int16_t WebRtcIsac_kQMeanGain1Q12[144];
extern const int16_t WebRtcIsac_kQMeanGain2Q12[144];
extern const int16_t WebRtcIsac_kQMeanGain3Q12[144];
extern const int16_t WebRtcIsac_kQMeanGain4Q12[144];
//(Y)
/* size of cdf table */
extern const uint16_t WebRtcIsac_kQCdfTableSizeGain[1];
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_ */

View File

@@ -0,0 +1,277 @@
/*
* 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 "pitch_lag_tables.h"
#include "settings.h"
/* header file for coding tables for the pitch filter side-info in the entropy coder */
/********************* Pitch Filter Gain Coefficient Tables ************************/
/* tables for use with small pitch gain */
/* cdf for quantized pitch filter lags */
const uint16_t WebRtcIsac_kQPitchLagCdf1Lo[127] = {
0, 134, 336, 549, 778, 998, 1264, 1512, 1777, 2070,
2423, 2794, 3051, 3361, 3708, 3979, 4315, 4610, 4933, 5269,
5575, 5896, 6155, 6480, 6816, 7129, 7477, 7764, 8061, 8358,
8718, 9020, 9390, 9783, 10177, 10543, 10885, 11342, 11795, 12213,
12680, 13096, 13524, 13919, 14436, 14903, 15349, 15795, 16267, 16734,
17266, 17697, 18130, 18632, 19080, 19447, 19884, 20315, 20735, 21288,
21764, 22264, 22723, 23193, 23680, 24111, 24557, 25022, 25537, 26082,
26543, 27090, 27620, 28139, 28652, 29149, 29634, 30175, 30692, 31273,
31866, 32506, 33059, 33650, 34296, 34955, 35629, 36295, 36967, 37726,
38559, 39458, 40364, 41293, 42256, 43215, 44231, 45253, 46274, 47359,
48482, 49678, 50810, 51853, 53016, 54148, 55235, 56263, 57282, 58363,
59288, 60179, 61076, 61806, 62474, 63129, 63656, 64160, 64533, 64856,
65152, 65535, 65535, 65535, 65535, 65535, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf2Lo[20] = {
0, 429, 3558, 5861, 8558, 11639, 15210, 19502, 24773, 31983,
42602, 48567, 52601, 55676, 58160, 60172, 61889, 63235, 65383, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf3Lo[2] = {
0, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf4Lo[10] = {
0, 2966, 6368, 11182, 19431, 37793, 48532, 55353, 60626, 65535};
const uint16_t *WebRtcIsac_kQPitchLagCdfPtrLo[4] = {WebRtcIsac_kQPitchLagCdf1Lo, WebRtcIsac_kQPitchLagCdf2Lo, WebRtcIsac_kQPitchLagCdf3Lo, WebRtcIsac_kQPitchLagCdf4Lo};
/* size of first cdf table */
const uint16_t WebRtcIsac_kQPitchLagCdfSizeLo[1] = {128};
/* index limits and ranges */
const int16_t WebRtcIsac_kQIndexLowerLimitLagLo[4] = {
-140, -9, 0, -4};
const int16_t WebRtcIsac_kQIndexUpperLimitLagLo[4] = {
-20, 9, 0, 4};
/* initial index for arithmetic decoder */
const uint16_t WebRtcIsac_kQInitIndexLagLo[3] = {
10, 1, 5};
/* mean values of pitch filter lags */
const double WebRtcIsac_kQMeanLag2Lo[19] = {
-17.21385070, -15.82678944, -14.07123081, -12.03003877, -10.01311864, -8.00794627, -5.91162987, -3.89231876, -1.90220980, -0.01879275,
1.89144232, 3.88123171, 5.92146992, 7.96435361, 9.98923648, 11.98266347, 13.96101002, 15.74855713, 17.10976611};
const double WebRtcIsac_kQMeanLag3Lo[1] = {
0.00000000};
const double WebRtcIsac_kQMeanLag4Lo[9] = {
-7.76246496, -5.92083980, -3.94095226, -1.89502305, 0.03724681, 1.93054221, 3.96443467, 5.91726366, 7.78434291};
const double WebRtcIsac_kQPitchLagStepsizeLo = 2.000000;
/* tables for use with medium pitch gain */
/* cdf for quantized pitch filter lags */
const uint16_t WebRtcIsac_kQPitchLagCdf1Mid[255] = {
0, 28, 61, 88, 121, 149, 233, 331, 475, 559,
624, 661, 689, 712, 745, 791, 815, 843, 866, 922,
959, 1024, 1061, 1117, 1178, 1238, 1280, 1350, 1453, 1513,
1564, 1625, 1671, 1741, 1788, 1904, 2072, 2421, 2626, 2770,
2840, 2900, 2942, 3012, 3068, 3115, 3147, 3194, 3254, 3319,
3366, 3520, 3678, 3780, 3850, 3911, 3957, 4032, 4106, 4185,
4292, 4474, 4683, 4842, 5019, 5191, 5321, 5428, 5540, 5675,
5763, 5847, 5959, 6127, 6304, 6564, 6839, 7090, 7263, 7421,
7556, 7728, 7872, 7984, 8142, 8361, 8580, 8743, 8938, 9227,
9409, 9539, 9674, 9795, 9930, 10060, 10177, 10382, 10614, 10861,
11038, 11271, 11415, 11629, 11792, 12044, 12193, 12416, 12574, 12821,
13007, 13235, 13445, 13654, 13901, 14134, 14488, 15000, 15703, 16285,
16504, 16797, 17086, 17328, 17579, 17807, 17998, 18268, 18538, 18836,
19087, 19274, 19474, 19716, 19935, 20270, 20833, 21303, 21532, 21741,
21978, 22207, 22523, 22770, 23054, 23613, 23943, 24204, 24399, 24651,
24832, 25074, 25270, 25549, 25759, 26015, 26150, 26424, 26713, 27048,
27342, 27504, 27681, 27854, 28021, 28207, 28412, 28664, 28859, 29064,
29278, 29548, 29748, 30107, 30377, 30656, 30856, 31164, 31452, 31755,
32011, 32328, 32626, 32919, 33319, 33789, 34329, 34925, 35396, 35973,
36443, 36964, 37551, 38156, 38724, 39357, 40023, 40908, 41587, 42602,
43924, 45037, 45810, 46597, 47421, 48291, 49092, 50051, 51448, 52719,
53440, 54241, 54944, 55977, 56676, 57299, 57872, 58389, 59059, 59688,
60237, 60782, 61094, 61573, 61890, 62290, 62658, 63030, 63217, 63454,
63622, 63882, 64003, 64273, 64427, 64529, 64581, 64697, 64758, 64902,
65414, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf2Mid[36] = {
0, 71, 335, 581, 836, 1039, 1323, 1795, 2258, 2608,
3005, 3591, 4243, 5344, 7163, 10583, 16848, 28078, 49448, 57007,
60357, 61850, 62837, 63437, 63872, 64188, 64377, 64614, 64774, 64949,
65039, 65115, 65223, 65360, 65474, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf3Mid[2] = {
0, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf4Mid[20] = {
0, 28, 246, 459, 667, 1045, 1523, 2337, 4337, 11347,
44231, 56709, 60781, 62243, 63161, 63969, 64608, 65062, 65502, 65535};
const uint16_t *WebRtcIsac_kQPitchLagCdfPtrMid[4] = {WebRtcIsac_kQPitchLagCdf1Mid, WebRtcIsac_kQPitchLagCdf2Mid, WebRtcIsac_kQPitchLagCdf3Mid, WebRtcIsac_kQPitchLagCdf4Mid};
/* size of first cdf table */
const uint16_t WebRtcIsac_kQPitchLagCdfSizeMid[1] = {256};
/* index limits and ranges */
const int16_t WebRtcIsac_kQIndexLowerLimitLagMid[4] = {
-280, -17, 0, -9};
const int16_t WebRtcIsac_kQIndexUpperLimitLagMid[4] = {
-40, 17, 0, 9};
/* initial index for arithmetic decoder */
const uint16_t WebRtcIsac_kQInitIndexLagMid[3] = {
18, 1, 10};
/* mean values of pitch filter lags */
const double WebRtcIsac_kQMeanLag2Mid[35] = {
-16.89183900, -15.86949778, -15.05476653, -14.00664348, -13.02793036, -12.07324237, -11.00542532, -10.11250602, -8.90792971, -8.02474753,
-7.00426767, -5.94055287, -4.98251338, -3.91053158, -2.98820425, -1.93524245, -0.92978085, -0.01722509, 0.91317387, 1.92973955,
2.96908851, 3.93728974, 4.96308471, 5.92244151, 7.08673497, 8.00993708, 9.04656316, 9.98538742, 10.97851694, 11.94772884,
13.02426166, 14.00039951, 15.01347042, 15.80758023, 16.94086895};
const double WebRtcIsac_kQMeanLag3Mid[1] = {
0.00000000};
const double WebRtcIsac_kQMeanLag4Mid[19] = {
-8.60409403, -7.89198395, -7.03450280, -5.86260421, -4.93822322, -3.93078706, -2.91302322, -1.91824007, -0.87003282, 0.02822649,
0.89951758, 1.87495484, 2.91802604, 3.96874074, 5.06571703, 5.93618227, 7.00520185, 7.88497726, 8.64160364};
const double WebRtcIsac_kQPitchLagStepsizeMid = 1.000000;
/* tables for use with large pitch gain */
/* cdf for quantized pitch filter lags */
const uint16_t WebRtcIsac_kQPitchLagCdf1Hi[511] = {
0, 7, 18, 33, 69, 105, 156, 228, 315, 612,
680, 691, 709, 724, 735, 738, 742, 746, 749, 753,
756, 760, 764, 774, 782, 785, 789, 796, 800, 803,
807, 814, 818, 822, 829, 832, 847, 854, 858, 869,
876, 883, 898, 908, 934, 977, 1010, 1050, 1060, 1064,
1075, 1078, 1086, 1089, 1093, 1104, 1111, 1122, 1133, 1136,
1151, 1162, 1183, 1209, 1252, 1281, 1339, 1364, 1386, 1401,
1411, 1415, 1426, 1430, 1433, 1440, 1448, 1455, 1462, 1477,
1487, 1495, 1502, 1506, 1509, 1516, 1524, 1531, 1535, 1542,
1553, 1556, 1578, 1589, 1611, 1625, 1639, 1643, 1654, 1665,
1672, 1687, 1694, 1705, 1708, 1719, 1730, 1744, 1752, 1759,
1791, 1795, 1820, 1867, 1886, 1915, 1936, 1943, 1965, 1987,
2041, 2099, 2161, 2175, 2200, 2211, 2226, 2233, 2244, 2251,
2266, 2280, 2287, 2298, 2309, 2316, 2331, 2342, 2356, 2378,
2403, 2418, 2447, 2497, 2544, 2602, 2863, 2895, 2903, 2935,
2950, 2971, 3004, 3011, 3018, 3029, 3040, 3062, 3087, 3127,
3152, 3170, 3199, 3243, 3293, 3322, 3340, 3377, 3402, 3427,
3474, 3518, 3543, 3579, 3601, 3637, 3659, 3706, 3731, 3760,
3818, 3847, 3869, 3901, 3920, 3952, 4068, 4169, 4220, 4271,
4524, 4571, 4604, 4632, 4672, 4730, 4777, 4806, 4857, 4904,
4951, 5002, 5031, 5060, 5107, 5150, 5212, 5266, 5331, 5382,
5432, 5490, 5544, 5610, 5700, 5762, 5812, 5874, 5972, 6022,
6091, 6163, 6232, 6305, 6402, 6540, 6685, 6880, 7090, 7271,
7379, 7452, 7542, 7625, 7687, 7770, 7843, 7911, 7966, 8024,
8096, 8190, 8252, 8320, 8411, 8501, 8585, 8639, 8751, 8842,
8918, 8986, 9066, 9127, 9203, 9269, 9345, 9406, 9464, 9536,
9612, 9667, 9735, 9844, 9931, 10036, 10119, 10199, 10260, 10358,
10441, 10514, 10666, 10734, 10872, 10951, 11053, 11125, 11223, 11324,
11516, 11664, 11737, 11816, 11892, 12008, 12120, 12200, 12280, 12392,
12490, 12576, 12685, 12812, 12917, 13003, 13108, 13210, 13300, 13384,
13470, 13579, 13673, 13771, 13879, 13999, 14136, 14201, 14368, 14614,
14759, 14867, 14958, 15030, 15121, 15189, 15280, 15385, 15461, 15555,
15653, 15768, 15884, 15971, 16069, 16145, 16210, 16279, 16380, 16463,
16539, 16615, 16688, 16818, 16919, 17017, 18041, 18338, 18523, 18649,
18790, 18917, 19047, 19167, 19315, 19460, 19601, 19731, 19858, 20068,
20173, 20318, 20466, 20625, 20741, 20911, 21045, 21201, 21396, 21588,
21816, 22022, 22305, 22547, 22786, 23072, 23322, 23600, 23879, 24168,
24433, 24769, 25120, 25511, 25895, 26289, 26792, 27219, 27683, 28077,
28566, 29094, 29546, 29977, 30491, 30991, 31573, 32105, 32594, 33173,
33788, 34497, 35181, 35833, 36488, 37255, 37921, 38645, 39275, 39894,
40505, 41167, 41790, 42431, 43096, 43723, 44385, 45134, 45858, 46607,
47349, 48091, 48768, 49405, 49955, 50555, 51167, 51985, 52611, 53078,
53494, 53965, 54435, 54996, 55601, 56125, 56563, 56838, 57244, 57566,
57967, 58297, 58771, 59093, 59419, 59647, 59886, 60143, 60461, 60693,
60917, 61170, 61416, 61634, 61891, 62122, 62310, 62455, 62632, 62839,
63103, 63436, 63639, 63805, 63906, 64015, 64192, 64355, 64475, 64558,
64663, 64742, 64811, 64865, 64916, 64956, 64981, 65025, 65068, 65115,
65195, 65314, 65419, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535,
65535};
const uint16_t WebRtcIsac_kQPitchLagCdf2Hi[68] = {
0, 7, 11, 22, 37, 52, 56, 59, 81, 85,
89, 96, 115, 130, 137, 152, 170, 181, 193, 200,
207, 233, 237, 259, 289, 318, 363, 433, 592, 992,
1607, 3062, 6149, 12206, 25522, 48368, 58223, 61918, 63640, 64584,
64943, 65098, 65206, 65268, 65294, 65335, 65350, 65372, 65387, 65402,
65413, 65420, 65428, 65435, 65439, 65450, 65454, 65468, 65472, 65476,
65483, 65491, 65498, 65505, 65516, 65520, 65528, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf3Hi[2] = {
0, 65535};
const uint16_t WebRtcIsac_kQPitchLagCdf4Hi[35] = {
0, 7, 19, 30, 41, 48, 63, 74, 82, 96,
122, 152, 215, 330, 701, 2611, 10931, 48106, 61177, 64341,
65112, 65238, 65309, 65338, 65364, 65379, 65401, 65427, 65453, 65465,
65476, 65490, 65509, 65528, 65535};
const uint16_t *WebRtcIsac_kQPitchLagCdfPtrHi[4] = {WebRtcIsac_kQPitchLagCdf1Hi, WebRtcIsac_kQPitchLagCdf2Hi, WebRtcIsac_kQPitchLagCdf3Hi, WebRtcIsac_kQPitchLagCdf4Hi};
/* size of first cdf table */
const uint16_t WebRtcIsac_kQPitchLagCdfSizeHi[1] = {512};
/* index limits and ranges */
const int16_t WebRtcIsac_kQindexLowerLimitLagHi[4] = {
-552, -34, 0, -16};
const int16_t WebRtcIsac_kQindexUpperLimitLagHi[4] = {
-80, 32, 0, 17};
/* initial index for arithmetic decoder */
const uint16_t WebRtcIsac_kQInitIndexLagHi[3] = {
34, 1, 18};
/* mean values of pitch filter lags */
const double WebRtcIsac_kQMeanLag2Hi[67] = {
-17.07263295, -16.50000000, -15.83966081, -15.55613708, -14.96948007, -14.50000000, -14.00000000, -13.48377986, -13.00000000, -12.50000000,
-11.93199636, -11.44530414, -11.04197641, -10.39910301, -10.15202337, -9.51322461, -8.93357741, -8.46456632, -8.10270672, -7.53751847,
-6.98686404, -6.50000000, -6.08463150, -5.46872991, -5.00864717, -4.50163760, -4.01382410, -3.43856708, -2.96898001, -2.46554810,
-1.96861004, -1.47106701, -0.97197237, -0.46561654, -0.00531409, 0.45767857, 0.96777907, 1.47507903, 1.97740425, 2.46695420,
3.00695774, 3.47167185, 4.02712538, 4.49280007, 5.01087640, 5.48191963, 6.04916550, 6.51511058, 6.97297819, 7.46565499,
8.01489405, 8.39912001, 8.91819757, 9.50000000, 10.11654065, 10.50000000, 11.03712583, 11.50000000, 12.00000000, 12.38964346,
12.89466127, 13.43657881, 13.96013840, 14.46279912, 15.00000000, 15.39412269, 15.96662441};
const double WebRtcIsac_kQMeanLag3Hi[1] = {
0.00000000};
const double WebRtcIsac_kQMeanLag4Hi[34] = {
-7.98331221, -7.47988769, -7.03626557, -6.52708003, -6.06982173, -5.51856292, -5.05827033, -4.45909878, -3.99125864, -3.45308135,
-3.02328139, -2.47297273, -1.94341995, -1.44699056, -0.93612243, -0.43012406, 0.01120357, 0.44054812, 0.93199883, 1.45669587,
1.97218322, 2.50187419, 2.98748690, 3.49343202, 4.01660147, 4.50984306, 5.01402683, 5.58936797, 5.91787793, 6.59998900,
6.85034315, 7.53503316, 7.87711194, 8.53631648};
const double WebRtcIsac_kQPitchLagStepsizeHi = 0.500000;
/* transform matrix */
const double WebRtcIsac_kTransform[4][4] = {
{-0.50000000, -0.50000000, -0.50000000, -0.50000000},
{ 0.67082039, 0.22360680, -0.22360680, -0.67082039},
{ 0.50000000, -0.50000000, -0.50000000, 0.50000000},
{ 0.22360680, -0.67082039, 0.67082039, -0.22360680}};
/* transpose transform matrix */
const double WebRtcIsac_kTransformTranspose[4][4] = {
{-0.50000000, 0.67082039, 0.50000000, 0.22360680},
{-0.50000000, 0.22360680, -0.50000000, -0.67082039},
{-0.50000000, -0.22360680, -0.50000000, 0.67082039},
{-0.50000000, -0.67082039, 0.50000000, -0.22360680}};

View File

@@ -0,0 +1,114 @@
/*
* 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.
*/
/*
* pitch_lag_tables.h
*
* This file contains tables for the pitch filter side-info in the entropy coder.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_
#include "typedefs.h"
/* header file for coding tables for the pitch filter side-info in the entropy coder */
/********************* Pitch Filter Lag Coefficient Tables ************************/
/* tables for use with small pitch gain */
/* cdfs for quantized pitch lags */
extern const uint16_t WebRtcIsac_kQPitchLagCdf1Lo[127];
extern const uint16_t WebRtcIsac_kQPitchLagCdf2Lo[20];
extern const uint16_t WebRtcIsac_kQPitchLagCdf3Lo[2];
extern const uint16_t WebRtcIsac_kQPitchLagCdf4Lo[10];
extern const uint16_t *WebRtcIsac_kQPitchLagCdfPtrLo[4];
/* size of first cdf table */
extern const uint16_t WebRtcIsac_kQPitchLagCdfSizeLo[1];
/* index limits and ranges */
extern const int16_t WebRtcIsac_kQIndexLowerLimitLagLo[4];
extern const int16_t WebRtcIsac_kQIndexUpperLimitLagLo[4];
/* initial index for arithmetic decoder */
extern const uint16_t WebRtcIsac_kQInitIndexLagLo[3];
/* mean values of pitch filter lags */
extern const double WebRtcIsac_kQMeanLag2Lo[19];
extern const double WebRtcIsac_kQMeanLag3Lo[1];
extern const double WebRtcIsac_kQMeanLag4Lo[9];
extern const double WebRtcIsac_kQPitchLagStepsizeLo;
/* tables for use with medium pitch gain */
/* cdfs for quantized pitch lags */
extern const uint16_t WebRtcIsac_kQPitchLagCdf1Mid[255];
extern const uint16_t WebRtcIsac_kQPitchLagCdf2Mid[36];
extern const uint16_t WebRtcIsac_kQPitchLagCdf3Mid[2];
extern const uint16_t WebRtcIsac_kQPitchLagCdf4Mid[20];
extern const uint16_t *WebRtcIsac_kQPitchLagCdfPtrMid[4];
/* size of first cdf table */
extern const uint16_t WebRtcIsac_kQPitchLagCdfSizeMid[1];
/* index limits and ranges */
extern const int16_t WebRtcIsac_kQIndexLowerLimitLagMid[4];
extern const int16_t WebRtcIsac_kQIndexUpperLimitLagMid[4];
/* initial index for arithmetic decoder */
extern const uint16_t WebRtcIsac_kQInitIndexLagMid[3];
/* mean values of pitch filter lags */
extern const double WebRtcIsac_kQMeanLag2Mid[35];
extern const double WebRtcIsac_kQMeanLag3Mid[1];
extern const double WebRtcIsac_kQMeanLag4Mid[19];
extern const double WebRtcIsac_kQPitchLagStepsizeMid;
/* tables for use with large pitch gain */
/* cdfs for quantized pitch lags */
extern const uint16_t WebRtcIsac_kQPitchLagCdf1Hi[511];
extern const uint16_t WebRtcIsac_kQPitchLagCdf2Hi[68];
extern const uint16_t WebRtcIsac_kQPitchLagCdf3Hi[2];
extern const uint16_t WebRtcIsac_kQPitchLagCdf4Hi[35];
extern const uint16_t *WebRtcIsac_kQPitchLagCdfPtrHi[4];
/* size of first cdf table */
extern const uint16_t WebRtcIsac_kQPitchLagCdfSizeHi[1];
/* index limits and ranges */
extern const int16_t WebRtcIsac_kQindexLowerLimitLagHi[4];
extern const int16_t WebRtcIsac_kQindexUpperLimitLagHi[4];
/* initial index for arithmetic decoder */
extern const uint16_t WebRtcIsac_kQInitIndexLagHi[3];
/* mean values of pitch filter lags */
extern const double WebRtcIsac_kQMeanLag2Hi[67];
extern const double WebRtcIsac_kQMeanLag3Hi[1];
extern const double WebRtcIsac_kQMeanLag4Hi[34];
extern const double WebRtcIsac_kQPitchLagStepsizeHi;
/* transform matrix */
extern const double WebRtcIsac_kTransform[4][4];
/* transpose transform matrix */
extern const double WebRtcIsac_kTransformTranspose[4][4];
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_ */

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2012 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.
*/
/*
* settings.h
*
* Declaration of #defines used in the iSAC codec
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_
/* sampling frequency (Hz) */
#define FS 16000
/* number of samples per frame (either 320 (20ms), 480 (30ms) or 960 (60ms)) */
#define INITIAL_FRAMESAMPLES 960
#define MAXFFTSIZE 2048
#define NFACTOR 11
/* do not modify the following; this will have to be modified if we
* have a 20ms framesize option */
/**********************************************************************/
/* miliseconds */
#define FRAMESIZE 30
/* number of samples per frame processed in the encoder, 480 */
#define FRAMESAMPLES 480 /* ((FRAMESIZE*FS)/1000) */
#define FRAMESAMPLES_HALF 240
#define FRAMESAMPLES_QUARTER 120
/**********************************************************************/
/* max number of samples per frame (= 60 ms frame) */
#define MAX_FRAMESAMPLES 960
#define MAX_SWBFRAMESAMPLES (MAX_FRAMESAMPLES * 2)
/* number of samples per 10ms frame */
#define FRAMESAMPLES_10ms ((10*FS)/1000)
#define SWBFRAMESAMPLES_10ms (FRAMESAMPLES_10ms * 2)
/* number of samples in 30 ms frame */
#define FRAMESAMPLES_30ms 480
/* number of subframes */
#define SUBFRAMES 6
/* length of a subframe */
#define UPDATE 80
/* length of half a subframe (low/high band) */
#define HALF_SUBFRAMELEN (UPDATE/2)
/* samples of look ahead (in a half-band, so actually
* half the samples of look ahead @ FS) */
#define QLOOKAHEAD 24 /* 3 ms */
/* order of AR model in spectral entropy coder */
#define AR_ORDER 6
/* order of LP model in spectral entropy coder */
#define LP_ORDER 0
/* window length (masking analysis) */
#define WINLEN 256
/* order of low-band pole filter used to approximate masking curve */
#define ORDERLO 12
/* order of hi-band pole filter used to approximate masking curve */
#define ORDERHI 6
#define UB_LPC_ORDER 4
#define UB_LPC_VEC_PER_FRAME 2
#define UB16_LPC_VEC_PER_FRAME 4
#define UB_ACTIVE_SUBFRAMES 2
#define UB_MAX_LPC_ORDER 6
#define UB_INTERPOL_SEGMENTS 1
#define UB16_INTERPOL_SEGMENTS 3
#define LB_TOTAL_DELAY_SAMPLES 48
enum ISACBandwidth {isac8kHz = 8, isac12kHz = 12, isac16kHz = 16};
enum ISACBand {kIsacLowerBand = 0, kIsacUpperBand12 = 1, kIsacUpperBand16 = 2};
enum IsacSamplingRate {kIsacWideband = 16, kIsacSuperWideband = 32};
#define UB_LPC_GAIN_DIM SUBFRAMES
#define FB_STATE_SIZE_WORD32 6
/* order for post_filter_bank */
#define POSTQORDER 3
/* order for pre-filterbank */
#define QORDER 3
/* another order */
#define QORDER_ALL (POSTQORDER+QORDER-1)
/* for decimator */
#define ALLPASSSECTIONS 2
/* array size for byte stream in number of bytes. */
/* The old maximum size still needed for the decoding */
#define STREAM_SIZE_MAX 600
#define STREAM_SIZE_MAX_30 200 /* 200 bytes=53.4 kbps @ 30 ms.framelength */
#define STREAM_SIZE_MAX_60 400 /* 400 bytes=53.4 kbps @ 60 ms.framelength */
/* storage size for bit counts */
#define BIT_COUNTER_SIZE 30
/* maximum order of any AR model or filter */
#define MAX_AR_MODEL_ORDER 12//50
/* For pitch analysis */
#define PITCH_FRAME_LEN (FRAMESAMPLES_HALF) /* 30 ms */
#define PITCH_MAX_LAG 140 /* 57 Hz */
#define PITCH_MIN_LAG 20 /* 400 Hz */
#define PITCH_MAX_GAIN 0.45
#define PITCH_MAX_GAIN_06 0.27 /* PITCH_MAX_GAIN*0.6 */
#define PITCH_MAX_GAIN_Q12 1843
#define PITCH_LAG_SPAN2 (PITCH_MAX_LAG/2-PITCH_MIN_LAG/2+5)
#define PITCH_CORR_LEN2 60 /* 15 ms */
#define PITCH_CORR_STEP2 (PITCH_FRAME_LEN/4)
#define PITCH_BW 11 /* half the band width of correlation surface */
#define PITCH_SUBFRAMES 4
#define PITCH_GRAN_PER_SUBFRAME 5
#define PITCH_SUBFRAME_LEN (PITCH_FRAME_LEN/PITCH_SUBFRAMES)
#define PITCH_UPDATE (PITCH_SUBFRAME_LEN/PITCH_GRAN_PER_SUBFRAME)
/* maximum number of peaks to be examined in correlation surface */
#define PITCH_MAX_NUM_PEAKS 10
#define PITCH_PEAK_DECAY 0.85
/* For weighting filter */
#define PITCH_WLPCORDER 6
#define PITCH_WLPCWINLEN PITCH_FRAME_LEN
#define PITCH_WLPCASYM 0.3 /* asymmetry parameter */
#define PITCH_WLPCBUFLEN PITCH_WLPCWINLEN
/* For pitch filter */
/* Extra 50 for fraction and LP filters */
#define PITCH_BUFFSIZE (PITCH_MAX_LAG + 50)
#define PITCH_INTBUFFSIZE (PITCH_FRAME_LEN+PITCH_BUFFSIZE)
/* Max rel. step for interpolation */
#define PITCH_UPSTEP 1.5
/* Max rel. step for interpolation */
#define PITCH_DOWNSTEP 0.67
#define PITCH_FRACS 8
#define PITCH_FRACORDER 9
#define PITCH_DAMPORDER 5
#define PITCH_FILTDELAY 1.5f
/* stepsize for quantization of the pitch Gain */
#define PITCH_GAIN_STEPSIZE 0.125
/* Order of high pass filter */
#define HPORDER 2
/* some mathematical constants */
/* log2(exp) */
#define LOG2EXP 1.44269504088896
#define PI 3.14159265358979
/* Maximum number of iterations allowed to limit payload size */
#define MAX_PAYLOAD_LIMIT_ITERATION 5
/* Redundant Coding */
#define RCU_BOTTLENECK_BPS 16000
#define RCU_TRANSCODING_SCALE 0.40f
#define RCU_TRANSCODING_SCALE_INVERSE 2.5f
#define RCU_TRANSCODING_SCALE_UB 0.50f
#define RCU_TRANSCODING_SCALE_UB_INVERSE 2.0f
#define SIZE_RESAMPLER_STATE 6
/* Define Error codes */
/* 6000 General */
#define ISAC_MEMORY_ALLOCATION_FAILED 6010
#define ISAC_MODE_MISMATCH 6020
#define ISAC_DISALLOWED_BOTTLENECK 6030
#define ISAC_DISALLOWED_FRAME_LENGTH 6040
#define ISAC_UNSUPPORTED_SAMPLING_FREQUENCY 6050
/* 6200 Bandwidth estimator */
#define ISAC_RANGE_ERROR_BW_ESTIMATOR 6240
/* 6400 Encoder */
#define ISAC_ENCODER_NOT_INITIATED 6410
#define ISAC_DISALLOWED_CODING_MODE 6420
#define ISAC_DISALLOWED_FRAME_MODE_ENCODER 6430
#define ISAC_DISALLOWED_BITSTREAM_LENGTH 6440
#define ISAC_PAYLOAD_LARGER_THAN_LIMIT 6450
#define ISAC_DISALLOWED_ENCODER_BANDWIDTH 6460
/* 6600 Decoder */
#define ISAC_DECODER_NOT_INITIATED 6610
#define ISAC_EMPTY_PACKET 6620
#define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630
#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640
#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650
#define ISAC_RANGE_ERROR_DECODE_PITCH_GAIN 6660
#define ISAC_RANGE_ERROR_DECODE_PITCH_LAG 6670
#define ISAC_RANGE_ERROR_DECODE_LPC 6680
#define ISAC_RANGE_ERROR_DECODE_SPECTRUM 6690
#define ISAC_LENGTH_MISMATCH 6730
#define ISAC_RANGE_ERROR_DECODE_BANDWITH 6740
#define ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER 6750
#define ISAC_DISALLOWED_LPC_MODEL 6760
/* 6800 Call setup formats */
#define ISAC_INCOMPATIBLE_FORMATS 6810
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SETTINGS_H_ */

View File

@@ -0,0 +1,139 @@
/*
* 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 "spectrum_ar_model_tables.h"
#include "settings.h"
/********************* AR Coefficient Tables ************************/
/* cdf for quantized reflection coefficient 1 */
const uint16_t WebRtcIsac_kQArRc1Cdf[NUM_AR_RC_QUANT_BAUNDARY] = {
0, 2, 4, 129, 7707, 57485, 65495, 65527, 65529, 65531,
65533, 65535};
/* cdf for quantized reflection coefficient 2 */
const uint16_t WebRtcIsac_kQArRc2Cdf[NUM_AR_RC_QUANT_BAUNDARY] = {
0, 2, 4, 7, 531, 25298, 64525, 65526, 65529, 65531,
65533, 65535};
/* cdf for quantized reflection coefficient 3 */
const uint16_t WebRtcIsac_kQArRc3Cdf[NUM_AR_RC_QUANT_BAUNDARY] = {
0, 2, 4, 6, 620, 22898, 64843, 65527, 65529, 65531,
65533, 65535};
/* cdf for quantized reflection coefficient 4 */
const uint16_t WebRtcIsac_kQArRc4Cdf[NUM_AR_RC_QUANT_BAUNDARY] = {
0, 2, 4, 6, 35, 10034, 60733, 65506, 65529, 65531,
65533, 65535};
/* cdf for quantized reflection coefficient 5 */
const uint16_t WebRtcIsac_kQArRc5Cdf[NUM_AR_RC_QUANT_BAUNDARY] = {
0, 2, 4, 6, 36, 7567, 56727, 65385, 65529, 65531,
65533, 65535};
/* cdf for quantized reflection coefficient 6 */
const uint16_t WebRtcIsac_kQArRc6Cdf[NUM_AR_RC_QUANT_BAUNDARY] = {
0, 2, 4, 6, 14, 6579, 57360, 65409, 65529, 65531,
65533, 65535};
/* representation levels for quantized reflection coefficient 1 */
const int16_t WebRtcIsac_kQArRc1Levels[NUM_AR_RC_QUANT_BAUNDARY - 1] = {
-32104, -29007, -23202, -15496, -9279, -2577, 5934, 17535, 24512, 29503, 32104
};
/* representation levels for quantized reflection coefficient 2 */
const int16_t WebRtcIsac_kQArRc2Levels[NUM_AR_RC_QUANT_BAUNDARY - 1] = {
-32104, -29503, -23494, -15261, -7309, -1399, 6158, 16381, 24512, 29503, 32104
};
/* representation levels for quantized reflection coefficient 3 */
const int16_t WebRtcIsac_kQArRc3Levels[NUM_AR_RC_QUANT_BAUNDARY - 1] = {
-32104, -29503, -23157, -15186, -7347, -1359, 5829, 17535, 24512, 29503, 32104
};
/* representation levels for quantized reflection coefficient 4 */
const int16_t WebRtcIsac_kQArRc4Levels[NUM_AR_RC_QUANT_BAUNDARY - 1] = {
-32104, -29503, -24512, -15362, -6665, -342, 6596, 14585, 24512, 29503, 32104
};
/* representation levels for quantized reflection coefficient 5 */
const int16_t WebRtcIsac_kQArRc5Levels[NUM_AR_RC_QUANT_BAUNDARY - 1] = {
-32104, -29503, -24512, -15005, -6564, -106, 7123, 14920, 24512, 29503, 32104
};
/* representation levels for quantized reflection coefficient 6 */
const int16_t WebRtcIsac_kQArRc6Levels[NUM_AR_RC_QUANT_BAUNDARY - 1] = {
-32104, -29503, -24512, -15096, -6656, -37, 7036, 14847, 24512, 29503, 32104
};
/* quantization boundary levels for reflection coefficients */
const int16_t WebRtcIsac_kQArBoundaryLevels[NUM_AR_RC_QUANT_BAUNDARY] = {
-32768, -31441, -27566, -21458, -13612, -4663, 4663, 13612, 21458, 27566, 31441,
32767
};
/* initial index for AR reflection coefficient quantizer and cdf table search */
const uint16_t WebRtcIsac_kQArRcInitIndex[6] = {
5, 5, 5, 5, 5, 5};
/* pointers to AR cdf tables */
const uint16_t *WebRtcIsac_kQArRcCdfPtr[AR_ORDER] = {
WebRtcIsac_kQArRc1Cdf, WebRtcIsac_kQArRc2Cdf, WebRtcIsac_kQArRc3Cdf,
WebRtcIsac_kQArRc4Cdf, WebRtcIsac_kQArRc5Cdf, WebRtcIsac_kQArRc6Cdf
};
/* pointers to AR representation levels tables */
const int16_t *WebRtcIsac_kQArRcLevelsPtr[AR_ORDER] = {
WebRtcIsac_kQArRc1Levels, WebRtcIsac_kQArRc2Levels, WebRtcIsac_kQArRc3Levels,
WebRtcIsac_kQArRc4Levels, WebRtcIsac_kQArRc5Levels, WebRtcIsac_kQArRc6Levels
};
/******************** GAIN Coefficient Tables ***********************/
/* cdf for Gain coefficient */
const uint16_t WebRtcIsac_kQGainCdf[19] = {
0, 2, 4, 6, 8, 10, 12, 14, 16, 1172,
11119, 29411, 51699, 64445, 65527, 65529, 65531, 65533, 65535};
/* representation levels for quantized squared Gain coefficient */
const int32_t WebRtcIsac_kQGain2Levels[18] = {
// 17, 28, 46, 76, 128, 215, 364, 709, 1268, 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000};
128, 128, 128, 128, 128, 215, 364, 709, 1268, 1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000};
/* quantization boundary levels for squared Gain coefficient */
const int32_t WebRtcIsac_kQGain2BoundaryLevels[19] = {
0, 21, 35, 59, 99, 166, 280, 475, 815, 1414, 2495, 4505, 8397, 16405, 34431, 81359, 240497, 921600, 0x7FFFFFFF};
/* pointers to Gain cdf table */
const uint16_t *WebRtcIsac_kQGainCdf_ptr[1] = {WebRtcIsac_kQGainCdf};
/* Gain initial index for gain quantizer and cdf table search */
const uint16_t WebRtcIsac_kQGainInitIndex[1] = {11};
/************************* Cosine Tables ****************************/
/* Cosine table */
const int16_t WebRtcIsac_kCos[6][60] = {
{512, 512, 511, 510, 508, 507, 505, 502, 499, 496, 493, 489, 485, 480, 476, 470, 465, 459, 453, 447,
440, 433, 426, 418, 410, 402, 394, 385, 376, 367, 357, 348, 338, 327, 317, 306, 295, 284, 273, 262,
250, 238, 226, 214, 202, 190, 177, 165, 152, 139, 126, 113, 100, 87, 73, 60, 47, 33, 20, 7},
{512, 510, 508, 503, 498, 491, 483, 473, 462, 450, 437, 422, 406, 389, 371, 352, 333, 312, 290, 268,
244, 220, 196, 171, 145, 120, 93, 67, 40, 13, -13, -40, -67, -93, -120, -145, -171, -196, -220, -244,
-268, -290, -312, -333, -352, -371, -389, -406, -422, -437, -450, -462, -473, -483, -491, -498, -503, -508, -510, -512},
{512, 508, 502, 493, 480, 465, 447, 426, 402, 376, 348, 317, 284, 250, 214, 177, 139, 100, 60, 20,
-20, -60, -100, -139, -177, -214, -250, -284, -317, -348, -376, -402, -426, -447, -465, -480, -493, -502, -508, -512,
-512, -508, -502, -493, -480, -465, -447, -426, -402, -376, -348, -317, -284, -250, -214, -177, -139, -100, -60, -20},
{511, 506, 495, 478, 456, 429, 398, 362, 322, 279, 232, 183, 133, 80, 27, -27, -80, -133, -183, -232,
-279, -322, -362, -398, -429, -456, -478, -495, -506, -511, -511, -506, -495, -478, -456, -429, -398, -362, -322, -279,
-232, -183, -133, -80, -27, 27, 80, 133, 183, 232, 279, 322, 362, 398, 429, 456, 478, 495, 506, 511},
{511, 502, 485, 459, 426, 385, 338, 284, 226, 165, 100, 33, -33, -100, -165, -226, -284, -338, -385, -426,
-459, -485, -502, -511, -511, -502, -485, -459, -426, -385, -338, -284, -226, -165, -100, -33, 33, 100, 165, 226,
284, 338, 385, 426, 459, 485, 502, 511, 511, 502, 485, 459, 426, 385, 338, 284, 226, 165, 100, 33},
{510, 498, 473, 437, 389, 333, 268, 196, 120, 40, -40, -120, -196, -268, -333, -389, -437, -473, -498, -510,
-510, -498, -473, -437, -389, -333, -268, -196, -120, -40, 40, 120, 196, 268, 333, 389, 437, 473, 498, 510,
510, 498, 473, 437, 389, 333, 268, 196, 120, 40, -40, -120, -196, -268, -333, -389, -437, -473, -498, -510}
};

View File

@@ -0,0 +1,78 @@
/*
* 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.
*/
/*
* spectrum_ar_model_tables.h
*
* This file contains definitions of tables with AR coefficients,
* Gain coefficients and cosine tables.
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
#include "structs.h"
#define NUM_AR_RC_QUANT_BAUNDARY 12
/********************* AR Coefficient Tables ************************/
/* cdf for quantized reflection coefficient 1 */
extern const uint16_t WebRtcIsac_kQArRc1Cdf[NUM_AR_RC_QUANT_BAUNDARY];
/* cdf for quantized reflection coefficient 2 */
extern const uint16_t WebRtcIsac_kQArRc2Cdf[NUM_AR_RC_QUANT_BAUNDARY];
/* cdf for quantized reflection coefficient 3 */
extern const uint16_t WebRtcIsac_kQArRc3Cdf[NUM_AR_RC_QUANT_BAUNDARY];
/* cdf for quantized reflection coefficient 4 */
extern const uint16_t WebRtcIsac_kQArRc4Cdf[NUM_AR_RC_QUANT_BAUNDARY];
/* cdf for quantized reflection coefficient 5 */
extern const uint16_t WebRtcIsac_kQArRc5Cdf[NUM_AR_RC_QUANT_BAUNDARY];
/* cdf for quantized reflection coefficient 6 */
extern const uint16_t WebRtcIsac_kQArRc6Cdf[NUM_AR_RC_QUANT_BAUNDARY];
/* quantization boundary levels for reflection coefficients */
extern const int16_t WebRtcIsac_kQArBoundaryLevels[NUM_AR_RC_QUANT_BAUNDARY];
/* initial indices for AR reflection coefficient quantizer and cdf table search */
extern const uint16_t WebRtcIsac_kQArRcInitIndex[AR_ORDER];
/* pointers to AR cdf tables */
extern const uint16_t *WebRtcIsac_kQArRcCdfPtr[AR_ORDER];
/* pointers to AR representation levels tables */
extern const int16_t *WebRtcIsac_kQArRcLevelsPtr[AR_ORDER];
/******************** GAIN Coefficient Tables ***********************/
/* cdf for Gain coefficient */
extern const uint16_t WebRtcIsac_kQGainCdf[19];
/* representation levels for quantized Gain coefficient */
extern const int32_t WebRtcIsac_kQGain2Levels[18];
/* squared quantization boundary levels for Gain coefficient */
extern const int32_t WebRtcIsac_kQGain2BoundaryLevels[19];
/* pointer to Gain cdf table */
extern const uint16_t *WebRtcIsac_kQGainCdf_ptr[1];
/* Gain initial index for gain quantizer and cdf table search */
extern const uint16_t WebRtcIsac_kQGainInitIndex[1];
/************************* Cosine Tables ****************************/
/* Cosine table */
extern const int16_t WebRtcIsac_kCos[6][60];
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ */

View File

@@ -0,0 +1,482 @@
/*
* Copyright (c) 2012 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.
*/
/*
* structs.h
*
* This header file contains all the structs used in the ISAC codec
*
*/
#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_
#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/source/settings.h"
#include "webrtc/typedefs.h"
typedef struct Bitstreamstruct {
uint8_t stream[STREAM_SIZE_MAX];
uint32_t W_upper;
uint32_t streamval;
uint32_t stream_index;
} Bitstr;
typedef struct {
double DataBufferLo[WINLEN];
double DataBufferHi[WINLEN];
double CorrBufLo[ORDERLO+1];
double CorrBufHi[ORDERHI+1];
float PreStateLoF[ORDERLO+1];
float PreStateLoG[ORDERLO+1];
float PreStateHiF[ORDERHI+1];
float PreStateHiG[ORDERHI+1];
float PostStateLoF[ORDERLO+1];
float PostStateLoG[ORDERLO+1];
float PostStateHiF[ORDERHI+1];
float PostStateHiG[ORDERHI+1];
double OldEnergy;
} MaskFiltstr;
typedef struct {
//state vectors for each of the two analysis filters
double INSTAT1[2*(QORDER-1)];
double INSTAT2[2*(QORDER-1)];
double INSTATLA1[2*(QORDER-1)];
double INSTATLA2[2*(QORDER-1)];
double INLABUF1[QLOOKAHEAD];
double INLABUF2[QLOOKAHEAD];
float INSTAT1_float[2*(QORDER-1)];
float INSTAT2_float[2*(QORDER-1)];
float INSTATLA1_float[2*(QORDER-1)];
float INSTATLA2_float[2*(QORDER-1)];
float INLABUF1_float[QLOOKAHEAD];
float INLABUF2_float[QLOOKAHEAD];
/* High pass filter */
double HPstates[HPORDER];
float HPstates_float[HPORDER];
} PreFiltBankstr;
typedef struct {
//state vectors for each of the two analysis filters
double STATE_0_LOWER[2*POSTQORDER];
double STATE_0_UPPER[2*POSTQORDER];
/* High pass filter */
double HPstates1[HPORDER];
double HPstates2[HPORDER];
float STATE_0_LOWER_float[2*POSTQORDER];
float STATE_0_UPPER_float[2*POSTQORDER];
float HPstates1_float[HPORDER];
float HPstates2_float[HPORDER];
} PostFiltBankstr;
typedef struct {
//data buffer for pitch filter
double ubuf[PITCH_BUFFSIZE];
//low pass state vector
double ystate[PITCH_DAMPORDER];
//old lag and gain
double oldlagp[1];
double oldgainp[1];
} PitchFiltstr;
typedef struct {
//data buffer
double buffer[PITCH_WLPCBUFLEN];
//state vectors
double istate[PITCH_WLPCORDER];
double weostate[PITCH_WLPCORDER];
double whostate[PITCH_WLPCORDER];
//LPC window -> should be a global array because constant
double window[PITCH_WLPCWINLEN];
} WeightFiltstr;
typedef struct {
//for inital estimator
double dec_buffer[PITCH_CORR_LEN2 + PITCH_CORR_STEP2 +
PITCH_MAX_LAG/2 - PITCH_FRAME_LEN/2+2];
double decimator_state[2*ALLPASSSECTIONS+1];
double hp_state[2];
double whitened_buf[QLOOKAHEAD];
double inbuf[QLOOKAHEAD];
PitchFiltstr PFstr_wght;
PitchFiltstr PFstr;
WeightFiltstr Wghtstr;
} PitchAnalysisStruct;
/* Have instance of struct together with other iSAC structs */
typedef struct {
/* Previous frame length (in ms) */
int32_t prev_frame_length;
/* Previous RTP timestamp from received
packet (in samples relative beginning) */
int32_t prev_rec_rtp_number;
/* Send timestamp for previous packet (in ms using timeGetTime()) */
uint32_t prev_rec_send_ts;
/* Arrival time for previous packet (in ms using timeGetTime()) */
uint32_t prev_rec_arr_ts;
/* rate of previous packet, derived from RTP timestamps (in bits/s) */
float prev_rec_rtp_rate;
/* Time sinse the last update of the BN estimate (in ms) */
uint32_t last_update_ts;
/* Time sinse the last reduction (in ms) */
uint32_t last_reduction_ts;
/* How many times the estimate was update in the beginning */
int32_t count_tot_updates_rec;
/* The estimated bottle neck rate from there to here (in bits/s) */
int32_t rec_bw;
float rec_bw_inv;
float rec_bw_avg;
float rec_bw_avg_Q;
/* The estimated mean absolute jitter value,
as seen on this side (in ms) */
float rec_jitter;
float rec_jitter_short_term;
float rec_jitter_short_term_abs;
float rec_max_delay;
float rec_max_delay_avg_Q;
/* (assumed) bitrate for headers (bps) */
float rec_header_rate;
/* The estimated bottle neck rate from here to there (in bits/s) */
float send_bw_avg;
/* The estimated mean absolute jitter value, as seen on
the other siee (in ms) */
float send_max_delay_avg;
// number of packets received since last update
int num_pkts_rec;
int num_consec_rec_pkts_over_30k;
// flag for marking that a high speed network has been
// detected downstream
int hsn_detect_rec;
int num_consec_snt_pkts_over_30k;
// flag for marking that a high speed network has
// been detected upstream
int hsn_detect_snd;
uint32_t start_wait_period;
int in_wait_period;
int change_to_WB;
uint32_t senderTimestamp;
uint32_t receiverTimestamp;
//enum IsacSamplingRate incomingStreamSampFreq;
uint16_t numConsecLatePkts;
float consecLatency;
int16_t inWaitLatePkts;
} BwEstimatorstr;
typedef struct {
/* boolean, flags if previous packet exceeded B.N. */
int PrevExceed;
/* ms */
int ExceedAgo;
/* packets left to send in current burst */
int BurstCounter;
/* packets */
int InitCounter;
/* ms remaining in buffer when next packet will be sent */
double StillBuffered;
} RateModel;
typedef struct {
unsigned int SpaceAlloced;
unsigned int MaxPermAlloced;
double Tmp0[MAXFFTSIZE];
double Tmp1[MAXFFTSIZE];
double Tmp2[MAXFFTSIZE];
double Tmp3[MAXFFTSIZE];
int Perm[MAXFFTSIZE];
int factor [NFACTOR];
} FFTstr;
/* The following strutc is used to store data from encoding, to make it
fast and easy to construct a new bitstream with a different Bandwidth
estimate. All values (except framelength and minBytes) is double size to
handle 60 ms of data.
*/
typedef struct {
/* Used to keep track of if it is first or second part of 60 msec packet */
int startIdx;
/* Frame length in samples */
int16_t framelength;
/* Pitch Gain */
int pitchGain_index[2];
/* Pitch Lag */
double meanGain[2];
int pitchIndex[PITCH_SUBFRAMES*2];
/* LPC */
int LPCindex_s[108*2]; /* KLT_ORDER_SHAPE = 108 */
int LPCindex_g[12*2]; /* KLT_ORDER_GAIN = 12 */
double LPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*2];
double LPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*2];
/* Encode Spec */
int16_t fre[FRAMESAMPLES];
int16_t fim[FRAMESAMPLES];
int16_t AvgPitchGain[2];
/* Used in adaptive mode only */
int minBytes;
} ISAC_SaveEncData_t;
typedef struct {
int indexLPCShape[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
double lpcGain[SUBFRAMES<<1];
int lpcGainIndex[SUBFRAMES<<1];
Bitstr bitStreamObj;
int16_t realFFT[FRAMESAMPLES_HALF];
int16_t imagFFT[FRAMESAMPLES_HALF];
} ISACUBSaveEncDataStruct;
typedef struct {
Bitstr bitstr_obj;
MaskFiltstr maskfiltstr_obj;
PreFiltBankstr prefiltbankstr_obj;
PitchFiltstr pitchfiltstr_obj;
PitchAnalysisStruct pitchanalysisstr_obj;
FFTstr fftstr_obj;
ISAC_SaveEncData_t SaveEnc_obj;
int buffer_index;
int16_t current_framesamples;
float data_buffer_float[FRAMESAMPLES_30ms];
int frame_nb;
double bottleneck;
int16_t new_framelength;
double s2nr;
/* Maximum allowed number of bits for a 30 msec packet */
int16_t payloadLimitBytes30;
/* Maximum allowed number of bits for a 30 msec packet */
int16_t payloadLimitBytes60;
/* Maximum allowed number of bits for both 30 and 60 msec packet */
int16_t maxPayloadBytes;
/* Maximum allowed rate in bytes per 30 msec packet */
int16_t maxRateInBytes;
/*---
If set to 1 iSAC will not addapt the frame-size, if used in
channel-adaptive mode. The initial value will be used for all rates.
---*/
int16_t enforceFrameSize;
/*-----
This records the BWE index the encoder injected into the bit-stream.
It will be used in RCU. The same BWE index of main payload will be in
the redundant payload. We can not retrive it from BWE because it is
a recursive procedure (WebRtcIsac_GetDownlinkBwJitIndexImpl) and has to be
called only once per each encode.
-----*/
int16_t lastBWIdx;
} ISACLBEncStruct;
typedef struct {
Bitstr bitstr_obj;
MaskFiltstr maskfiltstr_obj;
PreFiltBankstr prefiltbankstr_obj;
FFTstr fftstr_obj;
ISACUBSaveEncDataStruct SaveEnc_obj;
int buffer_index;
float data_buffer_float[MAX_FRAMESAMPLES +
LB_TOTAL_DELAY_SAMPLES];
double bottleneck;
/* Maximum allowed number of bits for a 30 msec packet */
//int16_t payloadLimitBytes30;
/* Maximum allowed number of bits for both 30 and 60 msec packet */
//int16_t maxPayloadBytes;
int16_t maxPayloadSizeBytes;
double lastLPCVec[UB_LPC_ORDER];
int16_t numBytesUsed;
int16_t lastJitterInfo;
} ISACUBEncStruct;
typedef struct {
Bitstr bitstr_obj;
MaskFiltstr maskfiltstr_obj;
PostFiltBankstr postfiltbankstr_obj;
PitchFiltstr pitchfiltstr_obj;
FFTstr fftstr_obj;
} ISACLBDecStruct;
typedef struct {
Bitstr bitstr_obj;
MaskFiltstr maskfiltstr_obj;
PostFiltBankstr postfiltbankstr_obj;
FFTstr fftstr_obj;
} ISACUBDecStruct;
typedef struct {
ISACLBEncStruct ISACencLB_obj;
ISACLBDecStruct ISACdecLB_obj;
} ISACLBStruct;
typedef struct {
ISACUBEncStruct ISACencUB_obj;
ISACUBDecStruct ISACdecUB_obj;
} ISACUBStruct;
/*
This struct is used to take a snapshot of the entropy coder and LPC gains
right before encoding LPC gains. This allows us to go back to that state
if we like to limit the payload size.
*/
typedef struct {
/* 6 lower-band & 6 upper-band */
double loFiltGain[SUBFRAMES];
double hiFiltGain[SUBFRAMES];
/* Upper boundary of interval W */
uint32_t W_upper;
uint32_t streamval;
/* Index to the current position in bytestream */
uint32_t stream_index;
uint8_t stream[3];
} transcode_obj;
typedef struct {
// lower-band codec instance
ISACLBStruct instLB;
// upper-band codec instance
ISACUBStruct instUB;
// Bandwidth Estimator and model for the rate.
BwEstimatorstr bwestimator_obj;
RateModel rate_data_obj;
double MaxDelay;
/* 0 = adaptive; 1 = instantaneous */
int16_t codingMode;
// overall bottleneck of the codec
int32_t bottleneck;
// QMF Filter state
int32_t analysisFBState1[FB_STATE_SIZE_WORD32];
int32_t analysisFBState2[FB_STATE_SIZE_WORD32];
int32_t synthesisFBState1[FB_STATE_SIZE_WORD32];
int32_t synthesisFBState2[FB_STATE_SIZE_WORD32];
// Error Code
int16_t errorCode;
// bandwidth of the encoded audio 8, 12 or 16 kHz
enum ISACBandwidth bandwidthKHz;
// Sampling rate of audio, encoder and decode, 8 or 16 kHz
enum IsacSamplingRate encoderSamplingRateKHz;
enum IsacSamplingRate decoderSamplingRateKHz;
// Flag to keep track of initializations, lower & upper-band
// encoder and decoder.
int16_t initFlag;
// Flag to to indicate signal bandwidth switch
int16_t resetFlag_8kHz;
// Maximum allowed rate, measured in Bytes per 30 ms.
int16_t maxRateBytesPer30Ms;
// Maximum allowed payload-size, measured in Bytes.
int16_t maxPayloadSizeBytes;
/* The expected sampling rate of the input signal. Valid values are 16000,
* 32000 and 48000. This is not the operation sampling rate of the codec.
* Input signals at 48 kHz are resampled to 32 kHz, then encoded. */
uint16_t in_sample_rate_hz;
/* State for the input-resampler. It is only used for 48 kHz input signals. */
int16_t state_in_resampler[SIZE_RESAMPLER_STATE];
} ISACMainStruct;
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ */

View File

@@ -0,0 +1,131 @@
/*
* 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 "os_specific_inline.h"
#include <math.h>
static double costab1[FRAMESAMPLES_HALF];
static double sintab1[FRAMESAMPLES_HALF];
static double costab2[FRAMESAMPLES_QUARTER];
static double sintab2[FRAMESAMPLES_QUARTER];
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,
int16_t *outreQ7,
int16_t *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] = (int16_t)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
outimQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
outreQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
outimQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)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;
}
}