www.pudn.com > aacenc.rar > encoder.c
/* MBSoft Encoder DLL interface module.*/ #include#include #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 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; }