ALSA阈值,avail_min和期间有什么区别?

And*_*lez 6 audio alsa audio-recording

我正在四核debian盒子上进行ALSA捕获程序,我很困惑.

基本的ALSA捕获,hw:0接口,16位,44.1 KHz,使用带有poll()的阻塞线程,由snd_pcm_start()和控制snd_pcm_drop().我检查所有ALSA API调用的返回值.基本捕获工作正常,但我无法弄清楚如何设置轮询速率(即,ALSA通知我的poll()例程返回的频率,因为可以读取帧).

我用它snd_pcm_sw_params_set_avail_min()来设置为2048帧,当有大约2048帧可供读取时,poll()返回.我打电话snd_pcm_avail_delay()之前打电话snd_pcm_readi(),这一切看似合理.但如果我将它设置为低于2048的任何值,我会得到不一致的结果.如果我将avail_min设置为1024的一半时间poll()返回时有大约1024帧可用,而有一半时间直到1500帧可用.当我将avail_min设置为512时,第一次读取是512,但随后95%的后续读取是1024帧或更大.当我呼叫snd_pcm_hw_params_get_period_size_min/max()此设备报告有效范围为16-8192帧时,因此512帧的时间段似乎不合理 - 驱动程序报告hw支持它.

我已经试过的每个组合snd_pcm_sw_params_set_avail_min(),snd_pcm_hw_params_set_period_size()snd_pcm_sw_params_set_start_threshold(),但仍不能得到合理的结果.

我已经尝试用pthread setaffinity将这个线程钉到单个CPU核心.我试图sched_setschedule()给这个过程"软"实时优先级.似乎没有什么能让我得到一致的poll()返回,除了将avail_min设置为至少2048.

以下是一些ALSA问题:

  1. 是启动阈值(snd_pcm_sw_params_set_start_threshold()仅与异步捕获相关吗?也就是说,启动阈值似乎不适用于基于poll()的捕获.这是正确的吗?

  2. 帧中的周期大小和帧中的avail_min大小有什么区别?文档似乎暗示avail_min设置poll()将返回的点,因为至少有许多帧可供读取.句点大小是一个hw参数,但API仍然提供最小值和最大值以及设置它的方法.在我看来,他们真的是一样的但我不能让我的poll()根据我设定的时间段返回.

  3. 当我解释snd_pcm_sw_params_set_avail_min()为触发poll()例程设置可用捕获帧的目标数量的意图时,我是否误读了文档?

  4. 对于我来说,期望poll()应该比任何可用于读取的500到1500帧之间的返回更加一致,这是否合理?或者这是正常的行为,我应该期望可供阅读的帧数有很大的变化吗?

  5. 如果预期有很大的变化,最好总是读取报告的总可用帧,snd_pcm_avail()或者每次poll()返回时最好读取一定数量的帧?

CL.*_*CL. 1

启动阈值对于捕获设备来说没有多大意义;只需将其设置为 1 即可。

硬件连续填充捕获缓冲区,但仅在每个周期结束时引发中断。当 ALSA 等待某些数据可用时(在 poll 或 snd_pcm_read* 中),它不会在avail_min 帧可用之前返回。但是,此检查仅在函数开始时或被中断唤醒时进行。

因此,如果您不想等待太久,则必须将周期大小设置得足够短。