ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:37.78KB ,
资源ID:10701125      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-10701125.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Linux ALSA声卡驱动之四Control设备的创建.docx)为本站会员(b****3)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

Linux ALSA声卡驱动之四Control设备的创建.docx

1、Linux ALSA声卡驱动之四Control设备的创建Linux ALSA声卡驱动之四:Control设备的创建Control接口 Control接口主要让用户空间的应用程序(alsa-lib)可以访问和控制音频codec芯片中的多路开关,滑动控件等。对于Mixer(混 音)来说,Control接口显得尤为重要,从ALSA 0.9.x版本开始,所有的mixer工作都是通过control接口的API来实现的。ALSA已经为AC97定义了完整的控制接口模型,如果你的Codec芯片只支持AC97接口,你可以不用关心本节的内容。定义了所有的Control API。如果你要为你的codec实现自己的c

2、ontrols,请在代码中包含该头文件。Controls的定义 要自定义一个Control,我们首先要定义3各回调函数:info,get和put。然后,定义一个snd_kcontrol_new结构:c-sharp view plaincopy1. staticstructsnd_kcontrol_newmy_control_devinitdata=2. .iface=SNDRV_CTL_ELEM_IFACE_MIXER,3. .name=PCMPlaybackSwitch,4. .index=0,5. .access=SNDRV_CTL_ELEM_ACCESS_READWRITE,6. .pr

3、ivate_value=0xffff,7. .info=my_control_info,8. .get=my_control_get,9. .put=my_control_put10. ;iface字段指出了control的类型,alsa定义了几种类型(SNDDRV_CTL_ELEM_IFACE_XXX),常用的类型是 MIXER,当然也可以定义属于全局的CARD类型,也可以定义属于某类设备的类型,例如HWDEP,PCMRAWMIDI,TIMER等,这时需要在 device和subdevice字段中指出卡的设备逻辑编号。name字段是该control的名字,从ALSA 0.9.x开始,cont

4、rol的名字是变得比较重要,因为control的作用是按名字来归类的。ALSA已经预定义了一些control的名字,我们再Control Name一节详细讨论。index字段用于保存该control的在该卡中的编号。如果声卡中有不止一个codec,每个codec中有相同名字的control,这时我们可以通过index来区分这些controls。当index为0时,则可以忽略这种区分策略。access字段包含了该control的访问类型。每一个bit代表一种访问类型,这些访问类型可以多个“或”运算组合在一起。private_value字段包含了一个任意的长整数类型值。该值可以通过info,get

5、,put这几个回调函数访问。你可以自己决定如何使用该字段,例如可以把它拆分成多个位域,又或者是一个指针,指向某一个数据结构。tlv字段为该control提供元数据。Control的名字 control的名字需要遵循一些标准,通常可以分成3部分来定义control的名字:源-方向-功能。 源,可以理解为该control的输入端,alsa已经预定义了一些常用的源,例如:Master,PCM,CD,Line等等。 方向,代表该control的数据流向,例如:Playback,Capture,Bypass,Bypass Capture等等,也可以不定义方向,这时表示该Control是双向的(playb

6、ack和capture)。 功能,根据control的功能,可以是以下字符串:Switch,Volume,Route等等。 也有一些命名上的特例: 全局的capture和playback Capture Source,Capture Volume,Capture Switch,它们用于全局的capture source,switch和volume。同理,Playback Volume,Playback Switch,它们用于全局的输出switch和volume。 Tone-controles 音调控制的开关和音量命名为:Tone Control - XXX,例如,Tone Control -

7、Switch,Tone Control - Bass,Tone Control - Center。 3D controls 3D控件的命名规则:,3D Control - Switch,3D Control - Center,3D Control - Space。 Mic boost 麦克风音量加强控件命名为:Mic Boost或Mic Boost(6dB)。 访问标志(ACCESS Flags) Access字段是一个bitmask,它保存了改control的访问类型。默认的访问类型 是:SNDDRV_CTL_ELEM_ACCESS_READWRITE,表明该control支持读和写操作。如

8、果access字段没有定义 (.access=0),此时也认为是READWRITE类型。如果是一个只读control,access应该设置为:SNDDRV_CTL_ELEM_ACCESS_READ,这时,我们不必定义put回调 函数。类似地,如果是只写control,access应该设置为:SNDDRV_CTL_ELEM_ACCESS_WRITE,这时,我们不必定义 get回调函数。如果control的值会频繁地改变(例如:电平表),我们可以使用VOLATILE类型,这意味着该control会在没有通知的情况下改变,应用程序应该定时地查询该control的值。回调函数 info回调函数info

9、回调函数用于获取control的详细信息。它的主要工作就是填充通过参数传入的snd_ctl_elem_info对象,以下例子是一个具有单个元素的boolean型control的info回调:c-sharp view plaincopy1. staticintsnd_myctl_mono_info(structsnd_kcontrol*kcontrol,2. structsnd_ctl_elem_info*uinfo)3. 4. uinfo-type=SNDRV_CTL_ELEM_TYPE_BOOLEAN;5. uinfo-count=1;6. uinfo-value.integer.min=0

10、;7. uinfo-value.integer.max=1;8. return0;9. type字段指出该control的值类型,值类型可以是BOOLEAN, INTEGER, ENUMERATED, BYTES,IEC958和INTEGER64之一。count字段指出了改control中包含有多少个元素单元,比如,立体声的音量control左 右两个声道的音量值,它的count字段等于2。value字段是一个联合体(union),value的内容和control的类型有关。其 中,boolean和integer类型是相同的。ENUMERATED类型有些特殊。它的value需要设定一个字符串和

11、字符串的索引,请看以下例子:c-sharp view plaincopy1. staticintsnd_myctl_enum_info(structsnd_kcontrol*kcontrol,2. structsnd_ctl_elem_info*uinfo)3. 4. staticchar*texts4=5. First,Second,Third,Fourth6. ;7. uinfo-type=SNDRV_CTL_ELEM_TYPE_ENUMERATED;8. uinfo-count=1;9. uinfo-value.enumerated.items=4;10. if(uinfo-value.

12、enumerated.item3)11. uinfo-value.enumerated.item=3;12. strcpy(uinfo-value.enumerated.name,13. textsuinfo-value.enumerated.item);14. return0;15. alsa已经为我们实现了一些通用的info回调函数,例如:snd_ctl_boolean_mono_info(),snd_ctl_boolean_stereo_info()等等。get回调函数该回调函数用于读取control的当前值,并返回给用户空间的应用程序。c-sharp view plaincopy1.

13、staticintsnd_myctl_get(structsnd_kcontrol*kcontrol,2. structsnd_ctl_elem_value*ucontrol)3. 4. structmychip*chip=snd_kcontrol_chip(kcontrol);5. ucontrol-value.integer.value0=get_some_value(chip);6. return0;7. value字段的赋值依赖于control的类型(如同info回调)。很多声卡的驱动利用它存储硬件寄存器的地址、bit-shift和bit-mask,这时,private_value字段

14、可以按以下例子进行设置:.private_value = reg | (shift 16) | (mask private_value & 0xff; int shift = (kcontrol-private_value 16) & 0xff; int mask = (kcontrol-private_value 24) & 0xff; . /根据以上的值读取相应寄存器的值并填入value中如果control的count字段大于1,表示control有多个元素单元,get回调函数也应该为value填充多个数值。put回调函数put回调函数用于把应用程序的控制值设置到control中。c-sh

15、arp view plaincopy1. staticintsnd_myctl_put(structsnd_kcontrol*kcontrol,2. structsnd_ctl_elem_value*ucontrol)3. 4. structmychip*chip=snd_kcontrol_chip(kcontrol);5. intchanged=0;6. if(chip-current_value!=7. ucontrol-value.integer.value0)8. change_current_value(chip,9. ucontrol-value.integer.value0);1

16、0. changed=1;11. 12. returnchanged;13. 如上述例子所示,当control的值被改变时,put回调必须要返回1,如果值没有被改变,则返回0。如果发生了错误,则返回一个负数的错误号。和get回调一样,当control的count大于1时,put回调也要处理多个control中的元素值。创建Controls 当把以上讨论的内容都准备好了以后,我们就可以创建我们自己的control了。alsa-driver为我们提供了两个用于创建control的API: snd_ctl_new1() snd_ctl_add() 我们可以用以下最简单的方式创建control:c-s

17、harp view plaincopy1. err=snd_ctl_add(card,snd_ctl_new1(&my_control,chip);2. if(errprivate_data字段,该字段可以在回调函数中访问。snd_ctl_new1()会分配一个新的snd_kcontrol实例,并把my_control中相应的值复制到该实例中,所以,在定义 my_control时,通常我们可以加上_devinitdata前缀。snd_ctl_add则把该control绑定到声卡对象card当中。元数据(Metadata) 很多mixer control需要提供以dB为单位的信息,我们可以使用D

18、ECLARE_TLV_xxx宏来定义一些包含这种信息的变量,然后把control的 tlv.p字段指向这些变量,最后,在access字段中加上SNDRV_CTL_ELEM_ACCESS_TLV_READ标志,就像这样:static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);static struct snd_kcontrol_new my_control _devinitdata = . .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TL

19、V_READ, . .tlv.p = db_scale_my_control,;DECLARE_TLV_DB_SCALE宏定义的mixer control,它所代表的值按一个固定的dB值的步长变化。该宏的第一个参数是要定义变量的名字,第二个参数是最小值,以0.01dB为单位。第三个参 数是变化的步长,也是以0.01dB为单位。如果该control处于最小值时会做出mute时,需要把第四个参数设为1。DECLARE_TLV_DB_LINEAR宏定义的mixer control,它的输出随值的变化而线性变化。该宏的第一个参数是要定义变量的名字,第二个参数是最小值,以0.01dB为单位。第二个参数是

20、最大 值,以0.01dB为单位。如果该control处于最小值时会做出mute时,需要把第二个参数设为TLV_DB_GAIN_MUTE。这两个宏实际上就是定义一个整形数组,所谓tlv,就是Type-Lenght-Value的意思,数组的第0各元素代表数据的类型,第1个元素代表数据的长度,第三个元素和之后的元素保存该变量的数据。Control设备的建立 Control设备和PCM设备一样,都属于声卡下的逻辑设备。用户空间的应用程序通过alsa-lib访问该Control设备,读取或控制control的控制状态,从而达到控制音频Codec进行各种Mixer等控制操作。Control设备的创建过程大

21、体上和PCM设备的创建过程相同。详细的创建过程可以参考本博的另一篇文章:Linux音频驱动之三:PCM设备的创建。下面我们只讨论有区别的地方。我们需要在我们的驱动程序初始化时主动调用snd_pcm_new()函数创建pcm设备,而control设备则在 snd_card_create()内被创建,snd_card_create()通过调用snd_ctl_create()函数创建control设备 节点。所以我们无需显式地创建control设备,只要建立声卡,control设备被自动地创建。和pcm设备一样,control设备的名字遵循一定的规则:controlCxx,这里的xx代表声卡的编号。

22、我们也可以通过代码正是这一点,下面的是snd_ctl_dev_register()函数的代码:c-sharp view plaincopy1. /*2. *registrationofthecontroldevice3. */4. staticintsnd_ctl_dev_register(structsnd_device*device)5. 6. structsnd_card*card=device-device_data;7. interr,cardnum;8. charname16;9. 10. if(snd_BUG_ON(!card)11. return-ENXIO;12. cardn

23、um=card-number;13. if(snd_BUG_ON(cardnum=SNDRV_CARDS)14. return-ENXIO;15. /*control设备的名字*/16. sprintf(name,controlC%i,cardnum);17. if(err=snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,card,-1,18. &snd_ctl_f_ops,card,name)0)19. returnerr;20. return0;21. snd_ctl_dev_register()函数会在snd_card_register()中,

24、即声卡的注册阶段被调用。注册完成 后,control设备的相关信息被保存在snd_minors数组中,用control设备的此设备号作索引,即可在snd_minors数组 中找出相关的信息。注册完成后的数据结构关系可以用下图进行表述: control设备的操作函数入口用户程序需要打开control设备时,驱动程序通过snd_minors全局数组和此设备号,可以获得snd_ctl_f_ops结构中的各 个回调函数,然后通过这些回调函数访问control中的信息和数据(最终会调用control的几个回调函数get,put,info)。详细的代码我 就不贴了,大家可以读一下代码:/sound/core/control.c。

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2