AI_CHN_ATTR_S ai_attr;
ai_attr.pcAudioNode = pDeviceName;
ai_attr.enSampleFormat = RK_SAMPLE_FMT_S16;
ai_attr.u32NbSamples = u32FrameCnt;
ai_attr.u32SampleRate = u32SampleRate;
ai_attr.u32Channels = u32ChnCnt;
ai_attr.enAiLayout = AI_LAYOUT_NORMAL;
音頻輸入屬性結(jié)構(gòu)體
-
pcAudioNode//音頻設(shè)備節(jié)點(diǎn)路徑
-
enSampleFormat
-
采樣格式
-
typedef enum rkSample_Format_E { RK_SAMPLE_FMT_NONE = -1, RK_SAMPLE_FMT_U8, RK_SAMPLE_FMT_S16, RK_SAMPLE_FMT_S32, RK_SAMPLE_FMT_FLT, RK_SAMPLE_FMT_U8P, RK_SAMPLE_FMT_S16P, RK_SAMPLE_FMT_S32P, RK_SAMPLE_FMT_FLTP, RK_SAMPLE_FMT_G711A, RK_SAMPLE_FMT_G711U, RK_SAMPLE_FMT_NB } Sample_Format_E;
-
不以P為結(jié)尾的都是interleaved結(jié)構(gòu),以P為結(jié)尾的是planar結(jié)構(gòu)
-
Planar模式是FFmpeg內(nèi)部存儲模式,我們實(shí)際使用的音頻文件都是Packed模式的。
-
AAC解碼輸出的數(shù)據(jù)為浮點(diǎn)型的 RK_SAMPLE_FMT_FLTP格式
-
MP3解碼輸出的數(shù)據(jù)為 RK_SAMPLE_FMT_S16P格式(使用的mp3文件為16位深)
-
-
u32NbSamples
- 每幀的采樣點(diǎn)個數(shù)
- 通常一幀是按1024個采樣點(diǎn)
-
u32SampleRate
- 采樣率
- 就是每秒對聲音進(jìn)行采集的次數(shù),同樣也是所得的數(shù)字信號的每秒樣本數(shù);44,100 Hz - 音頻 CD, 也常用于 MPEG-1 音頻(VCD, SVCD, MP3)所用采樣率
-
u32Channels
- 通道數(shù)
- 單通道、雙聲道、四聲道、5.1聲道
-
enAiLayout
- 輸入布局類型
通過RK_MPI_AI_SetChnAttr設(shè)置音頻輸入通道屬性 ,然后RK_MPI_AI_EnableChn打開通道0
pthread_create創(chuàng)建線程去獲取數(shù)據(jù)流并保存
接著通過RK_MPI_AI_StartStream啟動音頻流
流程:文章來源:http://www.zghlxwxcb.cn/news/detail-436150.html
- 設(shè)置音頻輸入通道屬性
- 打開通道
- 啟動音頻流
- 創(chuàng)建線程去獲取數(shù)據(jù)流并保存
獲取數(shù)據(jù)流線程中通過從指定通道中獲取數(shù)據(jù) 然后fwrite往輸出音頻文件中寫數(shù)據(jù),最后關(guān)閉文件文章來源地址http://www.zghlxwxcb.cn/news/detail-436150.html
#include <assert.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "rkmedia_api.h"
static bool quit = false;
static void sigterm_handler(int sig) {
fprintf(stderr, "signal %d\n", sig);
quit = true;
}
static void *GetMediaBuffer(void *path) {
char *save_path = (char *)path;
printf("#Start %s thread, arg:%s\n", __func__, save_path);
FILE *save_file = fopen(save_path, "w");
if (!save_file)
printf("ERROR: Open %s failed!\n", save_path);
MEDIA_BUFFER mb = NULL;
int cnt = 0;
while (!quit) {
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_AI, 0, -1);
if (!mb) {
printf("RK_MPI_SYS_GetMediaBuffer get null buffer!\n");
break;
}
printf("#%d Get Frame:ptr:%p, size:%zu, mode:%d, channel:%d, "
"timestamp:%lld\n",
cnt++, RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb),
RK_MPI_MB_GetModeID(mb), RK_MPI_MB_GetChannelID(mb),
RK_MPI_MB_GetTimestamp(mb));
if (save_file)
fwrite(RK_MPI_MB_GetPtr(mb), 1, RK_MPI_MB_GetSize(mb), save_file);
RK_MPI_MB_ReleaseBuffer(mb);
}
if (save_file)
fclose(save_file);
return NULL;
}
int main(int argc, char *argv[]) {
RK_U32 u32SampleRate = 44100;
RK_U32 u32ChnCnt = 1;
RK_U32 u32FrameCnt = 1024;
RK_S32 s32Volume = 100;
// default:CARD=rockchiprk809co
RK_CHAR *pDeviceName = "default";
RK_CHAR *pOutPath = "/mnt/nfs/ai.pcm";
int c;
int ret = 0;
printf("#Device: %s\n", pDeviceName);
printf("#SampleRate: %u\n", u32SampleRate);
printf("#Channel Count: %u\n", u32ChnCnt);
printf("#Frame Count: %u\n", u32FrameCnt);
printf("#Volume: %d\n", s32Volume);
printf("#Output Path: %s\n", pOutPath);
RK_MPI_SYS_Init();
AI_CHN_ATTR_S ai_attr;
ai_attr.pcAudioNode = pDeviceName;
ai_attr.enSampleFormat = RK_SAMPLE_FMT_S16;
ai_attr.u32NbSamples = u32FrameCnt;
ai_attr.u32SampleRate = u32SampleRate;
ai_attr.u32Channels = u32ChnCnt;
ai_attr.enAiLayout = AI_LAYOUT_NORMAL;
ret = RK_MPI_AI_SetChnAttr(0, &ai_attr);
ret |= RK_MPI_AI_EnableChn(0);
if (ret) {
printf("Enable AI[0] failed! ret=%d\n", ret);
return -1;
}
pthread_t read_thread;
pthread_create(&read_thread, NULL, GetMediaBuffer, pOutPath);
ret = RK_MPI_AI_StartStream(0);
if (ret) {
printf("Start AI failed! ret=%d\n", ret);
return -1;
}
printf("%s initial finish\n", __func__);
signal(SIGINT, sigterm_handler);
while (!quit) {
usleep(500000);
}
printf("%s exit!\n", __func__);
RK_MPI_AI_DisableChn(0);
return 0;
}
到了這里,關(guān)于RV1126 音頻開發(fā)(1)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!