📄 encoder.c
字号:
/* Encoder DLL interface module.*/
#ifdef FAAC_DLL
#include <windows.h>
#endif
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include "aacenc.h"
#include "bitstream.h" /* bit stream module */
#include "rateconv.h"
#include "enc.h" /* encoder cores */
#include "all.h"
#define BITHEADERBUFSIZE (65536)
/* ---------- functions ---------- */
faacAACStream *faacEncodeInit(faacAACConfig *ac, int *samplesToRead, int *bitBufferSize, int *headerSize)
{
int frameNumSample,delayNumSample;
int ch;
faacAACStream *as;
int startupNumFrame;
as = malloc( sizeof(faacAACStream));
if ((as->inputBuffer = (double**)malloc( ac->channels*sizeof(double*)))==NULL)
return NULL;
for (ch=0; ch < ac->channels; ch++)
{
if ((as->inputBuffer[ch]=(double*)malloc( 1024*sizeof(double)))==NULL)
return NULL;
}
if((ac->bit_rate % 1000)||(ac->bit_rate < 16000)) {
return NULL;
}
if (ac->channels != 2)
return NULL;
if ((ac->profile != MAIN_PROFILE)&&(ac->profile != LOW_PROFILE))
return NULL;
as->total_bits = 0;
as->frames = 0;
as->cur_frame = 0;
as->channels = ac->channels;
as->out_sampling_rate = ac->out_sampling_rate;
as->in_sampling_rate = ac->in_sampling_rate;
as->write_header = ac->write_header;
as->cut_off = ac->cut_off;
as->use_MS = ac->use_MS;
as->use_IS = ac->use_IS;
as->use_TNS = ac->use_TNS;
as->use_LTP = ac->use_LTP;
as->use_PNS = ac->use_PNS;
as->profile = ac->profile;
as->is_first_frame = 1;
if (ac->in_sampling_rate != ac->out_sampling_rate)
as->rc_needed = 1;
else
as->rc_needed = 0;
if (as->write_header) {
*headerSize = 17;
} else {
*headerSize = 0;
}
EncTfInit(ac, 0);
frameNumSample = 1024;
delayNumSample = 2*frameNumSample;
*samplesToRead = frameNumSample * ac->channels;
as->frame_bits = (int)(ac->bit_rate*frameNumSample/ac->out_sampling_rate+0.5); //in output, the number of bits per frame
/*?*/ *bitBufferSize = (int)(((as->frame_bits * 5) + 7)/8);
/* num frames to start up encoder due to delay compensation */
startupNumFrame = (delayNumSample+frameNumSample-1)/frameNumSample;
/* process audio file frame by frame */
as->cur_frame = -startupNumFrame;
as->available_bits = 8184; //???????
if (as->rc_needed) {
as->rc_buf = RateConvInit (0, /* in: debug level */
(double)as->out_sampling_rate/(double)as->in_sampling_rate, /* in: outputRate / inputRate */
as->channels, /* in: number of channels */
-1, /* in: num taps */
-1, /* in: alpha for Kaiser window */
-1, /* in: 6dB cutoff freq / input bandwidth */
-1, /* in: 100dB cutoff freq / input bandwidth */
samplesToRead); /* out: num input samples / frame */
as->samplesToRead = *samplesToRead;
} else {
*samplesToRead = 1024*as->channels;
as->samplesToRead = *samplesToRead;
}
as->savedSize = 0;
return as;
}
int faacEncodeFrame(faacAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer, int *bitBufSize)
{
int i, j, error;
int usedNumBit, usedBytes;
int savedSamplesOut, samplesOut, curSample = 0;
BsBitStream *bitBuf;
float *dataOut;
float *data = NULL;
int totalBytes = 0;
// Is this the last (incomplete) frame
if ((Samples < as->samplesToRead)&&(Samples > 0)) {
// Padd with zeros
memset(Buffer + Samples, 0, (as->samplesToRead-Samples)*sizeof(short));
}
if (as->rc_needed && (Samples > 0)) {
savedSamplesOut = samplesOut = as->savedSize + RateConv (
as->rc_buf, /* in: buffer (handle) */
Buffer, /* in: input data[] */
as->samplesToRead, /* in: number of input samples */
&dataOut);
data = malloc((samplesOut)*sizeof(float));
for (i = 0; i < as->savedSize; i++)
data[i] = as->saved[i];
for (j = 0; i < samplesOut; i++, j++)
data[i] = dataOut[j];
} else if (Samples > 0) {
samplesOut = 1024*as->channels;
data = malloc((samplesOut)*sizeof(float));
for (i = 0; i < samplesOut; i++)
data[i] = Buffer[i];
} else
samplesOut = 1024*as->channels;
while(samplesOut >= 1024*as->channels)
{
// Process Buffer
if (Buffer) {
if (as->channels == 2)
{
if (Samples > 0)
for (i = 0; i < 1024; i++)
{
as->inputBuffer[0][i] = data[curSample+(i*2)];
as->inputBuffer[1][i] = data[curSample+(i*2)+1];
}
else // (Samples == 0) when called by faacEncodeFinish
for (i = 0; i < 1024; i++)
{
as->inputBuffer[0][i] = 0;
as->inputBuffer[1][i] = 0;
}
} else {
// No mono supported yet (basically only a problem with decoder
// the encoder in fact supports it).
return FERROR;
}
}
if (as->is_first_frame) {
EncTfFrame(as, (BsBitStream*)NULL);
as->is_first_frame = 0;
as->cur_frame++;
*bitBufSize = 0;
samplesOut -= (as->channels*1024);
curSample += (as->channels*1024);
continue;
}
bitBuf = BsOpenWrite(as->frame_bits * 10); /* alloc a bitstream*/
/* compute available number of bits */
/* frameAvailNumBit contains number of bits in reservoir */
/* variable bit rate: don't exceed bit reservoir size */
if (as->available_bits > 8184)
as->available_bits = 8184;
/* Add to frameAvailNumBit the number of bits for this frame */
as->available_bits += as->frame_bits;
/* Encode frame */
error = EncTfFrame(as, bitBuf);
if (error == FERROR)
return FERROR;
usedNumBit = BsBufferNumBit(bitBuf);
as->total_bits += usedNumBit;
// Copy bitBuf into bitBuffer here
usedBytes = (int)((usedNumBit+7)/8);
for (i = 0; i < usedBytes; i++)
bitBuffer[i+totalBytes] = bitBuf->data[i];
totalBytes += usedBytes;
BsClose(bitBuf);
/* Adjust available bit counts */
as->available_bits -= usedNumBit; /* Subtract bits used */
as->cur_frame++;
samplesOut -= (as->channels*1024);
curSample += (as->channels*1024);
}
*bitBufSize = totalBytes;
as->savedSize = samplesOut;
for (i = 0; i < samplesOut; i++)
as->saved[i] = data[curSample+i];
if (data) free(data);
return FNO_ERROR;
}
int faacEncodeFinish(faacAACStream *as, unsigned char *bitBuffer, int *bitBufSize)
{
unsigned char tmpBitBuffer[2048];
int tmpBitBufSize, i;
faacEncodeFrame(as, NULL, 0, tmpBitBuffer, &tmpBitBufSize);
for (i = 0; i < tmpBitBufSize; i++)
bitBuffer[i] = tmpBitBuffer[i];
faacEncodeFrame(as, NULL, 0, tmpBitBuffer, bitBufSize);
for (i = 0; i < *bitBufSize; i++)
bitBuffer[i+tmpBitBufSize] = tmpBitBuffer[i];
*bitBufSize += tmpBitBufSize;
return FNO_ERROR;
}
int faacEncodeFree(faacAACStream *as, unsigned char *headerBuf)
{
BsBitStream *bitHeader;
float seconds;
int bits, bytes, ch;
seconds = (float)as->out_sampling_rate/(float)1024;
seconds = (float)as->cur_frame/seconds;
/* free encoder memory */
EncTfFree();
if (as->rc_needed)
RateConvFree (as->rc_buf);
if (as->write_header)
{
int i;
static int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0};
as->total_bits += 17 * 8;
bitHeader = BsOpenWrite(BITHEADERBUFSIZE);
for (i = 0; ; i++)
{
if (SampleRates[i] == as->out_sampling_rate)
break;
else if (SampleRates[i] == 0)
{
return FERROR;
}
}
// ADIF_Header
BsPutBit(bitHeader,'A',8);
BsPutBit(bitHeader,'D',8);
BsPutBit(bitHeader,'I',8);
BsPutBit(bitHeader,'F',8);
BsPutBit(bitHeader,0,1); // Copyright present
BsPutBit(bitHeader,0,1); // Original
BsPutBit(bitHeader,0,1); // Home
BsPutBit(bitHeader,0,1); // Bitstream type
BsPutBit(bitHeader,(int)(as->total_bits/seconds),23); // Bitrate
BsPutBit(bitHeader, 0, 4); // num program config elements
// ADIF_buffer_fulness
BsPutBit(bitHeader, 0, 20);
// program_config_element
BsPutBit(bitHeader,0,4);
BsPutBit(bitHeader,as->profile,2);
BsPutBit(bitHeader,i,4);
BsPutBit(bitHeader,1,4);
BsPutBit(bitHeader,0,4);
BsPutBit(bitHeader,0,4);
BsPutBit(bitHeader,0,2);
BsPutBit(bitHeader,0,3);
BsPutBit(bitHeader,0,4);
BsPutBit(bitHeader,0,1);
BsPutBit(bitHeader,0,1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -