天天看點

FAAC庫實作PCM編碼

技術在于交流、溝通,轉載請注明出處并保持作品的完整性。

原文:https://blog.csdn.net/hiwubihe/article/details/81260931

[音頻編解碼系列文章]

  1. 音頻編解碼基礎
  2. FFMPEG實作音頻重采樣
  3. FFMPEG實作PCM編碼(采用封裝格式實作)
  4. FFMPEG實作PCM編碼(不采用封裝格式實作)
  5. FAAC庫實作PCM編碼
  6. FAAD庫實作RAW格式AAC解碼
  7. FAAD庫實作RAW格式AAC封裝成ADTS格式
  8. FAAD庫實作ADTS格式解碼
  9. FFMPEG實作對AAC解碼(采用封裝格式實作)
  10. FFMPEG實作對AAC解碼(不采用封裝格式實作)

faac對pcm編碼很簡單,測試一下31bit樣本深度,編碼後沒有聲音,16bit編碼沒問題,估計是faac不支援這種樣本格式,實際中如果需要對32bit采用aac編碼,可能需要重采樣。

faac調用流程:

FAAC庫實作PCM編碼

demo代碼如下:

/*******************************************************************************
Copyright (c) wubihe Tech. Co., Ltd. All rights reserved.
--------------------------------------------------------------------------------

Date Created:	2014-10-25
Author:			wubihe QQ:1269122125 Email:[email protected]
Description:	使用aac庫把PCM編碼成aac 測試時 源檔案是f32le格式 轉換的AAC檔案聽不見聲音 
				估計是faac不支援這種格式,如果需要編碼可能要重新采樣。
--------------------------------------------------------------------------------
Modification History
DATE          AUTHOR          DESCRIPTION
--------------------------------------------------------------------------------

********************************************************************************/
  
#include <stdio.h> 
#include "faac.h"
 
#ifndef BYTE
typedef unsigned char BYTE;
#endif



int main()
{ 	
	//設定PCM 參數
	unsigned long   nSampleRate = 48000;
	unsigned int    nChannels	= 2;
	unsigned int    nPCMBitSize = 16;
	//編碼時一幀一幀送入編碼器編碼的 音頻幀的概念是各個編碼器自己定義的 AAC定義為1024個樣本數
	//MP3定義為1152個樣本數,雙通道此值要*2
	unsigned long   nInputSamples   = 0;
	unsigned long   nMaxOutputBytes = 0;
	//faac操作句柄
	faacEncHandle   hEncoder = { 0 };

	// 設定輸入輸出檔案  
	FILE* fpIn  = NULL;
	FILE* fpOut = NULL;
	fopen_s(&fpIn, "huangdun_r48000_s16le_c2.pcm","rb");
	fopen_s(&fpOut, "huangdun.aac", "wb");

	if (fpIn == NULL || fpOut == NULL)
	{
		printf("打開檔案失敗!\n");
		return -1;
	}

	// 打開faac編碼器引擎   nInputSamples 傳回2048 雙通道,nMaxOutputBytes每次編碼後最大傳回值
	hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);


	if (hEncoder == NULL)
	{
		printf("faacEncOpen失敗!\n");
		return -1;
	}

	// 配置設定記憶體資訊  
	int     nPCMBufferSize = nInputSamples*nPCMBitSize / 8;
	BYTE*   pbPCMBuffer = new BYTE[nPCMBufferSize];
	BYTE*   pbAACBuffer = new BYTE[nMaxOutputBytes];

	// 擷取目前編碼器資訊  -- 不能缺少,隻有擷取以後才可以Set
	faacEncConfigurationPtr pConfiguration = { 0 };
	pConfiguration = faacEncGetCurrentConfiguration(hEncoder);

	// 設定編碼配置資訊  
	/*
	PCM Sample Input Format
	0   FAAC_INPUT_NULL         invalid, signifies a misconfigured config
	1   FAAC_INPUT_16BIT        native endian 16bit
	2   FAAC_INPUT_24BIT        native endian 24bit in 24 bits      (not implemented)
	3   FAAC_INPUT_32BIT        native endian 24bit in 32 bits      (DEFAULT)
	4   FAAC_INPUT_FLOAT        32bit floating point
	*/
	pConfiguration->inputFormat = FAAC_INPUT_16BIT;

	//AAC編碼等級
	// AAC object types   
	//#define MAIN 1  
	//#define LOW  2  
	//#define SSR  3  
	//#define LTP  4  
	pConfiguration->aacObjectType = LOW;

	//設定AAC單通道比特率 
	pConfiguration->bitRate   = 48000;    // or 0
	pConfiguration->bandWidth = 64000;  //or 0 or 32000

	/*下面可以選擇設定*/
	pConfiguration->allowMidside = 1;
	pConfiguration->useLfe = 0;
	pConfiguration->useTns = 0;   
	//AAC品質
	pConfiguration->quantqual = 100;
	//outputformat 0 = Raw; 1 = ADTS  
	pConfiguration->outputFormat = 0;
	pConfiguration->shortctl = SHORTCTL_NORMAL;  

	// 重置編碼器的配置資訊  
	faacEncSetConfiguration(hEncoder, pConfiguration);

	size_t nRet = 0;

	int i = 0;
	while ((nRet = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn)) > 0)
	{
		//實際讀取的樣本數 兩個通道總樣本數
		nInputSamples = nRet / (nPCMBitSize / 8);

		// 編碼  
		nRet = faacEncEncode(hEncoder, (int*)pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);

		// 寫入轉碼後的資料  
		fwrite(pbAACBuffer, 1, nRet, fpOut);
	}

	faacEncClose(hEncoder);
	fclose(fpOut);
	fclose(fpIn);

	delete[] pbAACBuffer;
	delete[] pbPCMBuffer;

	printf("faac complete aac encode!!\n");
	getchar();

	return 0;
}

           

繼續閱讀