tinyalsa录音功能实现

5 篇文章 0 订阅

tinyalsa录音功能实现,通道转换功能实现,并保存为本地pcm文件,依赖tinyalsa库

1. C++实现

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <stdio.h>
#include "example/tinyalsa/include/tinyalsa/pcm.h"

struct pcm *pcm;
char *pcm_buffer;
char *pcm_buffer_4ch;

unsigned int card =0;      //声卡号
unsigned int device = 0;   //声卡设备
unsigned int flags = PCM_IN //声卡标志
struct pcm_config  config;  //音频配置信息

int pcm_size;
int pcm_size_4ch;
int channel_num = 6;       //通道数
int sample_rate = 16000;   //采样率

FILE *file1;
FILE *file2;

int AudioInit(){
  if (nullptr != pcm) {
    return 0;
  }

  file1 = fopen("1.pcm", "wb");
  if(!file1){
    std::cout << "open file1 failed!" << std::endl;
  }

  file2 = fopen("2.pcm", "wb");
  if(!file2){
    std::cout << "open file2 failed!" << std::endl;
  }

  // alas init
  memset(&config, 0, sizeof(config));
  config.channels = channel_num;
  config.rate = sample_rate;
  config.period_size = 16 * 16;   //16ms * (16000 / 1000)
  config.period_count = 4;        //每次读取4次中断的音频
  config.format = PCM_FORMAT_S32_LE;   //位深为32
  config.start_threshold = 0;
  config.stop_threshold = 0;
  config.silence_threshold = 0;

  // audio init
  pcm = pcm_open(card, device, flags, &config, 0);
  if(NULL == pcm || !pcm_is_ready(pcm)){
    return -1;
  } 

  //buffer_size = period_size * period_count
  int buffer_size = pcm_get_buffer_size(pcm);   
  std::cout << "buffer size is " << buffer_size << std::endl;
  pcm_size = pcm_frames_to_bytes(pcm, buffer_size);
  std::cout << "pcm bytes size is " << pcm_size << std::endl;
  pcm_buffer = reinterpret_cast<char *>(malloc(pcm_size));
  std::cout << "sizeof(pcm_buffer) is " << sizeof(pcm_buffer) << std::endl;

  // 32bit -> 16bit  6ch -> 4ch 
  pcm_size_4ch = pcm_size / 6 / 2 * 4;     
  pcm_buffer_4ch = reinterpret_cast<char *>(malloc(pcm_size_4ch));

  if (NULL == pcm_buffer || NULL == pcm_buffer_4ch) {
    std::cout << "unable to allocate pcm bytes" << std::endl;
    free(pcm_buffer);
    free(pcm_buffer_4ch);
    int ret = pcm_close(pcm);
    return 1;
  }
}

void Ch6_ch4(const char *pcm_buffer, int pcm_size, char *pcm_buffer_4ch){
  //32bit -> 16bit 小端模式取高16位,丢弃低16位 6ch -> 4ch
  for(int i = 0; i < pcm_size / 6 / 4; i++){
    pcm_buffer_4ch[i * 8] = pcm_buffer[i * 24 + 2];
    pcm_buffer_4ch[i * 8 + 1] = pcm_buffer[i * 24 + 3];
    pcm_buffer_4ch[i * 8 + 2] = pcm_buffer[i * 24 + 18];
    pcm_buffer_4ch[i * 8 + 3] = pcm_buffer[i * 24 + 19];
    pcm_buffer_4ch[i * 8 + 4] = 0;
    pcm_buffer_4ch[i * 8 + 5] = 0;
    pcm_buffer_4ch[i * 8 + 6] = 0;
    pcm_buffer_4ch[i * 8 + 7] = 0;
  }
}

void AudioRecord(){
  int frames_read = 0;
  int count = 100; //读取100次,100 * 64ms = 6.4s
  while (count--) {
    // 每次读取64ms
    frames_read = pcm_readi(pcm, pcm_buffer, pcm_get_buffer_size(pcm));
    if (frames_read != pcm_get_buffer_size(pcm)) {
      usleep(64 * 1000);
      continue;
    } 
    fwrite(pcm_buffer, 1, pcm_size, file1);
    Ch6_ch4(pcm_buffer, pcm_size, pcm_buffer_4ch);
    fwrite(pcm_buffer_4ch, 1, pcm_size_4ch, file2);
  }
}

void AudioEnd(){
  free(pcm_buffer);
  free(pcm_buffer_4ch);
  pcm_close(pcm);
  fclose(file1);
  fclose(file2);
}

int main(int argc, char **argv){
  std::cout << "hello lch!" << std::endl;
  AudioInit();
  AudioRecord();
  AudioEnd();
  std::cout << "end lch!" << std::endl;
  return 0;
}

2. CMakelists.txt

include_directories(${PROJECT_SOURCE_DIR})
link_directories(${PROJECT_SOURCE_DIR}/example/tinyalsa/lib)
set(SDK_AUDIO_DEMO_SRC
        ${PROJECT_SOURCE_DIR}/example/audio.cpp)
add_executable(sdk_test_audio ${SDK_AUDIO_DEMO_SRC})
target_link_libraries(sdk_test_audio tinyalsa)

3. 输出结果
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自动驾驶小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值