ARM&Linux基础
+ -

tinyalsa函数大全

2025-12-04 8 0

1. 设备管理

  • pcm_open:打开PCM设备
  • pcm_close:关闭PCM设备
  • pcm_is_ready:设备是否打开
struct pcm {
    int fd;
    unsigned int flags;
    int running:1;
    int prepared:1;
    int underruns;
    unsigned int buffer_size;
    unsigned int boundary;
    char error[PCM_ERROR_MAX];
    struct pcm_config config;
    struct snd_pcm_mmap_status *mmap_status;
    struct snd_pcm_mmap_control *mmap_control;
    struct snd_pcm_sync_ptr *sync_ptr;
    void *mmap_buffer;
    unsigned int noirq_frames_per_msec;
    int wait_for_avail_min;
    unsigned int subdevice;

    struct pcm_ops *ops;
    void *data;
    void *snd_node;
};

2. 状态控制

  • pcm_start:启动PCM设备开始数据传输
  • pcm_stop:停止PCM设备的数据传输
  • pcm_state:获取PCM设备的当前状态,PCM_STATE_XRUN,PCM_STATE_SUSPENDED,PCM_STATE_DISCONNECTED
    • pcm_prepare:准备PCM设备进行数据传输,pcm_write和pcm_start会内部调用。
#define SAMPLE_RATE     48000   // 采样率
#define CHANNELS        2       // 通道数
#define FORMAT          PCM_FORMAT_S16_LE  // 16位小端
#define PERIOD_SIZE     1024    // 每周期帧数
#define PERIOD_COUNT    4       // 周期数量

struct pcm_config config;
    memset(&config, 0, sizeof(config));
    config.channels = CHANNELS;           // 2通道
    config.rate = SAMPLE_RATE;            // 48kHz 采样率
    config.format = FORMAT;               // 16位小端
    config.period_size = PERIOD_SIZE;     // 每个周期1024帧
    config.period_count = PERIOD_COUNT;   // 4个周期
    config.start_threshold = 0;           // 立即开始录制
    config.stop_threshold = 0;            // 不自动停止
    config.silence_threshold = 0;         // 不填充静音

 alsaPcm = pcm_open(CardIndex, DeviceIndex, PCM_IN, &config);
  • start_threshold:通常为多少帧开始(当缓冲区中积累了多少数据后才开始播放),何时开始播放/录制,值可以为 config.period_size;或config.period_size * config.period_count / 2;
  • stop_threshold:当缓冲区中剩余多少数据时停止播放
  • silence_threshold:早期音频系统的遗留参数,现代音频系统基本不用。
  • period_size = 每个集装箱的容量(一次搬运多少货物)
  • period_count = 流水线上同时运行的集装箱数量
    ┌─────────────────────────────────────────┐
    │         音频环形缓冲区 (Ring Buffer)     │
    ├─────────────────────────────────────────┤
    │  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
    │  │ 周期 #1 │  │ 周期 #2 │   │ 周期 #3 │  │
    │  │  1024帧 │  │  1024帧 │  │  1024帧  │  │ ← period_count=3
    │  └─────────┘  └─────────┘  └─────────┘  │
    ├─────────────────────────────────────────┤
    │ 读指针 → 正在处理这个周期                 │
    │ 写指针 → 正在填充这个周期                 │
    └─────────────────────────────────────────┘
    
  • period_count=2:激进模式,最低延迟 最小内存 最高风险(易xrun)
  • period_count=4:平衡模式(推荐默认值) 良好的稳定性 适中的内存
  • period_count≥8:保守模式 高延迟 高稳定性 大内存占用
对延迟的影响

// 计算公式
单周期延迟 = period_size / sample_rate
总缓冲延迟 = period_size × period_count / sample_rate

// 示例:48kHz,period_size=1024
单周期延迟 = 1024 / 48000 = 21.3ms

不同 period_count 的总延迟:
period_count=2 → 42.7ms
period_count=4 → 85.3ms ← 常用配置
period_count=8 → 170.7ms

3. 数据传输(普通模式)

  • pcm_write:向PCM设备写入音频数据:向PCM设备写入音频数据
  • pcm_read:从PCM设备读取音频数据。如未启动,自动调用pcm_start

4. 数据传输(MMAP模式)

  • pcm_mmap_write:用内存映射方式写入音频数据,封装pcm_mmap_transfer
  • pcm_mmap_read:使用内存映射方式读取音频数据,封装pcm_mmap_transfer
    • pcm_mmap_transfer/pcm_mmap_begin:开始内存映射传输操作
    • pcm_mmap_transfer/pcm_mmap_commit:提交内存映射传输的数据

5. 信息查询

  • pcm_get_buffer_size:获取PCM缓冲区大小(帧数)
  • pcm_get_error:获取最近一次的错误信息
  • pcm_get_htimestamp:获取高精度时间戳和可用帧数

6. 参数管理

  • pcm_params_get:获取PCM设备的参数能力
  • pcm_params_free:释放PCM参数结构体
  • pcm_params_get_min:获取参数的最小值
  • pcm_params_get_max:获取参数的最大值

7. 等待和同步

  • pcm_wait:等待PCM设备可用的数据空间。写数据等待可用的数据空间。
  • pcm_get_poll_fd:获取用于poll的文件描述符

8. 格式转换

  • pcm_format_to_bits, pcm_frames_to_bytes, pcm_bytes_to_frames

0 篇笔记 写笔记

/proc/asound/pcm 是什么?
ALSA 有其自己的 proc 树,即 /proc/asound。每张声卡都有其子树 cardX,其中 X 的范围是 0 到 7。声卡特定的文件存储在 card* 子目录中。详解见:https://docs.linuxkernel.org.cn/sound/designs/procfile.html......
tinyalsa函数大全
1. 设备管理pcm_open:打开PCM设备pcm_close:关闭PCM设备pcm_is_ready:设备是否打开struct pcm { int fd; unsigned int flags; int running:1; int prepared:1; ......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!