⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filtbank.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * FAAC - Freeware Advanced Audio Coder
 * Copyright (C) 2001 Menno Bakker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: filtbank.c,v 1.3 2001/06/04 23:02:24 wmay 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_PI


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( 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( 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( 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( 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( 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( 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++)
				o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] = transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
			SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
        } else { /* overlap_select == NON_OVERLAPPED */
			for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
				transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] *= second_window[BLOCK_LEN_SHORT-i-1];
			SetMemory(transf_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -