3. ALSA参数配置与查询
任务目标
编写一个ALSA用户空间程序,完成以下功能:
- 打开默认PCM设备(
default); - 查询当前采样率、通道数、格式等硬件参数;
- 设置目标参数:采样率44100Hz、双通道、
S16_LE格式; - 再次查询并打印设置后的实际参数,验证配置是否生效。
环境与依赖
- Linux系统,内核已启用ALSA驱动;
- 安装ALSA用户态开发库:
sudo apt-get install libasound2-dev(Debian/Ubuntu); - 编译时链接
-lasound。
关键完整代码
#include <stdio.h>
#include <alsa/asoundlib.h>
static void print_hw_params(snd_pcm_t *handle) {
snd_pcm_hw_params_t *hw;
snd_pcm_hw_params_alloca(&hw);
if (snd_pcm_hw_params_current(handle, hw) < 0) {
printf("获取当前硬件参数失败\n");
return;
}
unsigned int rate;
int dir;
snd_pcm_uframes_t period_size, buffer_size;
snd_pcm_format_t format;
unsigned int channels;
snd_pcm_hw_params_get_rate(hw, &rate, &dir);
snd_pcm_hw_params_get_format(hw, &format);
snd_pcm_hw_params_get_channels(hw, &channels);
snd_pcm_hw_params_get_period_size(hw, &period_size, &dir);
snd_pcm_hw_params_get_buffer_size(hw, &buffer_size);
printf("采样率: %u Hz\n", rate);
printf("通道数: %u\n", channels);
printf("格式: %s\n", snd_pcm_format_name(format));
printf("周期大小: %lu 帧\n", (unsigned long)period_size);
printf("缓冲区大小: %lu 帧\n", (unsigned long)buffer_size);
}
int main() {
snd_pcm_t *handle;
int rc;
// 1. 打开PCM设备(播放方向)
rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
fprintf(stderr, "无法打开PCM设备: %s\n", snd_strerror(rc));
return 1;
}
printf("=== 设置前硬件参数 ===\n");
print_hw_params(handle);
// 2. 设置硬件参数
snd_pcm_hw_params_t *hw;
snd_pcm_hw_params_alloca(&hw);
snd_pcm_hw_params_any(handle, hw);
// 设置访问模式为交错模式
snd_pcm_hw_params_set_access(handle, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
// 设置格式为S16_LE
snd_pcm_hw_params_set_format(handle, hw, SND_PCM_FORMAT_S16_LE);
// 设置采样率44100Hz(允许驱动微调)
unsigned int rate = 44100;
int dir = 0;
snd_pcm_hw_params_set_rate_near(handle, hw, &rate, &dir);
// 设置通道数为2
snd_pcm_hw_params_set_channels(handle, hw, 2);
// 将配置写入驱动
rc = snd_pcm_hw_params(handle, hw);
if (rc < 0) {
fprintf(stderr, "设置硬件参数失败: %s\n", snd_strerror(rc));
snd_pcm_close(handle);
return 1;
}
printf("\n=== 设置后硬件参数 ===\n");
print_hw_params(handle);
// 3. 验证设置结果
unsigned int actual_rate;
snd_pcm_hw_params_current(handle, hw);
snd_pcm_hw_params_get_rate(hw, &actual_rate, &dir);
printf("\n请求采样率: 44100 Hz, 实际采样率: %u Hz\n", actual_rate);
if (actual_rate == 44100) {
printf("参数设置成功\n");
} else {
printf("注意: 驱动返回的采样率为 %u Hz(设备可能不支持44100Hz)\n", actual_rate);
}
snd_pcm_close(handle);
return 0;
}
编译与运行
gcc -o alsa_param alsa_param.c -lasound
./alsa_param
验证方法与判定标准
- 编译通过:无错误,生成可执行文件
alsa_param; - 运行输出:程序依次打印设置前、设置后的硬件参数;
- 判定通过条件:设置后的输出中,采样率为44100Hz(或驱动返回的最近值)、通道数为2、格式为
S16_LE;若设备不支持44100Hz,程序会打印实际采样率并提示,此时仍属正常行为——只要设置后的参数与驱动实际能力一致即可判定程序功能正确。
常见问题
- 打开设备失败:确认声卡驱动已加载,且当前用户有权限访问
/dev/snd/*;可尝试sudo ./alsa_param。 - 设置采样率失败:部分USB声卡或板载声卡不支持44100Hz,改用
snd_pcm_hw_params_set_rate_near后驱动会返回最接近的可用值,程序会打印实际值。 - 格式名称显示为
Unknown:说明驱动返回了非标准格式,可检查声卡实际能力(cat /proc/asound/card0/pcm0p/sub0/hw_params)。