www.pudn.com > av3dec_20050318.zip > sam_decoder.c
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2004, Audio Video Coding Standard, Part III
*
* This software module was originally developed by
*
* JungHoe Kim (kjh94@samsung.com), Samsung AIT
*
* edited by
*
* Lei Miao (win.miaolei@samsung.com), Samsung AIT
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/
#include
#include "sam_cbc_dec.h"
#include "sam_scf_band.h"
#define SF_OFFSET 100
#define TEXP 128
#define MAX_IQ_TBL 128
static int av3BandL[60]; /*max : 51*/
static int av3BandS[20]; /*max : 15*/
static int nsfb1024;
static int nsfb128;
Float calc_scale(int fac);
Float iquant_exp(int q);
static Float exptable[TEXP];
static Float iq_exp_tbl[MAX_IQ_TBL];
int init_cbc(int fsidx)
{
int i;
for (i = 0; i < TEXP; i++)
exptable[i] = pow(2.0, 1./4.*i);
for (i = 0; i < MAX_IQ_TBL; i++)
iq_exp_tbl[i] = pow(i, 4./3.);
/* for long */
nsfb1024 = samp_rate_info[fsidx].nsfb1024;
av3BandL[0] = 0;
for (i = 0; i < nsfb1024; i++)
av3BandL[i+1] = samp_rate_info[fsidx].SFbands1024[i];
/* for short */
nsfb128 = samp_rate_info[fsidx].nsfb128;
av3BandS[0] = 0;
for (i = 0; i < nsfb128; i++)
av3BandS[i+1] = samp_rate_info[fsidx].SFbands128[i];
cbc_decode_init(fsidx);
BSHCDecInit();
return samp_rate_info[fsidx].samp_rate;
}
void decodeCBC(
int target,
int stereo_mode,
int windowSequence[],
int num_window_groups,
int window_group_length[],
int scalefactors[][8][MAX_SCFAC_BANDS],
int samples[][FRAMESIZE],
int maxSfb[],
int ps_mask[],
int ubits,
int frameSize,
int enc_top_layer,
int base_snf,
int base_band,
int nch,
int fill_length)
{
int i, w;
int swb_offset[8][52];
int sppl[2][FRAMESIZE];
target -= 16;
if (target > enc_top_layer)
target = enc_top_layer;
if (windowSequence[0] == SHORT_WINDOW) {
for (w = 0; w < num_window_groups; w++) {
swb_offset[w][0] = 0;
for (i = 0; i < nsfb128; i++)
swb_offset[w][i+1] = av3BandS[i+1] * window_group_length[w];
}
}
else {
for (i = 0; i < nsfb1024+1; i++)
swb_offset[0][i] = av3BandL[i];
}
cbc_decode(windowSequence[0], target, sppl, scalefactors, maxSfb[0], num_window_groups,
window_group_length, ps_mask, stereo_mode, swb_offset, ubits, frameSize,
enc_top_layer, base_snf, base_band, nch, fill_length);
/* Deinterleaving quantized spectral data for short window*/
if (windowSequence[0] == SHORT_WINDOW) {
int offset, b, s, k;
s = 0;
for (w = 0; w < num_window_groups; w++) {
for (i = 0; i < 128; i += 4) {
offset = (128 * s) + (i * window_group_length[w]);
for (k = 0; k < 4; k++)
for (b = 0 ; b < window_group_length[w]; b++) {
samples[0][128*(b+s)+i+k] = sppl[0][offset+4*b+k];
samples[1][128*(b+s)+i+k] = sppl[1][offset+4*b+k];
}
}
s += window_group_length[w];
}
}
else {
for (i = 0; i < FRAMESIZE; i++) {
samples[0][i] = sppl[0][i];
samples[1][i] = sppl[1][i];
}
}
}
void dequantization(int target,
int windowSequence,
int scalefactors[][MAX_SCFAC_BANDS],
int num_window_groups,
int window_group_length[],
int samples[],
int maxSfb,
Float spectrums[],
int ch)
{
int sfb, i;
Float scale;
target = (target - 16);
for(i = 0; i < FRAMESIZE; i++)
spectrums[i] = -0.0;
if(windowSequence != SHORT_WINDOW) {
for(sfb = 0; sfb < maxSfb; sfb++) {
scale = calc_scale(scalefactors[0][sfb]-SF_OFFSET);
for(i = av3BandL[sfb]; i < av3BandL[sfb+1]; i++) {
spectrums[i] = iquant_exp(samples[i]) * scale;
}
}
}
else
{
int w, b, s, k;
int spl;
s = 0;
for(w = 0; w < num_window_groups; w++) {
for(sfb = 0; sfb < maxSfb; sfb++) {
scale = calc_scale(scalefactors[w][sfb]-SF_OFFSET);
for(b = 0 ; b < window_group_length[w]; b++) {
k = (s + b) * 128;
for(i = av3BandS[sfb]; i < av3BandS[sfb+1]; i++) {
spl = samples[k+i];
spectrums[k+i] = iquant_exp(spl) * scale;
}
}
}
s += window_group_length[w];
}
}
}
/* bypass stereo decoding, just get swb_offset info
from its 'samp_rate_info' in "sam_cbc_band.h" */
void cbc_swboffset_for_polarstereo(int* swb_offset_long,
int* swb_offset_short,
int fsidx)
{
int i;
/* for long */
swb_offset_long[0] = 0;
for (i = 0; i < samp_rate_info[fsidx].nsfb1024; i++)
swb_offset_long[i+1] = samp_rate_info[fsidx].SFbands1024[i];
/* for short */
swb_offset_short[0] = 0;
for (i = 0; i < samp_rate_info[fsidx].nsfb128; i++)
swb_offset_short[i+1] = samp_rate_info[fsidx].SFbands128[i];
}
Float calc_scale(int fac)
{
Float scale;
if(fac >= 0 && fac < TEXP) {
scale = exptable[fac];
} else {
if(fac == -SF_OFFSET)
scale = 0.;
else
scale = pow((double)2.0, (double)(0.25*fac));
}
return scale;
}
Float iquant_exp(int q)
{
Float return_value;
if (q > 0) {
if (q < MAX_IQ_TBL) {
return((Float)iq_exp_tbl[q]);
}
else {
return_value = (Float)(pow((double)q, (double)(4./3.)));
}
}
else {
q = -q;
if (q < MAX_IQ_TBL) {
return((Float)(-iq_exp_tbl[q]));
}
else {
return_value = (Float)(-pow((double)q, (double)(4./3.)));
}
}
return return_value;
}