1. 程式人生 > >FAAC庫實現PCM編碼

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呼叫流程:

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; }