核心文件
sound/core/sound.c:alsa driver,用于初始化,注册字符设备等
sound/core/init.c:提供一些card相关的API
sound/core/device.c:提供一些device相关的API
sound/core/pcm.c:初始化pcm相关的设备节点,提供一些pcm相关的API
card相关
数据结构
struct snd_card:alsa声卡结构
int number:声卡编号
char id[16]:声卡的标识名称
void *private_data:保存是有数据
struct list_head devices:记录该声卡下所有逻辑设备的链表(按照类型的数字从小到大排列)
struct list_head controls :记录该声卡下所有的控制单元的链表
关键函数
snd_card_new:创建一个新的声卡结构
snd_card_free:释放一个声卡结构
snd_card_register:注册声卡设备,将其注册到静态结构:static struct snd_card *snd_cards[SNDRV_CARDS];
snd_device_initialize:将设备注册到声卡下
snd_card_file_add:将文件连接到声卡目录下
snd_register_device:将声卡挂载的设备添加到kernel,并且保存到:static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
snd_unregister_device:释放已注册的device
device相关
数据结构
struct snd_device:声卡设备结构体
struct list_head list:用于向snd_card注册
struct snd_card *card:设备所属声卡
enum snd_device_type type:设备类型
void *device_data:私有数据,如snd_pcm
struct snd_device_ops *ops:回调函数,用于注册和释放
关键函数
snd_device_new:将device注册到card的链表
snd_device_register_all:将card的所有所属设备,进行注册(通过device的dev_register)
pcm相关
每个pcm类型的设备,作为一个device挂在到card的device链表;每个pcm设备的stream向内核注册一个device(一般是2个)
数据结构
struct snd_pcm:pcm设备结构
struct snd_card *card:所属声卡
int device:该pcm是声卡下的第几个pcm,第一个pcm设备从0开始
char id[64]:pcm设备的标志名称
struct snd_pcm_str streams[2]:该数组中的两个元素指向两个snd_pcm_str结构,分别代表playback stream和capture stream。snd_pcm_str中的substream字段,指向snd_pcm_substream结构snd_pcm_substream是pcm中间层的核心,绝大部分任务都是在substream中处理,尤其是他的ops(snd_pcm_ops)字段,许多user空间的应用程序通过alsa-lib对驱动程序的请求都是由该结构中的函数处理
struct snd_pcm_hardware:PCM硬件参数结构(播放录音分开),open后保存在runtime->hw
struct snd_pcm_ops:pcm的操作函数集(播放录音分开)。通过snd_pcm_set_ops进行设置
struct snd_pcm_runtime:pcm信息库。保存在substream->runtime,snd_pcm_runtime该substream的一些重要的软件和硬件运行环境和参数
struct snd_pcm_hardware hw:保存pcm硬件参数,open时设置。
unsigned char *dma_area:DMA缓冲区虚拟地址
dma_addr_t dma_addr:DMA缓冲区物理地址,仅当缓冲区是线性缓冲区时才指定此字段
size_t dma_bytes:DMA缓冲区长度,单位字节
struct snd_pcm_mmap_status *status:运行状态。可以通过runtime->status->hw_ptr获取当前的DMA硬件指针。
struct snd_pcm_mmap_control *control:控制状态。DMA 应用程序指针可以通过 runtime->control 引用
void *private_data:指向用户私有数据结构
struct snd_pcm_substream:子流结构体,保存在stream->substream
struct snd_pcm_str:流结构,保存在pcm->streams
关键函数
snd_pcm_new:将pcm注册到card的链表
snd_pcm_new_stream:向pcm设备添加一个stream
snd_pcm_set_ops:设置pcm的操作函数集
callback函数
snd_xxx_open:打开pcm设备回调函数,在打开pcm设备时被调用。函数中会设置substream->hw
snd_xxx_close:关闭pcm设备回调函数,在关闭pcm设备时被调用。
snd_xxx_hw_params:设置pcm硬件参数回调函数,在pcm ioct/prepare等多处被调用
snd_xxx_hw_free:释放pcm硬件参数回调函数,在pcm ioct/close等多处被调用
snd_xxx_prepare:正式开始数据传送之前会调用该函数,该函数通常会完成dma操作的必要准备工作
snd_xxx_trigger:数据传送的开始,暂停,恢复和停止时,该函数会被调用,该函数通常触发DMA
snd_xxx_pointer:该函数返回传送数据的当前位置
中断函数
snd_pcm_period_elapsed:PCM中间层更新指针位置和计算缓冲区可用空间
control相关
数据结构
struct snd_kcontrol_new:创建前用于声明control组件
snd_ctl_elem_iface_t iface:指出了control的类型,alsa定义了几种类型(SNDDRV_CTL_ELEM_IFACE_XXX),常用的类型是MIXER,当然也可以定义属于全局的CARD类型,也可以定义属于某类设备的类型,例如HWDEP,PCMRAWMIDI,TIMER等,这时需要在device和subdevice字段中指出卡的设备逻辑编号
const unsigned char *name:是该control的名字,从ALSA 0.9.x开始,control的名字是变得比较重要,因为control的作用是按名字来归类的
unsigned int index:用于保存该control的在该卡中的编号。如果声卡中有不止一个codec,每个codec中有相同名字的control,这时我们可以通过index来区分这些controls。当index为0时,则可以忽略这种区分策略
unsigned int access:包含了该control的访问类型。每一个bit代表一种访问类型,这些访问类型可以多个“或”运算组合在一起。
unsigned int count:相同control组件的数量
snd_kcontrol_info_t *info:回调函数,获取control信息
snd_kcontrol_get_t *get:回调函数,获取control的值
snd_kcontrol_put_t *put:回调函数,设置control的值
union {
snd_kcontrol_tlv_rw_t *c;
const unsigned int *p;
} tlv:该control提供元数据(metadata)。用于control数值与DB值转换。tlv
unsigned long private_value:包含了一个任意的长整数类型值。该值可以通过info,get,put这几个回调函数访问。你可以自己决定如何使用该字段,例如可以把它拆分成多个位域,又或者是一个指针,指向某一个数据结构。
metadata:用于control数值与DB值转换
DECLARE_TLV_DB_SCALE:第一个参数为名称,第二个参数为最小值,第三个参数为步长,第四个参数为最小时是否mute
DECLARE_TLV_DB_LINEAR:第一个参数为名称,第二个参数为最小值,第三个参数为最大值,第四个参数为最小时是否mute
struct snd_kcontrol:创建后的control组件
关键函数
snd_ctl_new1:创建control组件
snd_ctl_add:将control注册到card
snd_ctl_notify:通知用户层control值发生变化
初始化流程
sound.c
1.注册声卡的字符设备,其他模块通过其为device注册节点文件(snd_register_device)。注册之后的设备保存到static struct snd_minor *snd_minors[SNDRV_OS_MINORS],上层应用调用snd_open时,通过其进行索引并替换对应的ops函数。
2.调用snd_info_init,创建asound目录
pcm.c
1.调用snd_ctl_register_ioctl创建pcm扩展的ioctl 命令
2.调用snd_pcm_proc_init创建proc的pcm节点文件
参考资料