最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++使用fdk-aac實現(xiàn)將音頻PCM編碼成aac

 更新時間:2023年11月08日 14:24:50   作者:CodeOfCC  
mp4的音頻流通常是aac編碼,我們做音視頻采集的時候就需要將,采集的音頻PCM編碼成aac,本文就來為大家介紹一下C++如何使用fdk-aac實現(xiàn)將音頻PCM編碼成aac吧

前言

mp4的音頻流通常是aac編碼,我們做音視頻采集的時候就需要將,采集的音頻PCM編碼成aac,然后再打包進mp4,而aac編解碼庫中fdk-aac是性能較好的,使用方式也比較簡單。在C++項目中使用,通常再做一層封裝,提高模塊的復(fù)用性和替換性。本文將展示C++將fdk-aac封裝成一個編碼對象,以及使用示例。

一、接口設(shè)計

由于我前面的文章已經(jīng)給出了fdk-aac的使用示例:《Windows上使用vs編譯fdk-aac》,所以在這里直接設(shè)計對象的接口。

/// <summary>
/// aac編碼對象
/// 所有方法采用異常處理進行錯誤提示,使用時注意使用try-catch,拋出對象為std::exception。
/// 構(gòu)造方法參數(shù)的聲道數(shù)是最大緩存數(shù)量,并非實際聲道數(shù),實際聲道數(shù)由SetChannelMode方法確定,本版本需要確保SetChannelMode的聲道數(shù)與構(gòu)造方法參數(shù)的聲道數(shù)一致。
/// </summary>
class FdkaacEncoder {
public:
    /// <summary>
    /// 編碼數(shù)據(jù)到達事件參數(shù)
    /// </summary>
    class EncodedDataArrivedEventArgs 
    {
    public:
        /// <summary>
        /// 音頻幀
        /// </summary>
        AudioCodingFrame Frame;
    };
    /// <summary>
    /// 編碼數(shù)據(jù)到達事件
    /// </summary>
    std::function<void(void*,EncodedDataArrivedEventArgs*)> EncodedDataArrived;
    /// <summary>
    /// 構(gòu)造方法
    /// </summary>
    /// <param name="">編碼參數(shù)</param>
    FdkaacEncoder(SoundFormat format);
    /// <summary>
    /// 析構(gòu)方法
    /// </summary>
    ~FdkaacEncoder();
    /// <summary>
    /// 獲取聲音格式
    /// </summary>
    /// <returns>聲音格式</returns>
    SoundFormat GetSoundFormat();
    /// <summary>
    /// 設(shè)置比特率
    /// </summary>
    /// <param name="value">比特率,單位byte</param>
    void SetBitrate(int value);
    /// <summary>
    /// 獲取比特率
    /// </summary>
    /// <returns>比特率,單位byte</returns>
    int GetBitrate();
    /// <summary>
    /// 設(shè)置封裝類型
    /// </summary>
    /// <param name="value">封裝類型</param>
    void SetTransportType(TransportType value);
    /// <summary>
    /// 獲取封裝類型
    /// </summary>
    /// <returns>封裝類型</returns>
    TransportType GetTransportType();
    /// <summary>
    /// 設(shè)置比特率模式(CBR、VBR)
    /// </summary>
    /// <param name="value">比特率模式</param>
    void SetBitrateMode(BitrateModde value);
    /// <summary>
    /// 獲取比特率模式(CBR、VBR)
    /// </summary>
    /// <returns>比特率模式</returns>
    BitrateModde GetBitrateMode();
    /// <summary>
    /// 設(shè)置聲道順序
    /// </summary>
    /// <param name="value">聲道順序</param>
    void SetChannelOrder(ChannelOrder value);
    /// <summary>
    /// 獲取聲道順序
    /// </summary>
    /// <returns>聲道順序</returns>
    ChannelOrder GetChannelOrder();
    /// <summary>
    /// 設(shè)置聲道模式,聲道數(shù)需要小于等于構(gòu)造方法設(shè)置的聲道數(shù)。
    /// </summary>
    /// <param name="value">聲道模式</param>
    void SetChannelMode(ChannelMode value);
    /// <summary>
    /// 獲取聲道模式
    /// </summary>
    /// <returns></returns>
    ChannelMode GetChannelMode();
    /// <summary>
    /// 設(shè)置頻段復(fù)制模式
    /// </summary>
    /// <param name="value">頻段復(fù)制模式</param>
    void SetSbrMode(SbrMode value);
    /// <summary>
    /// 獲取頻段復(fù)制模式
    /// </summary>
    /// <returns>頻段復(fù)制模式</returns>
    SbrMode GetSbrMode();
    /// <summary>
    /// 設(shè)置AOT
    /// </summary>
    /// <param name="">AOT</param>
    void SetAudioObjectType(AudioObjectType);
    /// <summary>
    /// 獲取AOT
    /// </summary>
    /// <returns>AOT</returns>
    AudioObjectType GetAudioObjectType();
    /// <summary>
    /// 寫入音頻數(shù)據(jù)
    /// 注意數(shù)據(jù)長度不能過大,否則導(dǎo)致音頻不正常,建議2048。
    /// </summary>
    /// <param name="data">音頻數(shù)據(jù)</param>
    /// <param name="dataLength">數(shù)據(jù)長度</param>
    void Write(unsigned char* data, int dataLength);
}

二、使用示例

將wav文件編碼成acc文件。其中WavFileReader對象參考:《C++ 讀取wav文件中的PCM數(shù)據(jù)

1.雙聲道

#include<stdio.h>
#include<exception>
#include"WavFileReader.h"
#include"FdkaacEncoder.h"
void main(int argc, char* argv[])
{
    FILE* f=nullptr;
    try {        
        //wav文件讀取對象
        AC::WavFileReader wr;
        //aac編碼對象
        //其中參數(shù)的聲道數(shù)是最大緩存數(shù)量,并非實際聲道數(shù),實際聲道數(shù)由SetChannelMode方法確定,本版本需要確保SetChannelMode的聲道數(shù)與構(gòu)造方法參數(shù)的聲道數(shù)一致。
        AC::FdkaacEncoder fe({ 2 ,44100 ,16 });
        unsigned char buf[2048];
        //設(shè)置參數(shù)
        fe.SetSbrMode(AC::SbrMode_Disable);
        fe.SetAudioObjectType(AC::AudioObjectType::AUDIOOBJECTTYPE_AAC_LC);
        fe.SetBitrate(128 * 1024);
        fe.SetChannelMode(AC::ChannelMode::CHANNELMODE_2);
        fe.SetChannelOrder(AC::CHANNELORDER_WAV);
        fe.SetBitrateMode(AC::BitrateModde::BITRATEMODDE_CBR);
        fe.SetTransportType(AC::TRANSPORTTYPE_MP4_ADTS);
        //注冊編碼數(shù)據(jù)到達事件
        fe.EncodedDataArrived = [&](auto s, auto e) {
            //將得到的編碼數(shù)據(jù)寫入文件
            fwrite(e->Frame.Data, 1, e->Frame.DataLength, f);
        };
        //創(chuàng)建aac文件
        f = fopen("test_music.aac", "wb+");
        if (!f)
        {
            throw std::exception("create aac file fail,create name:test_music.aac");
        }
        //打開wav文件
        if (!wr.OpenWavFile("test_music.wav"))
        {
            throw std::exception("open wav file fail,filename:test_music.wav");
        }    
        while (1)
        {   //讀取wav中的pcm數(shù)據(jù)
            int size = wr.ReadData(buf, 2048);
            if (size < 1)
                break;
            //將pcm數(shù)據(jù)寫入編碼器
            fe.Write(buf, size);
        }    
        printf("encode completed\n");
    }
    catch(std::exception e){
        printf("%s\n",e.what());
    }
    catch (...) {
        printf("unknown errror\n");
    }
    if(f)
    fclose(f);
}

2.單聲道

#include<stdio.h>
#include<exception>
#include"WavFileReader.h"
#include"FdkaacEncoder.h"
void main(int argc, char* argv[])
{
    FILE* f = nullptr;
    try {
        //wav文件讀取對象
        AC::WavFileReader wr;
        //aac編碼對象
        //其中參數(shù)的聲道數(shù)是最大緩存數(shù)量,并非實際聲道數(shù),實際聲道數(shù)由SetChannelMode方法確定,本版本需要確保SetChannelMode的聲道數(shù)與構(gòu)造方法參數(shù)的聲道數(shù)一致。
        AC::FdkaacEncoder fe({ 1 ,44100 ,16 });
        unsigned char buf[2048];
        //設(shè)置參數(shù)
        fe.SetSbrMode(AC::SbrMode_Disable);
        fe.SetAudioObjectType(AC::AudioObjectType::AUDIOOBJECTTYPE_AAC_LC);
        fe.SetBitrate(128 * 1024);
        fe.SetChannelMode(AC::ChannelMode::CHANNELMODE_1);
        fe.SetChannelOrder(AC::CHANNELORDER_WAV);
        fe.SetBitrateMode(AC::BitrateModde::BITRATEMODDE_CBR);
        fe.SetTransportType(AC::TRANSPORTTYPE_MP4_ADTS);
        //注冊編碼數(shù)據(jù)到達事件
        fe.EncodedDataArrived = [&](auto s, auto e) {
            //將得到的編碼數(shù)據(jù)寫入文件
            fwrite(e->Frame.Data, 1, e->Frame.DataLength, f);
        };
        //創(chuàng)建aac文件
        f = fopen("test_music_1ch441s16b.aac", "wb+");
        if (!f)
        {
            throw std::exception("create aac file fail,create name:test_music_1ch441s16b.aac");
        }
        //打開wav文件
        if (!wr.OpenWavFile("test_music_1ch441s16b.wav"))
        {
            throw std::exception("open wav file fail,filename:test_music_1ch441s16b.wav");
        }
        while (1)
        {   //讀取wav中的pcm數(shù)據(jù)
            int size = wr.ReadData(buf, 2048);
            if (size < 1)
                break;
            //將pcm數(shù)據(jù)寫入編碼器
            fe.Write(buf, size);
        }
        printf("encode completed\n");
    }
    catch (std::exception e) {
        printf("%s\n", e.what());
    }
    catch (...) {
        printf("unknown errror\n");
    }
    if (f)
        fclose(f);
}

總結(jié)

以上就是今天要講的內(nèi)容,將編碼器設(shè)計成對象可以靈活的使用在項目中,尤其需要使用設(shè)計模式,比如原型模式:一個aac編碼器接口可以有不同的實現(xiàn)fdk-aac只是其中一種實現(xiàn),寫好的代碼可以隨意切換編碼器對象?;蛘卟呗阅J?,設(shè)計一個編碼器接口,調(diào)用時根據(jù)編碼格式選擇合適的編碼器??偟膩碚f,這個對象的設(shè)計和實現(xiàn)不算特別難,就是在細節(jié)的地方需要注意,比如錯誤提示,邊界值處理等。

以上就是C++使用fdk-aac實現(xiàn)將音頻PCM編碼成aac的詳細內(nèi)容,更多關(guān)于C++音頻編碼的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 自己實現(xiàn)strcpy函數(shù)的實現(xiàn)方法

    自己實現(xiàn)strcpy函數(shù)的實現(xiàn)方法

    本篇文章介紹了,自己實現(xiàn)strcpy函數(shù)的實現(xiàn)方法。需要的朋友參考下
    2013-05-05
  • Qt?timerEvent實現(xiàn)簡單秒表功能

    Qt?timerEvent實現(xiàn)簡單秒表功能

    這篇文章主要為大家詳細介紹了Qt?timerEvent實現(xiàn)簡單秒表功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • QT6.5.3安裝教程(使用國內(nèi)源)

    QT6.5.3安裝教程(使用國內(nèi)源)

    本教程講述了使用國內(nèi)源安裝QT6.5.3版本的實現(xiàn)步驟,文中通過圖文示例介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • C語言內(nèi)存對齊實例詳解

    C語言內(nèi)存對齊實例詳解

    這篇文章主要介紹了C語言內(nèi)存對齊,包括內(nèi)存對其的基本概念及用法,以及注意事項,并以實例形式加以說明,需要的朋友可以參考下
    2014-09-09
  • C++中的Qt?QTableView詳解

    C++中的Qt?QTableView詳解

    這篇文章主要介紹了Qt?QTableView詳解,主要包括常用接口,設(shè)置item屬性,右鍵彈出菜單,結(jié)合示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 詳解C語言中strcpy()函數(shù)與strncpy()函數(shù)的使用

    詳解C語言中strcpy()函數(shù)與strncpy()函數(shù)的使用

    這篇文章主要介紹了詳解C語言中strcpy()函數(shù)與strncpy()函數(shù)的使用,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-08-08
  • C 語言二叉樹幾種遍歷方法詳解及實例

    C 語言二叉樹幾種遍歷方法詳解及實例

    這篇文章主要介紹了C 語言二叉樹幾種遍歷方法詳解及實例的相關(guān)資料,二叉樹在數(shù)據(jù)結(jié)構(gòu)當(dāng)中是非常重要的知識要點,這里對二叉樹進行了總結(jié),需要的朋友可以參考下
    2017-01-01
  • vscode cmake compilers配置路徑的實現(xiàn)

    vscode cmake compilers配置路徑的實現(xiàn)

    本文主要介紹了vscode cmake compilers配置路徑的實現(xiàn),文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • 淺析C++中單鏈表的增、刪、改、減

    淺析C++中單鏈表的增、刪、改、減

    以下是對C++中單鏈表的增、刪、改、減進行了詳細的介紹,需要的朋友可以過來參考下
    2013-09-09
  • C\C++實現(xiàn)讀寫二進制文件的方法詳解

    C\C++實現(xiàn)讀寫二進制文件的方法詳解

    這篇文章主要為大家詳細介紹了C\C++實現(xiàn)讀寫二進制文件的方法,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以了解一下
    2023-03-03

最新評論

津南区| 丰都县| 泉州市| 绩溪县| 南郑县| 肇庆市| 宁南县| 五家渠市| 九龙城区| 治县。| 纳雍县| 喀喇| 百色市| 武鸣县| 晋中市| 武定县| 大庆市| 张家口市| 临汾市| 盐池县| 怀来县| 新晃| 蒙自县| 商洛市| 喀什市| 岳阳市| 无为县| 高平市| 宾阳县| 安达市| 河津市| 香河县| 广东省| 海淀区| 开鲁县| 眉山市| 元氏县| 社旗县| 武功县| 昌邑市| 青海省|