linux学习:音视频编程+alsa声音架构

目录

概念

采样

量化

编码

音频文件wav 格式

标准音频接口 ALSA

录制音频

步骤

api 

获取pcm设备句柄

设置 PCM 设备参数

代码

播放音频

步骤

代码


概念

信号都是模拟信号,不管是声音还是光线,这些模拟信号需要被 A/D 转换器转换成数字信号,才能被存储在计算机中,从概念上讲,可以将 A/D 转换视为三步完成的过程:采样、量化和编码

采样

用采样器每隔一段时间读取一次模拟信号,用这些离散的值来代表整个模拟信号的过程。单位时间内的采样值个数被称为采样频率。常用的采样频率是 11025Hz、22050Hz 和 44100Hz。当然,也可以是其他更高或者更低的频率

量化

对于每次采样得到的值,考虑使用多少个 bit 来存储它。如果使用 8 个 bit (即一个字节)来描述采样值,那么能表达的值的范围是 256,如果使用 16 个 bit 来描述, 范围就被扩展为 65536,描述一个采样值所使用的位数,也被称为分辨率。常用的量化步 长为 8 位、16 位或者 32 位。

编码

脉冲编码 调制就是把一个时间连续,取值连续的模拟信号变换成时间离散,取值离散的数字信号后在 信道中传输。脉冲编码调制就是对模拟信号先抽样,再对样值幅度量化,编码的过程

音频文件wav 格式

wav 是一种符合 RIFF 文档规范的文件格式,这种文档规范是一种以树形结构组织 数据的标准,以 wav 格式为例子,文档必须先包含“RIFF 数据块”,也就是下图左边部分的区域,其中 ID 固定为 RIFF 四个字符,而且是大端序。而 SIZE 是除了 ID 和 SIZE 之外本文档的总大小,FMT 则是 RIFF 规范下 DATA 的具体数据格式,wav 对应的是 WAVE。 剩下的 DATA 就是 RIFF 文档的内容,RIFF 文档的内容又可以由多个“数据块”组成,对于 wav 格式而言,它的组成如下图 中右边部分所示:包含两块,一个是 fmt 块,一个 data 块

标准音频接口 ALSA

安装 ALSA 库

  • 下载最新版alsa源码
  • 解压缩,进入源码目录中并依次执行./configure、make 和 make install
  • 将安装之后的 ALSA 库所在路径(缺省是/usr/lib/i386-Linux-gnu/)添加到环境 变量 LD_LIBRARY_PATH 中
  • 编译音频程序的时候,包含头文件,并且链接 alsa 库: 比如: gcc example.c -o example -lasound
  • 如果要将 ALSA 库安装到基于 ARM 平台的开发板上时,除了第 2 步中的./configure 需要增加指定交叉工具链前缀(例如--host=arm-none-linux-gnueabi)的参数外,还 需要将编译好的 ALSA 库的全部文件放到开发板中,并且保持绝对路径完全一致。

录制音频

步骤

  • 取得 PCM 设备的句柄
    • snd_pcm_t *handle;
  • 设置 PCM 流的方向(录制)
    • snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE;
  • 设置诸如数据 buffer 大小、采样频率、 量化级等
    • snd_pcm_hw_params_t *hwparams;

api 

获取pcm设备句柄

 在 ALSA 中,可以使用 plughw 或者 hw 来代表 PCM 设备接口,使用 plughw 时我们 不需要关心所设置的各种 params 是否被声卡支持,因为如果不支持的话会自动使用默认 的值,如果使用 hw 的话就必须仔细检查声卡硬件的信息,确保设置的每一项都被支持。一 般而言使用 plughw 就可以了,具体而言,使用如下函数获得 PCM 设备句柄

snd_pcm_open(&handle, “plughw:0,0”, stream,0);

0,0 中的第一个 0 是系统中声卡的编号,第二个 0 是设备的 编号,而最后一个 0 代表标准打开模式,除此之外还可以是 SND_PCM_NONBLOCK 或者 SND_PCM_ASYNC,前者代表非阻塞读写 PCM 设备,后者代表声卡系统以异步方式工作: 每当一个周期(period)结束时,将触发一个

设置 PCM 设备参数
  • 首先,给参数配置分配相应的空间,并且根据当前的 PCM 设备的具体情况初始化:
    • snd_pcm_hw_params_t *hwparams;
    • snd_pcm_hw_params_alloca(&hwparams);
    • snd_pcm_hw_params_any(handle, hwparams);
  • 设置访问模式为交错模式,这意味着采样点是帧连续的,而不是通道连续的
    • snd_pcm_hw_params_set_access(handle,SND_PCM_ACCESS_RW_INTERLEAVED);
      • SND_PCM_ACCESS_MMAP_INTERLEAVED:内存映射方式下的交错模式 SND_PCM_ACCESS_MMAP_NONINTERLEAVED:内存映射方式下的非交错模式 SND_PCM_ACCESS_RW_INTERLEAVED:直接 IO 方式下的交错模式 SND_PCM_ACCESS_RW_NONINTERLEAVED:直接 IO 方式下的非交错模
  • 设置量化参数
    • snd_pcm_format_t pcm_format =SND_PCM_FORMAT_S16_LE;
      • SND_PCM_FORMAT_S8 有符号 8 位
        SND_PCM_FORMAT_U8 无符号 8 位
        SND_PCM_FORMAT_S16_LE 有符号 16 位,小端序 SND_PCM_FORMAT_S16_BE 有符号 16 位,大端序 SND_PCM_FORMAT_U16_LE 无符号 16 位,小端序 SND_PCM_FORMAT_U16_BE 无符号 16 位,大端序
        SND_PCM_FORMAT_S24_LE 有符号 24 位,小端序 SND_PCM_FORMAT_S24_BE 有符号 24 位,大端序 SND_PCM_FORMAT_U24_LE 无符号 24 位,小端序 SND_PCM_FORMAT_U24_BE 无符号 24 位,大端序 SND_PCM_FORMAT_S32_LE 有符号 32 位,小端序 SND_PCM_FORMAT_S32_BE 有符号 32 位,大端序 SND_PCM_FORMAT_U32_LE 无符号 32 位,小端序 SND_PCM_FORMAT_U32_BE 无符号 32 位,大端序
    • snd_pcm_hw_params_set_format(handle, hwparams, pcm_format);
  • 设置音轨数目(本例中设置为双音轨,即立体声,1 为单音轨)
    • uint16_t channels = 2;
    • snd_pcm_hw_params_set_channels(handle, hwparams, channels);
  • 设置采样频率,设备所支持的采用频率有规定的数值,本例中以 exact_rate 为基准,设置一个尽量接近该值的频率
    • uint32_t exact_rate = 44100;
    • snd_pcm_hw_params_set_rate_near(handle, hwparams, &exact_rate, 0);
      • 采样频率的设置函数名字为 snd_pcm_h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值