ALSA 和 SOC+codec 整体架构

一、简介

整个Alsa体系分为用户空间和内核空间两部分,实现了很多强大的功能。从驱动开发的角度来看,基本只需要把注意力集中在跟硬件相关的部分就可以了。其它内容是Alsa体系维护者的事情。

在内核中,Alsa为不同的类型的硬件分别提供了不同的封装形式,这里仅介绍主框架(不同类型硬件的实现就是对主框架的封装)和SOC框架。

二、主框架

1、基本概念

  • 帧(frame):全部声道采样一次所得到的数据。以16位立体声来说,一帧的大小是2(声道) * 16(位/采样点) / 8(位/字节)=  4 (字节)。
  • 片断(period):数据块,一般对应于一次中断所处理的数据。
  • 子码流(snd_pcm_substream):通常对应回放(playback)或录音(record)。
  • 码流(snd_pcm):可以包含很多子码流,但通常只是一个回放,一个录音。
  • 控制(snd_kcontrol):通常用于音量调整等作用。
  • 声卡(snd_card): 等同于硬件声卡的概念,它包含了码流及控制方面的信息。
  • 回调函数(snd_pcm_ops):一个子码流在运行过程中所需要进行处理。
  • 运行时参数(snd_pcm_runtime):保存运行过程中(指hw_params回调和hw_free回调之间)中的相关参数,如缓冲区(包括大小,位置,帧大小,片断大小)、通道数,采样精度,采样频率等。
  • 硬件能力参数(snd_pcm_hardware):子码流硬件能力方面的相关参数,如所能支持的采样频率、采样精度,通道数量,缓冲大小等。

 

2、初始化

(1)、创建一块声卡(snd_card),调用snd_card_new,然后向该声卡中添加相关的码流和控制。

(2)、添加码流(snd_pcm),调用snd_pcm_new,注册码流回调函数(snd_pcm_ops)(回放和录音的回调函数是分别注册的),为码流预分配缓冲区,可以使用snd_pcm_lib_preallocate_pages_for_all,该函数会为所有子码流独立预分配缓冲区。

(3)、添加控制,就是调用snd_ctl_add注册snd_kcontrol_new数据结构。

(4)、注册该声卡,调用snd_card_register,成功后,该声卡的alsa驱动就可用了。

(5)、卸载声卡时,调用snd_card_free,alsa会自动删除码流(snd_pcm),控制(snd_kcontrol)和声卡(snd_card)。

 

3、运行

在运行过程中,Alsa会调用码流中注册的回调函数,这些回调函数使用的主要参数是子码流(snd_pcm_substream),及运行时参数(snd_pcm_runtime)。

可以通过substream->stream的值来区分是回放还是录音。

除pointer回调外,其它回调都是通过返回0表示成功,非0表示失败。

中断服务程序需要调用snd_pcm_period_elapsed函数,其作用相当于通知缓冲区空闲(对应回放)或者有效(对应录音)。

 

(1)、打开子码码流,对应回调函数中的open。该函数最主要的工作向运行时参数(snd_pcm_runtime)提供该子码流的硬件能力(snd_pcm_hardware),比如所能支持的采样率,采样精度等,通道数,缓冲区大小等。

(2)、设置参数,对应回调函数中的hw_params,在该函数内,所有目标参数如采样率、采样精度,通道数,缓冲区总大小等都有效,要求按照这些参数来配置硬件,分配缓冲区(当然也可以只记录下相关硬件参数,等到perpare时才进行实际配置,但其实没有必要)。实际缓冲区分配可以调用snd_pcm_lib_malloc_pages函数。在该函数被调用之后,运行时配置(snd_pcm_runtime)中的相关参数值才有效。

(3)、运行前准备,对应回调函数中的prepare,意味着该函数调用后,所有设置都已经就绪。

(4)、启动、停止,对应回调函数trigger,该函数的命令参数(cmd)表明是启动、停止、暂停、挂起还是恢复等。

(5)、读写位置反馈,对回调函数pointer,该函数返回数据的当前读取位置(对应回放)或数据的当前写入位置(对应录音),该位置是反复回绕的(环形缓冲区的用法)。

(6)、停止后清理,对应回调函数hw_free,在该函数中可以释放分配的缓冲区,可以调用snd_pcm_lib_free_pages函数。

(7)、关闭,对应回调函数close。

补充:

(8)、ioctl回调,目前的alsa版本(1.0.18a),要求必须给该回调赋值,其值可以使用snd_pcm_lib_ioctl函数。

(9)、ack回调,当alsa把数据写入缓冲区或从缓冲区读走后,会回调该函数,用于特殊的维护操作。

 

4、说明

(1)、正常的回调流程:

其中pointer会在start和stop之间被反复调用。

解释:用户通过open打开子码流并获得该子码流的能力参数,从而确定出一套可用的参数。调用hw_params设置这些参数。调用prepare进球最后的准备工作,比如清除fifo。调用trigger启动或停止工作。通过pointer了解工作进展。工作停止后,调用hw_free释放资源,使用close关闭子码流。

(2)、目前的android会出现open --> hw_free --> close过程,用于处理音量设置等控制(因此在hw_freek 需要检查所需释放的资源是否有效)。

(3)、在alsa体系内,数据的度量单位基本都是帧(frame)。

(4)、硬件实际操作可以灵活地嵌在相关步骤中。

 

三、SOC框架

这种框架主要用于I2S接口,其特点是两个独立的芯片通过传输总线连接起来构成音频系统,一端称为CPU端,负责发送和接收数字信号,另一端称为CODEC端,负责AD或DA转换,该框架的主要目的是使两端相互独立。

1、基本概念

数字音频接口(snd_soc_dai):用于描述CPU端或CODEC端的硬件能力。在运行过程中,SOC框架会综合两端的硬件能力,生成两端都可接收硬件能力参数(snd_pcm_hardware)。

音频接口连接(snd_soc_dai_link):通过该数据结构,可以描述两端的实际硬件连接。即哪个CPU端跟哪个CODEC端连在一起。

平台(snd_soc_platform):这个数据结构跟alsa框架中的码流(snd_pcm)对应,主要字义了相关的回调函数。

卡片(snd_soc_card):该结构可能是SOC中声卡的概念吧,这里译为卡片。该结构包含了音频接口连接(snd_soc_dai_link)和平台(snd_soc_platform)。

设备(snd_soc_device):该数据结构包含卡片(snd_soc_card),codec设备(snd_soc_codec_device),以及设备配置数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值