技術在于交流、溝通,轉載請注明出處并保持作品的完整性。
原文:https://blog.csdn.net/hiwubihe/article/details/81260931
[音頻編解碼系列文章]
- 音頻編解碼基礎
- FFMPEG實作音頻重采樣
- FFMPEG實作PCM編碼(采用封裝格式實作)
- FFMPEG實作PCM編碼(不采用封裝格式實作)
- FAAC庫實作PCM編碼
- FAAD庫實作RAW格式AAC解碼
- FAAD庫實作RAW格式AAC封裝成ADTS格式
- FAAD庫實作ADTS格式解碼
- FFMPEG實作對AAC解碼(采用封裝格式實作)
- FFMPEG實作對AAC解碼(不采用封裝格式實作)
faac對pcm編碼很簡單,測試一下31bit樣本深度,編碼後沒有聲音,16bit編碼沒問題,估計是faac不支援這種樣本格式,實際中如果需要對32bit采用aac編碼,可能需要重采樣。
faac調用流程:
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;
}