📄 encoder.c
字号:
/* MBSoft Encoder DLL interface module.*/
#include <windows.h>
#include <commctrl.h>
#include "aacenc.h"
#include "common.h" /* common module */
#include "bitstream.h" /* bit stream module */
#include "enc.h" /* encoder cores */
#define BITHEADERBUFSIZE (65536)
/* ---------- functions ---------- */
#define HIGHQ 7
#define NORMALQ 10
#define LOWQ 13
int ByteAlign(BsBitStream* ptrBs)
{
int len, i,j;
len = BsBufferNumBit( ptrBs );
j = (8 - (len%8))%8;
if ((len % 8) == 0) j = 0;
for( i=0; i<j; i++ ) {
BsPutBit( ptrBs, 0, 1 );
}
return j;
}
mbAACStream *mbEncodeInit(mbAACConfig *ac, int *samplesToRead, int *bitBufferSize, int *headerSize)
{
int frameNumSample,delayNumSample;
int ch;
int VBR_setting;
mbAACStream *as;
int startupNumFrame;
as = malloc( sizeof(mbAACStream));
if ((as->inputBuffer = (float**)malloc( ac->channels*sizeof(float*)))==NULL)
return NULL;
for (ch=0; ch < ac->channels; ch++)
{
if ((as->inputBuffer[ch]=(float*)malloc( 1024*sizeof(float)))==NULL)
return NULL;
}
if (ac->sampling_rate != 44100)
return NULL;
if (ac->use_VBR) {
if ((ac->VBR_setting > 2)||(ac->VBR_setting < 0))
return NULL;
} else {
switch (ac->bit_rate) {
case 64000:
case 80000:
case 96000:
case 112000:
case 128000:
case 160000:
case 192000:
case 224000:
case 256000:
break;
default:
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->sampling_rate = ac->sampling_rate;
as->write_header = ac->write_header;
as->use_VBR = ac->use_VBR;
as->profile = ac->profile;
as->is_first_frame = 1;
if (as->write_header) {
*headerSize = 17;
} else {
*headerSize = 0;
}
if (ac->use_VBR) {
ac->bit_rate = 128000;
}
if (ac->VBR_setting == VBR_HIGH)
VBR_setting = HIGHQ;
else if (ac->VBR_setting == VBR_LOW)
VBR_setting = LOWQ;
else if (ac->VBR_setting == VBR_NORMAL)
VBR_setting = NORMALQ;
EncTfInit(
ac->channels,
(float)ac->sampling_rate,
(float)ac->bit_rate,
ac->profile,
VBR_setting,
ac->write_header,
1); // Should be removed
frameNumSample = 1024;
delayNumSample = 2*frameNumSample;
*samplesToRead = frameNumSample * ac->channels;
as->frame_bits = (int)(ac->bit_rate*frameNumSample/ac->sampling_rate+0.5);
if (ac->use_VBR) {
*bitBufferSize = (int)(as->frame_bits * 5 + 8)/8; // Should be enough
} else {
*bitBufferSize = (int)(as->frame_bits * 2 + 8)/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;
return as;
}
int mbEncodeFrame(mbAACStream *as, short *Buffer, int Samples, unsigned char *bitBuffer, int *bitBufSize)
{
int i, error;
int usedNumBit, usedBytes;
BsBitStream *bitBuf;
// Is this the last (incomplete) frame
if ((Samples < 2048)&&(Samples > 0)) {
// Padd with zeros
memset(Buffer + Samples, 0, (2048-Samples)*sizeof(short));
}
// Process Buffer
if (as->channels == 2)
{
if (Samples > 0)
for (i = 0; i < 1024; i++)
{
as->inputBuffer[0][i] = *Buffer++;
as->inputBuffer[1][i] = *Buffer++;
}
else // (Samples == 0) when called by mbEncodeFinish
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 MBERROR;
}
if (as->is_first_frame) {
EncTfFrame(
as->inputBuffer,
(BsBitStream*)NULL,
0,
as->frame_bits,
0,
as->frame_bits + 8184,
as->use_VBR);
as->is_first_frame = 0;
as->cur_frame++;
*bitBufSize = 0;
return MBNO_ERROR;
}
bitBuf = BsOpenWrite(as->frame_bits * 10);
/* 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->inputBuffer,
bitBuf,
as->available_bits,
as->frame_bits,
8,
as->frame_bits + 8184,
as->use_VBR);
if (error == MBERROR)
return MBERROR;
usedNumBit = BsBufferNumBit(bitBuf);
as->total_bits += usedNumBit;
// Copy bitBuf into bitBuffer here
usedBytes = (int)(usedNumBit/8)+0.5;
*bitBufSize = usedBytes;
for (i = 0; i < usedBytes; i++)
bitBuffer[i] = bitBuf->data[i];
BsClose(bitBuf);
/* Adjust available bit counts */
as->available_bits -= usedNumBit; /* Subtract bits used */
as->cur_frame++;
return MBNO_ERROR;
}
int mbEncodeFinish(mbAACStream *as, unsigned char *bitBuffer, int *bitBufSize)
{
unsigned char tmpBitBuffer[2048];
int tmpBitBufSize, i;
mbEncodeFrame(as, NULL, 0, tmpBitBuffer, &tmpBitBufSize);
for (i = 0; i < tmpBitBufSize; i++)
bitBuffer[i] = tmpBitBuffer[i];
mbEncodeFrame(as, NULL, 0, tmpBitBuffer, bitBufSize);
for (i = 0; i < *bitBufSize; i++)
bitBuffer[i+tmpBitBufSize] = tmpBitBuffer[i];
*bitBufSize += tmpBitBufSize;
return MBNO_ERROR;
}
int mbEncodeFree(mbAACStream *as, unsigned char *headerBuf)
{
BsBitStream *bitHeader;
float seconds;
int bits, bytes, ch;
seconds = as->sampling_rate/1024;
seconds = as->cur_frame/seconds;
/* free encoder memory */
EncTfFree();
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->sampling_rate)
break;
else if (SampleRates[i] == 0)
{
return MBERROR;
}
}
// 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);
BsPutBit(bitHeader,0,1);
// element_list
BsPutBit(bitHeader,(as->channels == 2),1);
BsPutBit(bitHeader,0,4);
ByteAlign(bitHeader);
// Comment
BsPutBit(bitHeader,0,8);
bits = BsBufferNumBit(bitHeader);
// Copy bitBuf into bitBuffer here
bytes = (int)((bits+8)/8);
for (i = 0; i < bytes; i++)
headerBuf[i] = bitHeader->data[i];
BsClose(bitHeader);
}
for (ch=0; ch < as->channels; ch++)
if(as->inputBuffer[ch]) free(as->inputBuffer[ch]);
if(as->inputBuffer) free(as->inputBuffer);
free(as);
return MBNO_ERROR;
}
mbVersion *mbEncodeVersion()
{
mbVersion *mbv = malloc(sizeof(mbVersion));
mbv->DLLMajorVersion = 1;
mbv->DLLMinorVersion = 0;
mbv->MajorVersion = 0;
mbv->MinorVersion = 4;
strcpy(mbv->HomePage, "http://fly.to/mbsoft/");
return mbv;
}
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -