色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

全志R128芯片基礎組件開發指南—RTOS多媒體編碼

冬至子 ? 來源:丨budboool ? 作者:丨budboool ? 2023-10-11 14:54 ? 次閱讀

RTOS 多媒體編碼

介紹 FreeRTOS 下如何使用 xrecorder 的接口來開發錄制應用程序,方便錄制應用開發人員快速正確地開發,以及錄制應用測試人員如何根據該文檔對基于 xrecord 的錄制應用進行驗證測試。

編碼支持情況

目前 RTOS 平臺多媒體編碼應用支持的編碼格式分別為:pcm、amr、mp3、speex、opus。

其中 pcm、amr、mp3 可通過 xrecorder 進行編碼以及錄制;speex 和 opus 可通過第三方示例工程進行編碼。

xrecorder 狀態圖

在這里插入圖片描述

這張狀態轉換圖清晰地描述了 xrecorder 的各個狀態,也列舉了主要的方法的調用時序,每種方法只能在一些特定的狀態下使用,否則會出錯。

Init 狀態

Idle 狀態:當調用 XRecordCreate() 創建一個 xrecord 時,處于 idle 狀態。

Prepared 狀態

調用 XRecordPrepare() 函數并返回后,xrecorder 處于 Prepared 狀態。在這個狀態下說明所有的資源都已經就緒了,調用 XRecordStart() 函數就可以進行錄制。

Started 狀態

xrecorder prepare 完成后,調用 XRecordStart() 進行錄制,當應用開始錄制后,xrecorder 就處于 Started 狀態,這表明 xrecorder 正在錄制文件。

Stopped 狀態

Started 狀態下均可調用 XrecordStop() 停止 xrecorder,而處于 Stop 狀態的 xrecorder 要想重新錄制,需要通過 XRecorderPrepare() 回到先前的 Prepared 狀態重新開始才可以。

Destroyed 狀態

通過 XRecordDestroy() 的方法可以進入 Destroyed 狀態,只要 xrecorder 不再被使用,就應當盡快將其 destroy 掉。

接口函數

創建一個 XRecord

XRecord *XRecordCreate()

參數:

返回值:

設置錄制音頻的編碼格式

int XRecordSetAudioEncodeType(XRecord *p, XRECODER_AUDIO_ENCODE_TYPE type, XRecordConfig *config)

參數:

  • p: 通過 XRecordCreate 創建的 XRecord 指針
  • type: 已支持的編碼格式
  • config: 上層應用對音頻屬性的配置

返回值:

  • 成功: 0; 失敗: ?1

獲取指針

獲取指向音頻設備管理模塊的指針,用于錄制音頻

void XRecordSetAudioCap(XRecord* p, const CaptureCtrl* audioSrc)

參數:

  • p: 通過 XRecordCreate 創建的 XRecord 指針
  • audioSrc: 由上層應用獲取的音頻設備管理模塊的指針

返回值:

audioSrc 可在上層應用通過調用 cedarx 的音頻設備管理模塊的 RTCaptureDeviceCreate 來創建。

設置錄制后文件的保存的路徑

int XRecordSetDataDstUrl(XRecord* p, const char* pUrl, void* arg, const CdxKeyedVectorT* pHeaders)

參數:

  • p: 通過 XRecordCreate 創建的 XRecord 指針
  • pUrl:url 地址

返回值:

  • 成功:0;失敗:?1

將 XRecord 置為準備狀態, 準備 Muxer

int XRecordPrepare(XRecord* p)

參數:

  • p:通過 XRecordCreate 創建的 XRecord 指針

返回值:

  • 成功:0;失敗:?1

將 XRecord 置為啟動狀態

int XRecordStart(XRecord* p)

參數:

  • p:通過 XRecordCreate 創建的 XRecord 指針

返回值:

  • 成功:0;失敗:?1

將 XRecord 置為停止狀態

int XRecordStop(XRecord* p)

參數:

  • p:通過 XRecordCreate 創建的 XRecord 指針

返回值:

  • 成功: 0;失敗:?1

編碼數據入隊封裝

提供接口給下層編碼模塊,將編碼數據放進緩存隊列中等待封裝

int onAudioDataEnc(XRecord* app, CdxMuxerPacketT* buff)

參數:

  • app: xrecorder 的環境句柄;
  • buff:編碼后的緩存數據

返回值:

  • 成功: 0;失敗:?1

銷毀一個 XRecord

int XRecordDestroy(XRecord* p)

參數:

  • p:通過 XRecordCreate 創建的 XRecord 指針

返回值:

  • 成功: 0;失敗:?1

XRecorder 開發流程

  1. XRecordCreate() //創建一個錄制應用
  2. XRecordSetAudioCap() //設置音頻采集設備;可先調用 RTCaptureDeviceCreate 創建。
  3. XRecordSetDataDstUrl() //設置錄制后文件保存位置
  4. XRecordSetAudioEncodeType() //設置音頻數據的編碼格式
  5. XRecordPrepare() //設置 Muxer,讓 xrecorder 進入準備狀態
  6. XRecordStart() //開始錄制
  7. XRecordStop() //停止錄制
  8. XRecordDestroy() //當不需要進行錄制的時候,銷毀 xrecorder

注意事項

  1. 在調用 XRecordSetAudioCap 設置音頻采集設備之前,需先打開音頻采集設備來獲取句柄。在 rtos 平臺可調用 libcedarx 提供的音頻采集設備控制模塊 rtosCaptureControl.c 中的 RTCaptureDeviceCreate 來創建句柄。
  2. recorder 應用未支持暫停錄制。
  3. recorder 的錄制時長為調用 XRecordStart 至調用 XRecordStop 之間的時長來決定,因此上層應用需要錄制指定時長的音頻時,錄制的步驟應為調用 XRecordStart,等待指定的時間,調用XRecordStop。

示例代碼

#include < stdio.h >
#include < stdlib.h >
#include < stdbool.h >
#include < string.h >
#include < aw_common.h >
#include < console.h >

#include "vfs.h"
#include "xrecord.h"

#define RECORDER_LOGD(msg, arg...)      printf("[RECORDER_DBG] < %s : %d > " msg "n", __func__, __LINE__, ##arg)
#define RECORDER_LOGI(msg, arg...)      printf("[RECORDER_INFO] < %s : %d > " msg "n", __func__, __LINE__, ##arg)
#define RECORDER_LOGW(msg, arg...)      printf("[RECORDER_WRN] < %s : %d > " msg "n", __func__, __LINE__, ##arg)
#define RECORDER_LOGE(msg, arg...)      printf("[RECORDER_ERR] < %s : %d > " msg "n", __func__, __LINE__, ##arg)

typedef struct recorder_base recorder_base;

typedef struct rec_cfg
{
    XRECODER_AUDIO_ENCODE_TYPE   type;
    int                 sample_rate;
    int                 chan_num;
    int                 bitrate;
    int                 sampler_bits;
} rec_cfg;

struct recorder_base
{
    int (*start)(recorder_base *base, const char *url, const rec_cfg *cfg);
    int (*stop)(recorder_base *base);
};

struct ExampleCustomerWriterImpl
{
    CdxWriterT base;
    vfs_file_t *vfs;
};

typedef struct recorder
{
    recorder_base base;
    XRecord *xrecorder;
    CaptureCtrl *cap;
} recorder;

recorder_base *recorder_create();
int recorder_destroy(recorder_base *base);

/* Example Customer Writer */
static int __CdxExampleConnect(CdxWriterT *writer)
{
    struct ExampleCustomerWriterImpl *impl;

    impl = (struct ExampleCustomerWriterImpl *)writer;

    vfs_unlink("data/record/2.amr");
    impl- >vfs = vfs_open("data/record/2.amr", VFS_RDWR | VFS_CREAT);
    if (impl- >vfs == NULL) {
        return -1;
    }

    return 0;
}

static int __CdxExampleRead(CdxWriterT *writer, void *buf, int size)
{
    return 0;
}

static int __CdxExampleWrite(CdxWriterT *writer, void *buf, int size)
{
    uint32_t write_len;
    struct ExampleCustomerWriterImpl *impl;

    impl = (struct ExampleCustomerWriterImpl *)writer;

    write_len = vfs_write(impl- >vfs, buf, size);

    return write_len;
}

static long __CdxExampleSeek(CdxWriterT *writer, long moffset, int mwhere)
{
    return 0;
}

static long __CdxExampleTell(CdxWriterT *writer)
{
    return 0;
}

static int __CdxExampleClose(CdxWriterT *writer)
{
    struct ExampleCustomerWriterImpl *impl;

    impl = (struct ExampleCustomerWriterImpl *)writer;

    vfs_close(impl- >vfs);
    free(impl);

    return 0;
}

static const struct CdxWriterOps exampleCustomerWriteOps =
{
    .cdxConnect   =  __CdxExampleConnect,
    .cdxRead      =  __CdxExampleRead,
    .cdxWrite     =  __CdxExampleWrite,
    .cdxSeek      =  __CdxExampleSeek,
    .cdxTell      =  __CdxExampleTell,
    .cdxClose     =  __CdxExampleClose
};

CdxWriterT *ExampleCustomerWriterCreat()
{
    struct ExampleCustomerWriterImpl *impl;

    impl = malloc(sizeof(*impl));
    if (impl == NULL) {
        printf("example customer writer create fail.n");
        return NULL;
    }

    memset(impl, 0, sizeof(*impl));

    impl- >base.ops = &exampleCustomerWriteOps;

    return &impl- >base;
}

/* Main App */
static void showHelp(){
    printf("n");
    printf("**************************n");
    printf("* This is a simple audio recoder, when it is started, you can input commands to telln");
    printf("* what you want it to do.n");
    printf("* Usage: n");
    printf("*   cedarx_record amr 10  : this means record 10s amr musicn");
    printf("*   cedarx_record pcm 10  : this means record 10s pcm musicn");
    printf("**************************n");
}

recorder *recorder_singleton = NULL;

static int record_start(recorder_base *base, const char *url, const rec_cfg *cfg)
{
    recorder *impl = container_of(base, recorder, base);

    XRecordConfig audioConfig;

    if (cfg- >type == XRECODER_AUDIO_ENCODE_PCM_TYPE)
    {
        audioConfig.nChan = cfg- >chan_num;
        audioConfig.nSamplerate = cfg- >sample_rate;
        audioConfig.nSamplerBits = cfg- >sampler_bits;
        audioConfig.nBitrate = cfg- >bitrate;
    }
    else if (cfg- >type == XRECODER_AUDIO_ENCODE_AMR_TYPE)
    {
        audioConfig.nChan = 1;
        audioConfig.nSamplerate = 8000;//amr-nb 8000Hz amr-wb 16000Hz
        audioConfig.nSamplerBits = 16;
        audioConfig.nBitrate = 12200;//amr-nb 12200  amr-wb 23850
    } else {
        audioConfig.nChan = cfg- >chan_num;
        audioConfig.nSamplerate = cfg- >sample_rate;
        audioConfig.nSamplerBits = cfg- >sampler_bits;
        audioConfig.nBitrate = cfg- >bitrate;
    }

    XRecordSetDataDstUrl(impl- >xrecorder, url, NULL, NULL);
    XRecordSetAudioEncodeType(impl- >xrecorder, cfg- >type, &audioConfig);

    XRecordPrepare(impl- >xrecorder);
    XRecordStart(impl- >xrecorder);
    RECORDER_LOGI("record start");
    return 0;
}

static int record_stop(recorder_base *base)
{
    recorder *impl = container_of(base, recorder, base);
    XRecordStop(impl- >xrecorder);
    return 0;
}

extern CaptureCtrl* RTCaptureDeviceCreate();

recorder_base *recorder_create()
{
    if (recorder_singleton != NULL)
        return &recorder_singleton- >base;

    recorder *impl = malloc(sizeof(*impl));
    if (impl == NULL)
        return NULL;
    memset(impl, 0, sizeof(*impl));

    impl- >xrecorder = XRecordCreate();
    if (impl- >xrecorder == NULL)
        goto failed;

    impl- >cap = (void *)(uintptr_t)RTCaptureDeviceCreate();
    if (impl- >cap == NULL)
        goto failed;
    XRecordSetAudioCap(impl- >xrecorder, impl- >cap);

    impl- >base.start = record_start;
    impl- >base.stop = record_stop;

    recorder_singleton = impl;

    return &impl- >base;

failed:
    RECORDER_LOGE("recorder create failed");
    if (impl- >xrecorder)
        XRecordDestroy(impl- >xrecorder);
    if (impl)
        free(impl);
    return NULL;
}

int recorder_destroy(recorder_base *base)
{
    recorder *impl = container_of(base, recorder, base);

    if (impl- >xrecorder) {
        XRecordDestroy(impl- >xrecorder);
    }

    free(impl);

    recorder_singleton = NULL;

    return 0;
}

static int cedarx_record_test(int argc, char **argv)
{
    recorder_base *recorder;
    rec_cfg cfg;
    char music_url[64];
    char file_url[64];
    CdxWriterT *writer;
    memset(file_url, 0, 64);
    if(argc == 3){
        if( !strncmp("amr", argv[1], sizeof("amr")-1) ){
            cfg.type = XRECODER_AUDIO_ENCODE_AMR_TYPE;
            snprintf(file_url, 64, "file://data/%ds.amr", atoi(argv[2]));
            cfg.sample_rate = 8000;//8000
            cfg.chan_num = 1;//1
            cfg.bitrate = 12200;
            cfg.sampler_bits = 16;
        }
        else if( !strncmp("pcm", argv[1], sizeof("pcm")-1) ){
            cfg.type = XRECODER_AUDIO_ENCODE_PCM_TYPE;
            snprintf(file_url, 64, "file://data/%ds.pcm", atoi(argv[2]));
            cfg.sample_rate = 8000;//8000
            cfg.chan_num = 1;//1
            cfg.bitrate = 12200;
            cfg.sampler_bits = 16;
        }
        else if( !strncmp("mp3", argv[1], sizeof("mp3")-1) ){
            cfg.type = XRECODER_AUDIO_ENCODE_MP3_TYPE;
            snprintf(file_url, 64, "file://data/%ds.mp3", atoi(argv[2]));
            cfg.sample_rate = 16000;
            cfg.chan_num = 1;
            cfg.bitrate = 32000;
            cfg.sampler_bits = 16;
        } else {
            printf("now support!n");
            return -1;
        }
    }else{
        printf("the parameter is error,usage is as following:n");
        showHelp();
        return -1;
    }

    recorder = recorder_create();
    if (recorder == NULL) {
        printf("recorder create fail, exitn");
        return -1;
    }

    printf("===start record %s now, last for %d s===n", argv[1], atoi(argv[2]));
    recorder- >start(recorder, file_url, &cfg);
    sleep(atoi(argv[2]));
    recorder- >stop(recorder);
    printf("record %s over.n", argv[1]);
exit:
    return recorder_destroy(recorder);
}

FINSH_FUNCTION_EXPORT_CMD(cedarx_record_test, cedarx_record, cedarx record test demo);
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FreeRTOS
    +關注

    關注

    12

    文章

    485

    瀏覽量

    63497
  • 音頻編碼器
    +關注

    關注

    0

    文章

    17

    瀏覽量

    9216
  • 緩存器
    +關注

    關注

    0

    文章

    63

    瀏覽量

    11806
  • vfs
    vfs
    +關注

    關注

    0

    文章

    14

    瀏覽量

    5344
  • R128
    +關注

    關注

    0

    文章

    41

    瀏覽量

    224
收藏 0人收藏

    評論

    相關推薦

    R128基礎組件開發指南RTOS多媒體解碼

    介紹 FreeRTOS 下如何使用 rtplayer 的接口來開發播放器應用程序,方便播放器開發人員快速正確地開發,以及播放器測試人員如何根據該文檔對 rtplayer 播放器進行驗證測試。
    的頭像 發表于 10-10 16:28 ?2803次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>基礎<b class='flag-5'>組件</b><b class='flag-5'>開發指南</b>—<b class='flag-5'>RTOS</b><b class='flag-5'>多媒體</b>解碼

    R128 BLE最高吞吐量測試正確配置測試方法

    R128使用前我們需要了解BLE的最高吞吐量,以方便評估相關功能的開發
    的頭像 發表于 10-27 17:17 ?1685次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b> BLE最高吞吐量測試正確配置測試方法

    R128內存泄漏調試案例分享

    硬件:R128 軟件:FreeRTOS + rtplayer\_test(Cedarx)+ AudioSystem
    的頭像 發表于 11-20 17:27 ?1244次閱讀
    <b class='flag-5'>全</b><b class='flag-5'>志</b><b class='flag-5'>R128</b>內存泄漏調試案例分享

    詳解R128 RTOS安全方案功能

    介紹 R128 下安全方案的功能。安全完整的方案基于標準方案擴展,覆蓋硬件安全、硬件加解密引擎、安全啟動、安全系統、安全存儲等方面。 配置文件相關本文涉及到一些配置文件,在此進行說明。 env
    發表于 12-28 15:59

    R128入門編寫HelloWorld

    本文將介紹使用 R128 開發板從串口輸出 HelloWorld 的方式介紹 SDK 軟件開發流程。 載入方案我們使用的開發板是 R128-
    發表于 12-29 09:39

    R128硬件設計指南

    (ANT pin)無需匹配電路,但可預留天線 PI 型匹配電路。如上圖所示。為了方便天線PI型匹配電路調試,需在射頻輸出端口與天線間預留 0Ω電阻 WR1。如圖所示。 因 R128 芯片射頻前端已
    發表于 01-04 09:23

    R128 SDK架構與目錄結構

    R128 S2 是提供的一款 M33(ARM)+C906(RISCV-64)+HIFI5(Xtensa) 三核異構 SoC,同時芯片內部 SIP 有 1M SRAM、8M LSPS
    發表于 01-05 10:05

    R128 Devkit開發板原理圖模塊介紹及使用說明

    :CH341SER.EXE 購買鏈接 百問科技淘寶店 - R128 DevKit 原理圖模塊介紹R128 模組R128 模組使用 SMT
    發表于 01-17 09:45

    R128芯片 基礎組件開發指南——RTOS 多媒體解碼

    RTOS 多媒體解碼 介紹 FreeRTOS 下如何使用 rtplayer 的接口來開發播放器應用程序,方便播放器開發人員快速正確地開發,以
    發表于 10-10 13:52

    R128芯片應用開發案例——按鍵輸入

    按鍵3腳 載入方案 我們使用的開發板是 R128-Devkit,需要開發 C906 核心的應用程序,所以載入方案選擇r128s2_module_c906 $ source envse
    發表于 10-10 14:34

    R128芯片 基礎組件開發指南——RTOS 多媒體編碼

    RTOS 多媒體編碼 介紹 FreeRTOS 下如何使用 xrecorder 的接口來開發錄制應用程序,方便錄制應用開發人員快速正確地
    發表于 10-11 09:52

    R128芯片 基礎組件開發指南——RTOS 多媒體編碼

    RTOS 多媒體編碼 介紹 FreeRTOS 下如何使用 xrecorder 的接口來開發錄制應用程序,方便錄制應用開發人員快速正確地
    發表于 10-12 15:49

    R128軟件配置——RTOS 軟件包配置

    說明 了解了menuconfig的基本操作,我們再來了解一下 RTOS 的 menuconfig 具體都有是么內容。 Build target sunxi arch 分別選擇芯片的系列,對于R128
    發表于 10-20 15:31

    DshanMCU-R128s2 R128 EVT 開發套件

    針對 R128 模組,百問科技推出了 R128 EVT 開發套件作為快速開發評估工具。
    的頭像 發表于 12-22 15:16 ?1080次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 <b class='flag-5'>R128</b> EVT <b class='flag-5'>開發</b>套件

    DshanMCU-R128s2 SDK 架構與目錄結構

    R128 S2 是提供的一款 M33(ARM)+C906(RISCV-64)+HIFI5(Xtensa) 三核異構 SoC,同時芯片內部 SIP 有 1M SRAM、8M LSPS
    的頭像 發表于 12-22 15:57 ?1031次閱讀
    DshanMCU-<b class='flag-5'>R128</b>s2 SDK 架構與目錄結構

    電子發燒友

    中國電子工程師最喜歡的網站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品
    主站蜘蛛池模板: 91国偷自产一区二区三区 | 欧美性最猛xxxx在线观看视频 | BL文库好大粗黑强强肉NP | 岛国在线无码免费观 | 国产精品爆乳尤物99精品 | 成人在线高清不卡免费视频 | 国产精品亚洲在钱视频 | 国产人在线成免费视频 | 黄 色 网 站 免 费 涩涩屋 | 日韩欧美1区 | 麻豆精品传媒一二三区 | 99久久99久久免费精品蜜桃 | 国精产品一区一区三区有限公司 | 国产精品96久久久久久AV网址 | 亚洲乱妇88网 | 97精品少妇偷拍蜜桃AV | 99精品国产高清自在线看超 | 天美传媒在线完整免费观看网站 | 日韩av国产av欧美天堂社区 | 精品久久伦理中文字幕 | 闺蜜扒开我尿口使劲揉 | 校花被扒衣吸乳羞羞漫画 | 男女又黄又刺激B片免费网站 | 亚洲精品AV一区午夜福利 | 国产麻豆剧看黄在线观看 | 99热久久精品国产一区二区 | 99久久爱re热6在线播放 | 国产久爱青草视频在线观看 | 国产免费久久精品国产传媒 | 456亚洲人成在线播放网站 | china年轻小帅脸直播飞机 | 一个人的免费高清影院 | 欧美一区二区三区久久综 | 色欲久久99精品久久久久久AV | 国精产品砖一区二区三区糖心 | 91精品国产免费入口 | 97超级碰久久久久香蕉人人 | 白百合在线观看 | 久久人人爽人人片AV人成 | 亚洲三区视频 | 中文成人在线 |