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

C++使用fdk-aac實現將音頻PCM編碼成aac

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

前言

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

一、接口設計

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

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

二、使用示例

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

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編碼對象
        //其中參數的聲道數是最大緩存數量,并非實際聲道數,實際聲道數由SetChannelMode方法確定,本版本需要確保SetChannelMode的聲道數與構造方法參數的聲道數一致。
        AC::FdkaacEncoder fe({ 2 ,44100 ,16 });
        unsigned char buf[2048];
        //設置參數
        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);
        //注冊編碼數據到達事件
        fe.EncodedDataArrived = [&](auto s, auto e) {
            //將得到的編碼數據寫入文件
            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數據
            int size = wr.ReadData(buf, 2048);
            if (size < 1)
                break;
            //將pcm數據寫入編碼器
            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編碼對象
        //其中參數的聲道數是最大緩存數量,并非實際聲道數,實際聲道數由SetChannelMode方法確定,本版本需要確保SetChannelMode的聲道數與構造方法參數的聲道數一致。
        AC::FdkaacEncoder fe({ 1 ,44100 ,16 });
        unsigned char buf[2048];
        //設置參數
        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);
        //注冊編碼數據到達事件
        fe.EncodedDataArrived = [&](auto s, auto e) {
            //將得到的編碼數據寫入文件
            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數據
            int size = wr.ReadData(buf, 2048);
            if (size < 1)
                break;
            //將pcm數據寫入編碼器
            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);
}

總結

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

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

相關文章

  • 自己實現strcpy函數的實現方法

    自己實現strcpy函數的實現方法

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

    Qt?timerEvent實現簡單秒表功能

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

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

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

    C語言內存對齊實例詳解

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

    C++中的Qt?QTableView詳解

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

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

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

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

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

    vscode cmake compilers配置路徑的實現

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

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

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

    C\C++實現讀寫二進制文件的方法詳解

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

最新評論

柳林县| 手游| 庆阳市| 肃北| 五原县| 霍州市| 内乡县| 那曲县| 五家渠市| 济宁市| 五常市| 河北区| 满洲里市| 达孜县| 巴林右旗| 三江| 当雄县| 大渡口区| 黑河市| 昭平县| 宜兰市| 油尖旺区| 开化县| 五莲县| 宝清县| 东海县| 屯昌县| 岗巴县| 汝南县| 锦州市| 郯城县| 华池县| 谷城县| 容城县| 同江市| 定安县| 门头沟区| 汉川市| 清远市| 酒泉市| 金沙县|