title: snd-dummy 虚拟声卡驱动分析date: 2026-04-29tags:ALSALinux驱动音频studyaliases:snd-dummy driverdummy soundcardsnd-dummy 虚拟声卡驱动分析[!info] 概述sound/drivers/dummy.c是 Linux ALSA 虚拟声卡驱动用于测试和开发目的。它不连接任何真实硬件而是模拟一个完整声卡的行为。基本信息属性值作者Jaroslav Kysela (perexperex.cz)LicenseGPL用途声卡驱动开发测试的假设备源码路径kernel/sound/drivers/dummy.c核心数据结构snd_dummy 声卡主结构structsnd_dummy{structsnd_card*card;// ALSA 声卡structdummy_model*model;// 声卡模型(可选)structsnd_pcm*pcm;// PCM 设备structsnd_pcm_hardwarepcm_hw;// PCM 硬件能力描述spinlock_tmixer_lock;// 混音器锁intmixer_volume[5][2];// 5个声源的音量(左/右)intcapture_source[5][2];// 5个声源的录制开关intiobox;// I/O Box 状态structsnd_kcontrol*cd_volume_ctl;structsnd_kcontrol*cd_switch_ctl;};PCM 定时器操作抽象这是一个策略模式支持两种定时器实现structdummy_timer_ops{int(*create)(structsnd_pcm_substream*);void(*free)(structsnd_pcm_substream*);int(*prepare)(structsnd_pcm_substream*);int(*start)(structsnd_pcm_substream*);int(*stop)(structsnd_pcm_substream*);snd_pcm_uframes_t(*pointer)(structsnd_pcm_substream*);};定时器实现系统定时器 (dummy_systimer_*)使用 Linux 内核的jiffies定时器 (L:235-364)精度较低但兼容性好frac_pos用分数记录采样位置通过mod_timer周期性触发staticvoiddummy_systimer_rearm(structdummy_systimer_pcm*dpcm){mod_timer(dpcm-timer,jiffies(dpcm-frac_period_restdpcm-rate-1)/dpcm-rate);}高精度定时器 (dummy_hrtimer_*)使用hrtimer(L:371-488)当CONFIG_HIGH_RES_TIMERSy时启用更高精度使用ktime_t计算时间差atomic_t running标志控制运行状态staticintdummy_hrtimer_start(structsnd_pcm_substream*substream){structdummy_hrtimer_pcm*dpcmsubstream-runtime-private_data;dpcm-base_timehrtimer_cb_get_time(dpcm-timer);hrtimer_start(dpcm-timer,dpcm-period_time,HRTIMER_MODE_REL_SOFT);atomic_set(dpcm-running,1);return0;}PCM 接口实现PCM opsstaticstructsnd_pcm_opsdummy_pcm_ops{.opendummy_pcm_open,.closedummy_pcm_close,.ioctlsnd_pcm_lib_ioctl,.hw_paramsdummy_pcm_hw_params,.hw_freedummy_pcm_hw_free,.preparedummy_pcm_prepare,.triggerdummy_pcm_trigger,.pointerdummy_pcm_pointer,};关键函数函数位置作用dummy_pcm_openL:557打开PCM初始化定时器dummy_pcm_triggerL:496处理 START/STOP 命令dummy_pcm_pointerL:514返回当前播放位置dummy_pcm_copyL:642空操作不实际处理数据dummy_pcm_pageL:663返回固定页面用于 mmapfake_buffer 模式当fake_buffer1时 (L:611-640)[!tip] fake_buffer 特点不分配真实 DMA 缓冲区copy_user/copy_kernel/fill_silence都是空操作只设置dma_bytes以支持 mmap节省内存适合不需要真实音频数据的测试MIXER 混音器接口控制元素定义定义了多种混音器控件 (L:878-896)DUMMY_VOLUME(Master Volume,0,MIXER_ADDR_MASTER),// 主音量DUMMY_CAPSRC(Master Capture Switch,0,MIXER_ADDR_MASTER),// 主录制开关DUMMY_VOLUME(Synth Volume,0,MIXER_ADDR_SYNTH),// 合成器音量DUMMY_VOLUME(Line Volume,0,MIXER_ADDR_LINE),// 线路输入音量DUMMY_VOLUME(Mic Volume,0,MIXER_ADDR_MIC),// 麦克风音量DUMMY_VOLUME(CD Volume,0,MIXER_ADDR_CD),// CD 音量音量范围uinfo-value.integer.min-50;// -45 dBuinfo-value.integer.max100;// 30 dB (0正常音量)声卡模型可选的预配置模型用于模拟特定声卡 (L:148-229)模型特点emu10k1128KB buffer, 整数 period 约束rme965226通道, S32_LE 格式ice171210通道, 256KB bufferuda13412通道, S16_LE, 固定16380字节 bufferac972通道, 48kHz 固定采样率ca0106支持 48k/96k/192kHz 采样率模块参数可通过modprobe或启动参数设置 (L:61-92)# 加载时指定参数modprobe snd-dummyenable1index0pcm_devs2pcm_substreams8参数默认值说明index0-MAX声卡索引enable1, others0是否启用pcm_devs1PCM 设备数量 (0-4)pcm_substreams8每个 PCM 的子流数量 (1-128)fake_buffer1是否使用假缓冲区hrtimer1 (if HIGH_RES_TIMERS)使用高精度定时器procfs 调试接口在/proc/asound/cardX/dummy_pcm提供运行时信息 (L:923-1051)格式 (formats)采样率范围 (rate_min/max)通道数 (channels_min/max)缓冲区大小约束[!warning] 可写调试接口可通过写入修改这些参数进行测试这仅用于调试目的。驱动初始化流程module_init(alsa_card_dummy_init) │ ├─ platform_driver_register() // 注册平台驱动 ├─ alloc_fake_buffer() // 分配假缓冲区页面 │ └─ 遍历 SNDRV_CARDS 设备 └─ platform_device_register_simple() └─ snd_dummy_probe() ├─ snd_card_new() // 创建声卡 ├─ snd_card_dummy_pcm() // 创建 PCM ├─ snd_card_dummy_new_mixer() // 创建混音器 ├─ snd_card_register() // 注册声卡 └─ platform_set_drvdata() // 保存私有数据应用场景ALSA 应用开发测试- 不需要真实声卡即可测试驱动开发调试- 作为参考实现自动化测试- CI/CD 中生成虚拟声卡进行测试音频框架学习- 完整的 PCM Mixer Timer 实现参考设备节点加载后在/dev/snd/下可见pcmC0D0p // 第一个声卡的第一个 PCM 播放设备 (playback) pcmC0D0c // 第一个声卡的第一个 PCM 录制设备 (capture) controlC0 // 第一个声卡的混音控制设备学习要点[!abstract] 总结这个驱动是学习 ALSA 驱动开发的绝佳参考代码结构清晰涵盖了 ASoC 三大组件Platform Driver- 定时器实现Codec- 虚拟混音器Machine- 声卡注册相关资料[[Linux Audio Driver Training]][[ALSA_ASoC_插孔驱动学习笔记]]ALSA Project Homepage本文档由 Claude Code 分析生成