www.pudn.com > AVS_M_ver10.rar > d_stereo_x.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2007 Audio Video Coding Standard, Part ¢ú * * This software module was developed by AVS Audio sub-group * * 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 #include #include #include "../include/amr_plus.h" #include "../include/cod_hi_stereo.h" #include "../include/cod_tcx_stereo.h" #include "../include/s_util.h" /*-----------------------------------------------------------------* * Funtion init_decoder_stereo * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * ->Initialization of variables for the stereo decoder. * *-----------------------------------------------------------------*/ void init_decoder_stereo_x(Decoder_State_Plus *st) { /* Allocate memory for stereo states */ set_zero(st->my_old_synth_2k,L_FDEL_2k + D_STEREO_TCX + 2*(D_NC*5)/32); set_zero(st->my_old_synth_hi,2*D_NC); set_zero(st->my_old_synth,2*L_FDEL+20); set_zero(st->mem_left_2k,2*L_FDEL_2k); set_zero(st->mem_right_2k,2*L_FDEL_2k); set_zero(st->mem_left_hi,L_FDEL); set_zero(st->mem_right_hi,L_FDEL); set_zero(st->left.mem_d_tcx,D_NC + (D_STEREO_TCX*32/5)); set_zero(st->right.mem_d_tcx,D_NC + (D_STEREO_TCX*32/5)); init_dec_hi_stereo(st); set_zero(st->right.mem_d_nonc,D_NC); set_zero(st->left.mem_d_nonc,D_NC); init_tcx_stereo_decoder(st); st->last_stereo_mode =0; st->side_rms = 0.0; return; } /*-----------------------------------------------------------------* * Funtion decoder_stereo * * ~~~~~~~~~~~~~~~~~~~~~~ * * ->Principle stereo decoder routine (working at fs=12.8kHz). * * * * Note: HF band are encoded twice (2 channels) using 0.8kbps BWE. * * Usage of 2xBWE for stereo provide better time domain * * stereo definition in HF without increasing the bit-rate. * * Another advantage is that the stereo decoder is limited * * to the lower band (fs=12.8kHz) and this reduce the * * overall complexity of the AMR-WB+ codec. Also, this * * solution is not dependent of the AMR-WB+ mode where many * * different sampling frequencies are used (16, 24, 32 kHz). * *-----------------------------------------------------------------*/ #define DELAY_MAX_2 (D_NC+(D_STEREO_TCX*32/5)) static void delay(float signal[], int lg, int delay, float mem[]) { int i; float buf[DELAY_MAX_2]; for (i=0; i =delay; i--) { signal[i] = signal[i-delay]; } for (i=0; i my_old_synth,my_synth_buf,2*L_FDEL+20); mvr2r(synth,my_new_synth+20,L_FRAME_PLUS); mvr2r(st->my_old_synth_2k,my_old_synth_2k, D_STEREO_TCX + L_FDEL_2k + 2*(D_NC*5)/32); mvr2r(st->my_old_synth_hi,my_old_synth_hi,2*D_NC); mvr2r(st->mem_left_2k,old_left_2k,2*L_FDEL_2k); mvr2r(st->mem_right_2k,old_right_2k,2*L_FDEL_2k); /* mono synth band-split*/ /* do the lo,hi band-splitting on the mono signal */ band_split_taligned_2k(my_new_synth,my_new_synth_2k,my_new_synth_hi,L_FRAME_PLUS); /* Low band */ if (StbrMode < 0) { int i; for (i=0; i mem_stereo_ovlp[i]; new_right_2k[i] = my_old_synth_2k[i] - st->mem_stereo_ovlp[i]; } for (i=L_OVLP_2k; i mem_stereo_ovlp_size = L_OVLP_2k; st->last_stereo_mode = 0; st->side_rms = 0.0; } else dec_tcx_stereo(my_old_synth_2k,new_left_2k,new_right_2k,param+NPRM_STEREO_HI_X*NB_DIV,bad_frame,st); /* High band */ { float old_right_hi[L_FRAME_PLUS+L_FDEL+HI_FILT_ORDER]; float *new_right_hi = old_right_hi + L_FDEL; float old_left_hi[L_FRAME_PLUS+L_FDEL]; float *new_left_hi = old_left_hi + L_FDEL; if (StereoNbits[StbrMode]-4 > 300) { st->filt_hi_pmsvq = &filt_hi_pmsvq7; st->gain_hi_pmsvq = &gain_hi_pmsvq5; } else { st->filt_hi_pmsvq = &filt_hi_pmsvq4; st->gain_hi_pmsvq = &gain_hi_pmsvq2; } mvr2r(st->mem_left_hi,old_left_hi,L_FDEL); mvr2r(st->mem_right_hi,old_right_hi,L_FDEL); /* decode the high band */ if (StbrMode < 0) { int i; for (i=0; i right.mem_d_nonc); delay(new_left_hi,L_FRAME_PLUS,D_NC,st->left.mem_d_nonc); /*left_hi and right_hi are time aligned here */ /* synthesis is delayed, so delay the left_hi and right_hi */ delay(new_right_hi,L_FRAME_PLUS,D_NC+(D_STEREO_TCX*32/5),st->right.mem_d_tcx); delay(new_left_hi,L_FRAME_PLUS,D_NC+(D_STEREO_TCX*32/5),st->left.mem_d_tcx); /* the whole stereo is delayed by D_STEREO_TCX */ /* Join low and high frequency band*/ /* Left channel */ mvr2r(&my_synth_buf[L_FRAME_PLUS],st->my_old_synth,2*L_FDEL+20); band_join_2k(sig_left,new_left_2k, new_left_hi, L_FRAME_PLUS); /* Right channel */ mvr2r(&my_old_synth_hi[L_FRAME_PLUS],st->my_old_synth_hi,2*D_NC); band_join_2k(synth,new_right_2k, new_right_hi,L_FRAME_PLUS); mvr2r(&old_left_hi[L_FRAME_PLUS],st->mem_left_hi,L_FDEL); mvr2r(&old_right_hi[L_FRAME_PLUS],st->mem_right_hi,L_FDEL); } /* Update buffers*/ mvr2r(&my_old_synth_2k[L_FRAME_2k],st->my_old_synth_2k,L_FDEL_2k + D_STEREO_TCX+2*(D_NC*5)/32); mvr2r(&old_left_2k[L_FRAME_2k],st->mem_left_2k,2*L_FDEL_2k); mvr2r(&old_right_2k[L_FRAME_2k],st->mem_right_2k,2*L_FDEL_2k); return; } static int pack4bits_d(int nbits, short *ptr, int *prm) { int i; i=0; while (nbits > 4) { prm[i] = bin2int(4, ptr); ptr += 4; nbits -= 4; i++; } prm[i] = bin2int(nbits, ptr); i++; return(i); } void dec_prm_stereo_x(int bad_frame[], /* (i) : bfi for 4 frames (bad_frame[4]) */ short serial[], /* (i) : serial bits stream */ int nbits_pack, /* (i) : number of bits per packet of 20ms*/ int nbits_bwe, /* (i) : number of BWE bits per 20ms */ int param[], /* (o) : decoded parameters */ int brMode, Decoder_State_Plus* st) { int nbits, *prm; int k,mod_buf[1+NB_DIV]; int *mod; int nbits_AVQ[NB_DIV]; int prm_AVQ[NBITS_MAX+N_PACK_MAX]; short *ptr; float tmp_prm[NBITS_MAX+N_PACK_MAX]; int i,j,n_pack; int hf_bits=6; int hiband_mode; /*----------------------------------------------------------* * Set number of bits used for stereo (per packet of 20 ms) * * When stereo is transmitted, the bit ordering is: * * serial: mode (2bits), core, stereo, 2xBWE(2x16bits) * *----------------------------------------------------------*/ nbits = (StereoNbits[brMode] + (2*nbits_bwe))/4; hiband_mode = 0; if (StereoNbits[brMode]-4 > 300) { hiband_mode = 1; } mod = mod_buf+1; mod[-1] = st->last_stereo_mode; /* previous mode */ /*----------------------------------------------------------* * decode the high band parameters * *----------------------------------------------------------*/ for(k=0;k