linux alsa 不创建声卡能否创建pcm设备,Android音频(1)——ALSA声卡驱动

水铭晨
2023-12-01

一、ALSA基础知识

1. ALSA(Advanced Linux Sound Architecture)目前已经成为了linux的主流音频体系结构,ALSA开源项目网址:http://www.alsa-project.org/。

另一个音频驱动框架是OSS(open sound system),收费,已经废弃。

2.在内核设备驱动层,ALSA提供了alsa-driver,同时在应用层,ALSA提供了alsa-lib,应用程序只要调用alsa-lib提供的API,即可以完成对底层音频硬件的控制。

3.PCM(Pulse-code modulation)是脉冲编码调制,PCM信号的两个重要指标是采样频率和量化精度,目前,CD音频的采样频率通常为44100Hz,量化精度是16bit。

播放音乐时,应用程序从存储介质中读取音频数据(MP3、WMA、AAC...),经过解码后,最终送到音频驱动程序中的就是PCM数据;在录音时,音频驱动不停地把采样所得的PCM数据送回给应用程序,由应用程序完成压缩、存储等任务。所以,音频驱动的两大核心任务就是:

playback:如何把用户空间的应用程序发过来的PCM数据,转化为人耳可以辨别的模拟音频

capture:把mic拾取到得模拟信号,经过采样、量化,转换为PCM信号送回给用户空间的应用程序

4.采集两路数据称为双通道,wav格式的文件就是原始的采集声音数据的文件,压缩后可为mp3文件。

5.音频驱动入口文件(注册主设备号的文件)

alsa_sound_init //sound\core\sound.c

register_chrdev(116, "alsa", &snd_fops) //snd_fops中只有open()

音频系统创建的所有设备文件都以struct snd_minor的形式存储在全局数据snd_minors[]中,snd_fops.open()根据次设备号起中转功能。

6.ALSA发展历程:ALSA ---> ASoC --->DAPM,ASoC和DAPM将在后续博客讲。

7.相关概念

HiFi:High-Fidelity的缩写,翻译为“高保真”,其定义是:与原来的声音高度相似的重放声音。

PCM: Pulse-code modulation,中文译名是脉冲编码调制。

DAI: Digital Audio Interface

MIDI:Music Instrument Digital Interface

二、Control设备的创建

1. Control接口主要让用户空间的应用程序(alsa-lib)可以访问和控制音频codec芯片中的多路开关,滑动控件等。对于Mixer(混音)来说,Control接口显得尤为重要,从ALSA 0.9.x版本开始,所有的mixer工作都是通过control接口的API来实现的。使用snd_kcontrol_new结构来定义一个Control项,根据codec的芯片手册进行构造snd_kcontrol_new。

2.设置cidec配置的统一的接口就是snd_kcontrol,一个snd_kcontrol表示一个功能(可能是一个寄存器的某些位),每个sndkcontrol中有自己的读写函数。一个声卡有多个kcontrol,一个kcontrol对应一个功能,比如:音量,开关录音。kcontrol中有函数来设置功能。snd_kcontrol对应的是功能,其寄存器配置由codec驱动负责。

3.kcontrol创建过程示例

struct snd_kcontrol_new wm8960_snd_controls[] //wm8960.c

snd_soc_add_controls(codec, wm8960_snd_controls, ARRAY_SIZE(wm8960_snd_controls));

snd_ctl_add(card, snd_soc_cnew(control, codec, control->name, codec->name_prefix));//将snd_kcontrol_new结构转换成snd_kcontrol结构

snd_soc_cnew(control, codec, control->name, codec->name_prefix)//获取一个snd_kcontrol结构

kcontrol = snd_ctl_new1(&template, data);//然后将这些snd_kcontrol结构串接在snd_card.controls域中。

list_add_tail(&kcontrol->list, &card->controls);

二、声卡的创建

1. 使用struct snd_card表示,其是一个父设备,下面挂载着control pcm节点分别使用snd_device结构表示。snd_card可以说是整个ALSA音频驱动最顶层的一个结构,整个声卡的软件逻辑结构开始于该结构,几乎所有与声音相关的逻辑设备都是在snd_card的管理之下,声卡驱动的第一个动作通常就是创建一个snd_card结构体。

2. 声卡的创建过程

snd_card_create //sound/core/init.c//创建声卡的控制接口

snd_ctl_create(card); //sound/core/control.c//在声卡注册的时候会调用所有组件的dev_register回调来创建对应的设备节点:

snd_card_register(struct snd_card *card);//sound/core/init.c

snd_device_register_all(card)

list_for_each_entry(dev,&card->devices, list)

dev->ops->dev_register(dev) //注册所有的属于此Card的设备节点//对应control节点

snd_device_ops.dev_register =snd_ctl_dev_register,

snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,&snd_ctl_f_ops, /*name=*/"controlC0")//对应pcm节点

.dev_register =snd_pcm_dev_register,

snd_register_device_for_dev(&snd_pcm_f_ops[0:p/1:c]);

声卡设备/dev/snd/controlCX的file_operations是snd_ctl_f_ops//sound/core/control.c

声卡设备/dev/snd/pcmCXDXp的file_operations是snd_pcm_f_ops[0], /dev/snd/pcmCXDXc的file_operations是snd_pcm_f_ops[1] //pcm_native.c

4. 一个pcm就是一个逻辑device,它里面有两个通道,一个是playback通道,对应/dev/pcmC0D0p节点,另一个是capture通道,对应/dev/pcmC0D0c节点.

5. 创建声卡的功能部件(逻辑设备),例如PCM,Mixer,MIDI等的函数如下

PCM —— snd_pcm_new()

snd_device_new(card, SNDRV_DEV_PCM, pcm,&ops)

RAWMIDI —— snd_rawmidi_new()

snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi,&ops)

CONTROL —— snd_ctl_create()

snd_device_new(card, SNDRV_DEV_CONTROL, card,&ops);

TIMER —— snd_timer_new()

snd_device_new(card, SNDRV_DEV_TIMER, timer,&ops);

INFO —— snd_card_proc_new()

snd_device_new(card, SNDRV_DEV_INFO, entry,&ops)

JACK —— snd_jack_new()

snd_device_new(card, SNDRV_DEV_JACK, jack,&ops);

参考:

Linux ALSA声卡驱动之一:ALSA架构简介:https://blog.csdn.net/DroidPhone/article/details/6271122

Linux ALSA声卡驱动之二:声卡的创建:https://blog.csdn.net/droidphone/article/details/6289712

Linux ALSA声卡驱动之三:PCM设备的创建:https://blog.csdn.net/droidphone/article/details/6308006

Linux ALSA声卡驱动之四:Control设备的创建 :https://blog.csdn.net/gjy938815/article/details/9209457

 类似资料: