RV1126 音频开发(1)

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;

音频输入属性结构体

  • pcAudioNode//音频设备节点路径

  • 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为结尾的都是interleaved结构,以P为结尾的是planar结构

    • Planar模式是FFmpeg内部存储模式,我们实际使用的音频文件都是Packed模式的。

    • AAC解码输出的数据为浮点型的 RK_SAMPLE_FMT_FLTP格式

    • MP3解码输出的数据为 RK_SAMPLE_FMT_S16P格式(使用的mp3文件为16位深)

  • u32NbSamples

    • 每帧的采样点个数
    • 通常一帧是按1024个采样点
  • u32SampleRate

    • 采样率
    • 就是每秒对声音进行采集的次数,同样也是所得的数字信号的每秒样本数;44,100 Hz - 音频 CD, 也常用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率
  • u32Channels

    • 通道数
    • 单通道、双声道、四声道、5.1声道
  • enAiLayout

    • 输入布局类型

通过RK_MPI_AI_SetChnAttr设置音频输入通道属性 ,然后RK_MPI_AI_EnableChn打开通道0

pthread_create创建线程去获取数据流并保存

接着通过RK_MPI_AI_StartStream启动音频流

流程:

  • 设置音频输入通道属性
  • 打开通道
  • 启动音频流
  • 创建线程去获取数据流并保存

获取数据流线程中通过从指定通道中获取数据 然后fwrite往输出音频文件中写数据,最后关闭文件

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值