⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encoder.c

📁 AAC音频解码算法程序
💻 C
📖 第 1 页 / 共 2 页
字号:

/* 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 + -