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; iinputBuffer = (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; 
}