📄 filtbank.c
字号:
/************************* MPEG-2 NBC Audio Decoder ************************** * *"This software module was originally developed byAT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS in the course ofdevelopment of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,14496-1,2 and 3. This software module is an implementation of a part of one or moreMPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audiostandards free license to this software module or modifications thereof for use inhardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4Audio standards. Those intending to use this software module in hardware orsoftware products are advised that this use may infringe existing patents.The original developer of this software module and his/her company, the subsequenteditors and their companies, and ISO/IEC have no liability for use of this softwaremodule or modifications thereof in an implementation. Copyright is not released fornon MPEG-2 NBC/MPEG-4 Audio conforming products.The original developerretains full right to use the code for his/her own purpose, assign or donate thecode to a third party and to inhibit third party from using the code for nonMPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice mustbe included in all copies or derivative works."Copyright(c)1996. * * ****************************************************************************//* * $Id: filtbank.c,v 1.1 2006/02/23 14:30:26 kevin-fu Exp $ *//* * CHANGES: * 2001/01/17: menno: Added frequency cut off filter. * */#include <math.h>#include <stdio.h>#include <stdlib.h>#include "coder.h"#include "filtbank.h"#include "frame.h"#include "fft.h"#include "util.h"#define TWOPI 2*M_PIstatic void CalculateKBDWindow ( double* win, double alpha, int length );static double Izero ( double x);static void MDCT ( FFT_Tables *fft_tables, double *data, int N );static void IMDCT ( FFT_Tables *fft_tables, double *data, int N );void FilterBankInit(faacEncHandle hEncoder){ unsigned int i, channel; for (channel = 0; channel < hEncoder->numChannels; channel++) { hEncoder->freqBuff[channel] = (double*)AllocMemory(2*FRAME_LEN*sizeof(double)); hEncoder->overlapBuff[channel] = (double*)AllocMemory(FRAME_LEN*sizeof(double)); SetMemory(hEncoder->overlapBuff[channel], 0, FRAME_LEN*sizeof(double)); } hEncoder->sin_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double)); hEncoder->sin_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double)); hEncoder->kbd_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double)); hEncoder->kbd_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double)); for( i=0; i<BLOCK_LEN_LONG; i++ ) hEncoder->sin_window_long[i] = sin((M_PI/(2*BLOCK_LEN_LONG)) * (i + 0.5)); for( i=0; i<BLOCK_LEN_SHORT; i++ ) hEncoder->sin_window_short[i] = sin((M_PI/(2*BLOCK_LEN_SHORT)) * (i + 0.5)); CalculateKBDWindow(hEncoder->kbd_window_long, 4, BLOCK_LEN_LONG*2); CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2);}void FilterBankEnd(faacEncHandle hEncoder){ unsigned int channel; for (channel = 0; channel < hEncoder->numChannels; channel++) { if (hEncoder->freqBuff[channel]) FreeMemory(hEncoder->freqBuff[channel]); if (hEncoder->overlapBuff[channel]) FreeMemory(hEncoder->overlapBuff[channel]); } if (hEncoder->sin_window_long) FreeMemory(hEncoder->sin_window_long); if (hEncoder->sin_window_short) FreeMemory(hEncoder->sin_window_short); if (hEncoder->kbd_window_long) FreeMemory(hEncoder->kbd_window_long); if (hEncoder->kbd_window_short) FreeMemory(hEncoder->kbd_window_short);}void FilterBank(faacEncHandle hEncoder, CoderInfo *coderInfo, double *p_in_data, double *p_out_mdct, double *p_overlap, int overlap_select){ double *p_o_buf, *first_window, *second_window; double *transf_buf; int k, i; int block_type = coderInfo->block_type; transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double)); /* create / shift old values */ /* We use p_overlap here as buffer holding the last frame time signal*/ if(overlap_select != MNON_OVERLAPPED) { memcpy(transf_buf, p_overlap, FRAME_LEN*sizeof(double)); memcpy(transf_buf+BLOCK_LEN_LONG, p_in_data, FRAME_LEN*sizeof(double)); memcpy(p_overlap, p_in_data, FRAME_LEN*sizeof(double)); } else { memcpy(transf_buf, p_in_data, 2*FRAME_LEN*sizeof(double)); } /* Window shape processing */ if(overlap_select != MNON_OVERLAPPED) { switch (coderInfo->prev_window_shape) { case SINE_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW)) first_window = hEncoder->sin_window_long; else first_window = hEncoder->sin_window_short; break; case KBD_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW)) first_window = hEncoder->kbd_window_long; else first_window = hEncoder->kbd_window_short; break; } switch (coderInfo->window_shape){ case SINE_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW)) second_window = hEncoder->sin_window_long; else second_window = hEncoder->sin_window_short; break; case KBD_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW)) second_window = hEncoder->kbd_window_long; else second_window = hEncoder->kbd_window_short; break; } } else { /* Always long block and sine window for LTP */ first_window = hEncoder->sin_window_long; second_window = hEncoder->sin_window_long; } /* Set ptr to transf-Buffer */ p_o_buf = transf_buf; /* Separate action for each Block Type */ switch (block_type) { case ONLY_LONG_WINDOW : for ( i = 0 ; i < BLOCK_LEN_LONG ; i++){ p_out_mdct[i] = p_o_buf[i] * first_window[i]; p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1]; } MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG ); break; case LONG_SHORT_WINDOW : for ( i = 0 ; i < BLOCK_LEN_LONG ; i++) p_out_mdct[i] = p_o_buf[i] * first_window[i]; memcpy(p_out_mdct+BLOCK_LEN_LONG,p_o_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double)); for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++) p_out_mdct[i+BLOCK_LEN_LONG+NFLAT_LS] = p_o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1]; SetMemory(p_out_mdct+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double)); MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG ); break; case SHORT_LONG_WINDOW : SetMemory(p_out_mdct,0,NFLAT_LS*sizeof(double)); for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++) p_out_mdct[i+NFLAT_LS] = p_o_buf[i+NFLAT_LS] * first_window[i]; memcpy(p_out_mdct+NFLAT_LS+BLOCK_LEN_SHORT,p_o_buf+NFLAT_LS+BLOCK_LEN_SHORT,NFLAT_LS*sizeof(double)); for ( i = 0 ; i < BLOCK_LEN_LONG ; i++) p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1]; MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_LONG ); break; case ONLY_SHORT_WINDOW : p_o_buf += NFLAT_LS; for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) { for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++ ){ p_out_mdct[i] = p_o_buf[i] * first_window[i]; p_out_mdct[i+BLOCK_LEN_SHORT] = p_o_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1]; } MDCT( &hEncoder->fft_tables, p_out_mdct, 2*BLOCK_LEN_SHORT ); p_out_mdct += BLOCK_LEN_SHORT; p_o_buf += BLOCK_LEN_SHORT; first_window = second_window; } break; } if (transf_buf) FreeMemory(transf_buf);}void IFilterBank(faacEncHandle hEncoder, CoderInfo *coderInfo, double *p_in_data, double *p_out_data, double *p_overlap, int overlap_select){ double *o_buf, *transf_buf, *overlap_buf; double *first_window, *second_window; double *fp; int k, i; int block_type = coderInfo->block_type; transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double)); overlap_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double)); /* Window shape processing */ if (overlap_select != MNON_OVERLAPPED) {// switch (coderInfo->prev_window_shape){// case SINE_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW)) first_window = hEncoder->sin_window_long; else first_window = hEncoder->sin_window_short;// break;// case KBD_WINDOW:// if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))// first_window = hEncoder->kbd_window_long;// else// first_window = hEncoder->kbd_window_short;// break;// }// switch (coderInfo->window_shape){// case SINE_WINDOW: if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW)) second_window = hEncoder->sin_window_long; else second_window = hEncoder->sin_window_short;// break;// case KBD_WINDOW:// if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))// second_window = hEncoder->kbd_window_long;// else// second_window = hEncoder->kbd_window_short;// break;// } } else { /* Always long block and sine window for LTP */ first_window = hEncoder->sin_window_long; second_window = hEncoder->sin_window_long; } /* Assemble overlap buffer */ memcpy(overlap_buf,p_overlap,BLOCK_LEN_LONG*sizeof(double)); o_buf = overlap_buf; /* Separate action for each Block Type */ switch( block_type ) { case ONLY_LONG_WINDOW : memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double)); IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG ); for ( i = 0 ; i < BLOCK_LEN_LONG ; i++) transf_buf[i] *= first_window[i]; if (overlap_select != MNON_OVERLAPPED) { for ( i = 0 ; i < BLOCK_LEN_LONG; i++ ){ o_buf[i] += transf_buf[i]; o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1]; } } else { /* overlap_select == NON_OVERLAPPED */ for ( i = 0 ; i < BLOCK_LEN_LONG; i++ ) transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1]; } break; case LONG_SHORT_WINDOW : memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double)); IMDCT( &hEncoder->fft_tables, transf_buf, 2*BLOCK_LEN_LONG ); for ( i = 0 ; i < BLOCK_LEN_LONG ; i++) transf_buf[i] *= first_window[i]; if (overlap_select != MNON_OVERLAPPED) { for ( i = 0 ; i < BLOCK_LEN_LONG; i++ ) o_buf[i] += transf_buf[i]; memcpy(o_buf+BLOCK_LEN_LONG,transf_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double)); for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -