📄 frame.c
字号:
/*
* 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: frame.c,v 1.4 2002/02/25 22:26:43 dmackie Exp $
*/
/*
* CHANGES:
* 2001/01/17: menno: Added frequency cut off filter.
* 2001/02/28: menno: Added Temporal Noise Shaping.
* 2001/03/05: menno: Added Long Term Prediction.
* 2001/05/01: menno: Added backward prediction.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "frame.h"
#include "coder.h"
#include "joint.h"
#include "channels.h"
#include "bitstream.h"
#include "filtbank.h"
#include "aacquant.h"
#include "util.h"
#include "huffman.h"
#include "psych.h"
#include "tns.h"
#include "ltp.h"
#include "backpred.h"
faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder)
{
faacEncConfigurationPtr config = &(hEncoder->config);
return config;
}
int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder,
faacEncConfigurationPtr config)
{
hEncoder->config.allowMidside = config->allowMidside;
hEncoder->config.useLfe = config->useLfe;
hEncoder->config.useTns = config->useTns;
hEncoder->config.aacObjectType = config->aacObjectType;
hEncoder->config.mpegVersion = config->mpegVersion;
/* No SSR supported for now */
if (hEncoder->config.aacObjectType == SSR)
return 0;
/* LTP only with MPEG4 */
if ((hEncoder->config.aacObjectType == LTP) && (hEncoder->config.mpegVersion != MPEG4))
return 0;
/* Re-init TNS for new profile */
TnsInit(hEncoder);
/* Check for correct bitrate */
if (config->bitRate > MaxBitrate(hEncoder->sampleRate))
return 0;
if (config->bitRate < MinBitrate())
return 0;
/* Bitrate check passed */
hEncoder->config.bitRate = config->bitRate;
/* OK */
return 1;
}
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,
unsigned int numChannels,
unsigned long *inputSamples,
unsigned long *maxOutputBytes)
{
unsigned int channel;
faacEncHandle hEncoder;
*inputSamples = 1024*numChannels;
*maxOutputBytes = (6144/8)*numChannels;
hEncoder = (faacEncStruct*)AllocMemory(sizeof(faacEncStruct));
SetMemory(hEncoder, 0, sizeof(faacEncStruct));
hEncoder->numChannels = numChannels;
hEncoder->sampleRate = sampleRate;
hEncoder->sampleRateIdx = GetSRIndex(sampleRate);
/* 以缺省值初始化各变量*/
hEncoder->frameNum = 0;
hEncoder->flushFrame = 0;
/* 缺省设置*/
hEncoder->config.mpegVersion = MPEG4;
hEncoder->config.aacObjectType = LTP;
hEncoder->config.allowMidside = 1;
hEncoder->config.useLfe = 0;
hEncoder->config.useTns = 0;
hEncoder->config.bitRate = 64000; /*缺省的每信道比特率 */
hEncoder->config.bandWidth = 18000; /*缺省的带宽*/
#ifdef MPEG-4IP
hEncoder->config.useAdts = 1;
#endif
/* 根据已有参数寻找合适的采样频率*/
hEncoder->srInfo = &srInfo[hEncoder->sampleRateIdx];
for (channel = 0; channel < numChannels; channel++) {
hEncoder->coderInfo[channel].prev_window_shape = SINE_WINDOW;
hEncoder->coderInfo[channel].window_shape = SINE_WINDOW;
hEncoder->coderInfo[channel].block_type = ONLY_LONG_WINDOW;
hEncoder->coderInfo[channel].num_window_groups = 1;
hEncoder->coderInfo[channel].window_group_length[0] = 1;
hEncoder->coderInfo[channel].max_pred_sfb = GetMaxPredSfb(hEncoder->sampleRateIdx);
hEncoder->sampleBuff[channel] = NULL;
hEncoder->nextSampleBuff[channel] = NULL;
hEncoder->next2SampleBuff[channel] = NULL;
hEncoder->ltpTimeBuff[channel] = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
SetMemory(hEncoder->ltpTimeBuff[channel], 0, 2*BLOCK_LEN_LONG*sizeof(double));
}
/*初始化编码器各函数*/
PsyInit(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels,
hEncoder->sampleRate, hEncoder->sampleRateIdx);
FilterBankInit(hEncoder);
TnsInit(hEncoder);
LtpInit(hEncoder);
PredInit(hEncoder);
AACQuantizeInit(hEncoder->coderInfo, hEncoder->numChannels);
HuffmanInit(hEncoder->coderInfo, hEncoder->numChannels);
/*返回编码器句柄值*/
return hEncoder;
}
int FAACAPI faacEncClose(faacEncHandle hEncoder)
{
unsigned int channel;
/* 编码器关闭函数*/
PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels);
//关闭滤波器空间
FilterBankEnd(hEncoder);
//关闭Ltp编码器
LtpEnd(hEncoder);
//关闭AAC量化器
AACQuantizeEnd(hEncoder->coderInfo, hEncoder->numChannels);
//关闭霍夫曼编码器
HuffmanEnd(hEncoder->coderInfo, hEncoder->numChannels);
/* 释放保留的存储空间*/
for (channel = 0; channel < hEncoder->numChannels; channel++) {
if (hEncoder->ltpTimeBuff[channel]) FreeMemory(hEncoder->ltpTimeBuff[channel]);
if (hEncoder->sampleBuff[channel]) FreeMemory(hEncoder->sampleBuff[channel]);
if (hEncoder->nextSampleBuff[channel]) FreeMemory(hEncoder->nextSampleBuff[channel]);
}
/* 释放编码器空间*/
if (hEncoder) FreeMemory(hEncoder);
return 0;
}
int FAACAPI faacEncEncode(faacEncHandle hEncoder,
short *inputBuffer,
unsigned int samplesInput,
unsigned char *outputBuffer,
unsigned int bufferSize)
{
unsigned int channel, i;
int sb, frameBytes;
unsigned int bitsToUse, offset;
BitStream *bitStream; /*用于写音频帧的比特流数据*/
TnsInfo *tnsInfo_for_LTP;
TnsInfo *tnsDecInfo;
/* 函数体内部参数复制*/
ChannelInfo *channelInfo = hEncoder->channelInfo;
CoderInfo *coderInfo = hEncoder->coderInfo;
unsigned int numChannels = hEncoder->numChannels;
unsigned int sampleRate = hEncoder->sampleRate;
unsigned int aacObjectType = hEncoder->config.aacObjectType;
unsigned int mpegVersion = hEncoder->config.mpegVersion;
unsigned int useLfe = hEncoder->config.useLfe;
unsigned int useTns = hEncoder->config.useTns;
unsigned int allowMidside = hEncoder->config.allowMidside;
unsigned int bitRate = hEncoder->config.bitRate;
unsigned int bandWidth = hEncoder->config.bandWidth;
/* 转到下一个音频帧*/
hEncoder->frameNum++;
if (samplesInput == 0)
hEncoder->flushFrame++;
/* 2次帧刷新后,所有的采样都被编码,返回0字节被写入*/
if (hEncoder->flushFrame == 2)
return 0;
/* 决定信道的设置*/
GetChannelInfo(channelInfo, numChannels, useLfe);
/* 对当前的采样存储空间进行一次Update */
for (channel = 0; channel < numChannels; channel++) {
if (hEncoder->sampleBuff[channel]) {
for(i = 0; i < FRAME_LEN; i++) {
hEncoder->ltpTimeBuff[channel][i] = hEncoder->sampleBuff[channel][i];
}
}
if (hEncoder->nextSampleBuff[channel]) {
for(i = 0; i < FRAME_LEN; i++) {
hEncoder->ltpTimeBuff[channel][FRAME_LEN + i] =
hEncoder->nextSampleBuff[channel][i];
}
}
if (hEncoder->sampleBuff[channel])
FreeMemory(hEncoder->sampleBuff[channel]);
hEncoder->sampleBuff[channel] = hEncoder->nextSampleBuff[channel];
hEncoder->nextSampleBuff[channel] = (double*)AllocMemory(FRAME_LEN*sizeof(double));
if (samplesInput == 0) { /* 开始刷新存储区*/
for (i = 0; i < FRAME_LEN; i++)
hEncoder->nextSampleBuff[channel][i] = 0.0;
} else {
for (i = 0; i < (int)(samplesInput/numChannels); i++)
hEncoder->nextSampleBuff[channel][i] =
(double)inputBuffer[(i*numChannels)+channel];
for (i = (int)(samplesInput/numChannels); i < FRAME_LEN; i++)
hEncoder->nextSampleBuff[channel][i] = 0.0;
}
/* 心理声学部分*/
/* 更新存储区并对新的采样值做快速Fourier变换*/
PsyBufferUpdate(&hEncoder->gpsyInfo, &hEncoder->psyInfo[channel],
hEncoder->nextSampleBuff[channel]);
}
if (hEncoder->frameNum <= 1) /* 仍然填写输出存储区*/
return 0;
/* 心理声学部分*/
PsyCalculate(channelInfo, &hEncoder->gpsyInfo, hEncoder->psyInfo,
hEncoder->srInfo->cb_width_long, hEncoder->srInfo->num_cb_long,
hEncoder->srInfo->cb_width_short,
hEncoder->srInfo->num_cb_short, numChannels);
BlockSwitch(coderInfo, hEncoder->psyInfo, numChannels);
/* AAC滤波器簇以及MDCT */
for (channel = 0; channel < numChannels; channel++) {
int k;
FilterBank(hEncoder,
&coderInfo[channel],
hEncoder->sampleBuff[channel],
hEncoder->freqBuff[channel],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -