141 lines
5.4 KiB
C
Executable file
141 lines
5.4 KiB
C
Executable file
/*--------------------------------------------------------------------------*/
|
|
/* ITU-T G.722.1 Fullband Extension Annex X. Source Code */
|
|
/* © 2008 Ericsson AB. and Polycom Inc. */
|
|
/* All rights reserved. */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
#include "cnst.h"
|
|
#include "rom.h"
|
|
#include "proto.h"
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function itda */
|
|
/* ~~~~~~~~~~~~~~ */
|
|
/* */
|
|
/* Inverse time domain aliasing */
|
|
/*--------------------------------------------------------------------------*/
|
|
/* float *in (i) input vector */
|
|
/* float *out (o) output vector */
|
|
/*--------------------------------------------------------------------------*/
|
|
void itda(float *in, float *out)
|
|
{
|
|
short i;
|
|
|
|
for (i = 0; i < MLT960_LENGTH_DIV_2; i++)
|
|
{
|
|
out[i] = in[MLT960_LENGTH_DIV_2 + i];
|
|
out[MLT960_LENGTH_DIV_2 + i] = -in[MLT960_LENGTH - 1 - i];
|
|
out[MLT960_LENGTH + i] = -in[MLT960_LENGTH_DIV_2 - 1 - i];
|
|
out[3*MLT960_LENGTH_DIV_2 + i] = -in[i];
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function imdct_short */
|
|
/* ~~~~~~~~~~~~~~~~~~~~~ */
|
|
/* */
|
|
/* Inverse MDCT for short frames */
|
|
/*--------------------------------------------------------------------------*/
|
|
/* float *in (i) input vector */
|
|
/* float *out (o) output vector */
|
|
/*--------------------------------------------------------------------------*/
|
|
void imdct_short(float *in, float *out)
|
|
{
|
|
float alias[MAX_SEGMENT_LENGTH];
|
|
short i;
|
|
|
|
dct4_240(in, alias);
|
|
|
|
for (i = 0; i < MAX_SEGMENT_LENGTH/4; i++)
|
|
{
|
|
out[i] = alias[MAX_SEGMENT_LENGTH/4 + i];
|
|
out[MAX_SEGMENT_LENGTH/4 + i] = -alias[MAX_SEGMENT_LENGTH/2 - 1 - i];
|
|
out[MAX_SEGMENT_LENGTH/2 + i] = -alias[MAX_SEGMENT_LENGTH/4 - 1 - i];
|
|
out[3*MAX_SEGMENT_LENGTH/4 + i] = -alias[i];
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function inverse_transform */
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
|
/* */
|
|
/* Inverse transform from the DCT domain to time domain */
|
|
/*--------------------------------------------------------------------------*/
|
|
/* float *in_mdct (i) input MDCT vector */
|
|
/* float *out (o) output vector */
|
|
/* int *is_transient (o) transient flag */
|
|
/*--------------------------------------------------------------------------*/
|
|
void inverse_transform(float *in_mdct, float *out, int is_transient)
|
|
{
|
|
float out_alias[FRAME_LENGTH];
|
|
float alias[MAX_SEGMENT_LENGTH];
|
|
float *in_segment;
|
|
float *out_segment;
|
|
float tmp;
|
|
|
|
short ta, seg;
|
|
|
|
if (is_transient)
|
|
{
|
|
for (ta = 0; ta < FRAME_LENGTH; ta++)
|
|
{
|
|
out_alias[ta] = 0.0f;
|
|
}
|
|
|
|
out_segment = out_alias - MAX_SEGMENT_LENGTH / 4;
|
|
in_segment = in_mdct + 0;
|
|
|
|
imdct_short(in_segment, alias);
|
|
|
|
for (ta = MAX_SEGMENT_LENGTH /4; ta < MAX_SEGMENT_LENGTH /2; ta++)
|
|
{
|
|
out_segment[ta] = alias[ta];
|
|
}
|
|
|
|
for (ta = MAX_SEGMENT_LENGTH /2; ta < MAX_SEGMENT_LENGTH; ta++)
|
|
{
|
|
out_segment[ta] = alias[ta]*short_window[ta];
|
|
}
|
|
|
|
out_segment = out_segment + MAX_SEGMENT_LENGTH/2;
|
|
in_segment = in_segment + MAX_SEGMENT_LENGTH/2;
|
|
|
|
for (seg = 1 ; seg < NUM_TIME_SWITCHING_BLOCKS-1; seg++)
|
|
{
|
|
imdct_short(in_segment, alias);
|
|
|
|
for (ta = 0; ta < MAX_SEGMENT_LENGTH; ta++)
|
|
{
|
|
out_segment[ta] = out_segment[ta] + alias[ta] * short_window[ta];
|
|
}
|
|
|
|
in_segment = in_segment + MAX_SEGMENT_LENGTH/2;
|
|
out_segment = out_segment + MAX_SEGMENT_LENGTH/2;
|
|
}
|
|
|
|
imdct_short(in_segment, alias);
|
|
|
|
for (ta = 0; ta < MAX_SEGMENT_LENGTH /2; ta++)
|
|
{
|
|
out_segment[ta] = out_segment[ta] + alias[ta] * short_window[ta];
|
|
}
|
|
|
|
for (ta = MAX_SEGMENT_LENGTH /2; ta < MAX_SEGMENT_LENGTH /4+MAX_SEGMENT_LENGTH /2; ta++)
|
|
{
|
|
out_segment[ta] = alias[ta];
|
|
}
|
|
|
|
for (ta = 0; ta < FRAME_LENGTH/2; ta++)
|
|
{
|
|
tmp = out_alias[ta];
|
|
out_alias[ta] = out_alias[FRAME_LENGTH-1-ta];
|
|
out_alias[FRAME_LENGTH-1-ta] = tmp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dct4_960(in_mdct, out_alias);
|
|
}
|
|
|
|
itda(out_alias, out);
|
|
}
|