Audio codec FAAC PCM to AAC

1 Download and install FAAC

The installation process here is implemented on Mac and Linux, and Windows can be similarly referred to.

wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz
tar zxvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
sudo make install

2 FAAC APIs

2.1 Open FAAC engine

Prototype:

faacEncHandle faacEncOpen               // 返回一个FAAC的handle
(                   
    unsigned long   nSampleRate,        // 采样率,单位是bps
    unsigned long   nChannels,          // 声道,1为单声道,2为双声道
    unsigned long   &nInputSamples,     // 传引用,得到每次调用编码时所应接收的原始数据长度
    unsigned long   &nMaxOutputBytes    // 传引用,得到每次调用编码时生成的AAC数据的最大长度
);

2.2 Get/Set encoding configuration

Prototype:

Get the encoder's configuration:

faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向当前编码器配置的指针
(
    faacEncHandle hEncoder  // FAAC的handle
);

Set the configuration of the encoder:

int FAACAPI faacEncSetConfiguration
(
    faacDecHandle hDecoder,         // 此前得到的FAAC的handle
    faacEncConfigurationPtr config  // FAAC编码器的配置
);

2.3 Encode

Prototype:

int faacEncEncode
(
    faacEncHandle hEncoder,     // FAAC的handle
    short *inputBuffer,         // WAV原始数据
    unsigned int samplesInput,  // 调用faacEncOpen时得到的nInputSamples值
    unsigned char *outputBuffer,// 至少具有调用faacEncOpen时得到的nMaxOutputBytes字节长度的缓冲区
    unsigned int bufferSize     // outputBuffer缓冲区的实际大小
);

2.4 Close FAAC engine

Prototype

void faacEncClose
(
    faacEncHandle hEncoder  // 此前得到的FAAC handle
);
 
 

3 process

3.1 What to do to prepare?

Sample rate, number of channels (dual or mono?), and are individual samples of your WAV 8-bit or 16-bit?

3.2 Turn on the FAAC encoder and prepare for encoding

  1. After calling to faacEncOpenenable the FAAC encoder, the number of single input samples nInputSamplesand the maximum number of bytes of output data are obtained nMaxOutputBytes;
  2. According to nInputSamplesand nMaxOutputBytes, create buffers for WAV data and AAC data to be obtained respectively;
  3. Call faacEncGetCurrentConfigurationto get the current configuration. After modifying the configuration, call faacEncSetConfigurationto set the new configuration.
 
 

3.3 Start coding

Call faacEncEncode, everything that needs to be prepared has been prepared just now, it's very simple.

3.4 Aftercare

Close the encoder, and don't forget to release the buffer, and if you use a file stream, don't forget to close it.

4 Test procedure

4.1 Complete code

#include <faac.h>
#include <stdio.h>
 
typedef unsigned long   ULONG;
typedef unsigned int    UINT;
typedef unsigned char   BYTE;
typedef char            _TCHAR;
 
int main(int argc, _TCHAR* argv[])
{
    ULONG nSampleRate = 11025;  // 采样率
    UINT nChannels = 1;         // 声道数
    UINT nPCMBitSize = 16;      // 单样本位数
    ULONG nInputSamples = 0;
    ULONG nMaxOutputBytes = 0;
 
    int nRet;
    faacEncHandle hEncoder;
    faacEncConfigurationPtr pConfiguration; 
 
    int nBytesRead;
    int nPCMBufferSize;
    BYTE* pbPCMBuffer;
    BYTE* pbAACBuffer;
 
    FILE* fpIn; // WAV file for input
    FILE* fpOut; // AAC file for output
 
    fpIn = fopen("/home/michael/Development/testspace/in.wav", "rb");
    fpOut = fopen("/home/michael/Development/testspace/out.aac", "wb");
 
    // (1) Open FAAC engine
    hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
    if(hEncoder == NULL)
    {
        printf("[ERROR] Failed to call faacEncOpen()\n");
        return -1;
    }
 
    nPCMBufferSize = nInputSamples * nPCMBitSize / 8;
    pbPCMBuffer = new BYTE [nPCMBufferSize];
    pbAACBuffer = new BYTE [nMaxOutputBytes];
 
    // (2.1) Get current encoding configuration
    pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
    pConfiguration->inputFormat = FAAC_INPUT_16BIT;
 
    // (2.2) Set encoding configuration
    nRet = faacEncSetConfiguration(hEncoder, pConfiguration);
 
    for(int i = 0; 1; i++)
    {
        // 读入的实际字节数,最大不会超过nPCMBufferSize,一般只有读到文件尾时才不是这个值
        nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);
 
        // 输入样本数,用实际读入字节数计算,一般只有读到文件尾时才不是nPCMBufferSize/(nPCMBitSize/8);
        nInputSamples = nBytesRead / (nPCMBitSize / 8);
 
        // (3) Encode
        nRet = faacEncEncode(
        hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
 
        fwrite(pbAACBuffer, 1, nRet, fpOut);
 
        printf("%d: faacEncEncode returns %d\n", i, nRet);
 
        if(nBytesRead <= 0)
        {
            break;
        }
    }
 
    
 
    // (4) Close FAAC engine
    nRet = faacEncClose(hEncoder);
 
    delete[] pbPCMBuffer;
    delete[] pbAACBuffer;
    fclose(fpIn);
    fclose(fpOut);
 
    //getchar();
 
    return 0;
}
 
 

4.2 Compile and run

Save the above code as "wav2aac.cpp" file, then compile:

g++ wav2aac.cpp -o wav2aac -L/usr/local/lib -lfaac -I/usr/local/include

run:

./wav2aac

Then out.aacthe file is generated, listen to it!

Guess you like

Origin blog.csdn.net/qq_39436605/article/details/131974552