1、设置音量时应用程序的调用过程

(1)strace分析: amixer cset numid=1 30 (设置音量)

/dev/snd/controlC0

open

SNDRV_CTL_IOCTL_CARD_INFO

SNDRV_CTL_IOCTL_PVERSION

SNDRV_CTL_IOCTL_ELEM_INFO

SNDRV_CTL_IOCTL_ELEM_READ

SNDRV_CTL_IOCTL_ELEM_WRITE : snd_ctl_elem_write_user

(2)应用程序调用SNDRV_CTL_IOCTL_ELEM_WRITE时,驱动程序调用snd_ctl_elem_write_user函数,这个函数从用户空间把一些参数拷贝进来,然后调用函数snd_ctl_elem_write

(3)函数snd_ctl_elem_write

找到一个snd_kcontrol结构体,然后调用snd_control结构体的put函数。

(4)这个snd_kcontrol结构体是谁提供的

ASOC驱动程序分为3大块(machine,codec,platform),应该在codec这一块来提供的,因为它跟声卡密切相关。去调节音量的时候肯定要调整它

2、写程序(uda1341.c(codec))

(1)结构体snd_kcontrol_new

static const struct snd_kcontrol_new uda1341_vol_control = 

{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, //表示snd_kcontrol结构体用于哪一类设备(表示进行参数设置)

    .name = "Master Playback Volume",  //音量控制,每个声卡驱动程序的snd_kcontrol各不相同,为什么应用程序都可以调整它的音量,对于某些常用的属性,它们都有固定的名字。应用程序根据名字找到它的snd_kcontrol项,调用里面的put函数。

.info = uda1341_info_vol,  //获得一些信息,如音量范围是多少

.get  = uda1341_get_vol,//获得当前的音量值

.put  = uda1341_put_vol, //设置音量

};

(2) 获得音量信息,比如最小值最大值

/*

 * 获得音量信息,比如最小值最大值

 */

int uda1341_info_vol(struct snd_kcontrol *kcontrol,

struct snd_ctl_elem_info *uinfo)

{

uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;//音量值的类型是整数

uinfo->count = 2;//声道数是双声道的

uinfo->value.integer.min = 0;//最小整数,

uinfo->value.integer.max = 63;//最大整数,

return 0;

}

因为uda1341的音量控制是6位的(0表示最大音量,63表示最小音量),而应用程序中0表示最小音量,值越大表示音量越大

(3)获得当前音量值

/*

 * 获得当前音量值

 */

int uda1341_get_vol(struct snd_kcontrol *kcontrol,

struct snd_ctl_elem_value *ucontrol)

{

struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);





    ucontrol->value.integer.value[1] = \  //这里 \  表示ucontrol->value.integer.value[0] 等于ucontrol->value.integer.value[1]
,因为是双声道

ucontrol->value.integer.value[0] = 63 - snd_soc_read(codec, UDA1341_DATA00);//读寄存器DAT00的值,因为驱动程序的值和应用程序的值大小是相反的,uda1341不支持寄存器的读操作,要想得到一个寄存器的值,是去读某个cache(这个cache保存的是设置寄存器的值)

return 0;

}



(4) 设置当前音量值

/*

 * 设置当前音量值

 */

int uda1341_put_vol(struct snd_kcontrol *kcontrol,

struct snd_ctl_elem_value *ucontrol)

{

struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);

unsigned int val;





val = 63 - ucontrol->value.integer.value[0];//应用程序传进来的值写到寄存器里面要反转





    snd_soc_write(codec, UDA1341_DATA00, val);//把值val写到寄存器DATA00中去

    

return 0;

}

3、结构体snd_kcontrol_new和内核部分的连接

(1)probe函数

static int uda1341_soc_probe(struct snd_soc_codec *codec)

{

    int ret;

    uda1341_init_regs(codec);

    

ret = snd_soc_add_codec_controls(codec, &uda1341_vol_control, 1);

    return ret;

}

4、测试

amixer  controls查看控制项

amixer cget numid=1表示查看当前音量

amixer cset numid=1 30设置音量

5、Input Mux

因为不同的板子的麦克风通道不同(在uda1341),用同一驱动,想录音时应用程序应该设置input mux选项。

表明它能选择哪个麦克风通道,当前是哪一个麦克风通道,设置哪一个麦克风通道

值uda134x_mixer_enum[2]是数组的第2项

6、

让板子使用内核自带的驱动程序

查看设备节点和控制项(input mux在倒数第二项)

查看控制项第11项的值(当前值是0)

若选择第1个通道(模拟通道)最后1个参数表明第几个通道


ALSA声卡12_从零编写之添加音量控制_学习笔记的更多相关文章

  1. ALSA声卡10_从零编写之数据传输_学习笔记

    1.引言 (1)应用程序使用声卡的时候,数据流程是:应用程序把数据发送给驱动,驱动把数据发送给硬件声卡,声卡把数据转换成声音数据播放出去. (2)可以使用两种方式发送数据 第一种:app发数据,等驱动 ...

  2. ALSA声卡08_从零编写之框架_学习笔记

    1.整体框架 (1)图示((DAI(全称Digital Audio Interface)接口)) 在嵌入式系统里面,声卡驱动是ASOC,是在ALSA驱动上封装的一层,包括以下三大块 (2)程序框架 m ...

  3. ALSA声卡11_从零编写之调试——学习笔记

    1.调试 (1)把程序拷贝到服务器上进行编译 (2)把程序放到内核上面去 重新配置内核,吧原来的声卡驱动程序去掉 a. 修改语法错误 11th_myalsa b. 配置内核去掉原来的声卡驱动 -> ...

  4. ALSA声卡09_从零编写之参数设置_学习笔记

    1.参数设置分析 (1)open: soc_pcm_open 依次调用cpu_dai, dma, codec_dai, machine的open或startup函数 只在dma的open函数里添加参数 ...

  5. 《零基础学JavaScript(全彩版)》学习笔记

    <零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...

  6. ALSA声卡16_编写ALSA声卡应用程序_学习笔记

    1.体验 (1)ALSA声卡使用体验:使用arecord录音,使用aplay播放,在Alsa-utils里面) 准备: cd linux-3.4.2 patch -p1 < ../linux-3 ...

  7. ALSA声卡07_分析调用过程_学习笔记

    1.编译新的strace工具分析aplay和amixer应用程序对声卡的调用过程 (1)因为旧的strace工具不能识别不能识别alsa声卡驱动程序里面的ioctrl. (2)编译过程参考http:/ ...

  8. unity中添加音量控制的一些步骤

    1.先确认要控制的音源(Audio Source)所使用的输出(Output),例如我这里BGM使用的是MainMixer: 2.暴露音量(Volume)参数,让脚本可以控制.这里如果不暴露出来,脚本 ...

  9. 36、ALSA声卡驱动和应用

    (注意:内核上电的时候会把一些没运行的控制器模块的时钟都关掉,所有在写驱动的时候需要在使用的使用使用clk_get和clk_enable使能时钟) (说明:与ALSA声卡对应的是OSS架构,第二期视频 ...

随机推荐

  1. 关于Spinlock机制的一点思考

    存在两段代码同时在多核上执行的情况,这时候才需要一个真正的锁来宣告代码对资源的占有. 几个核可能会同时access临界区,这时的spinlock是如何实现的呢? 要用到CPU提供的一些特殊指令,对lo ...

  2. JDiPad项目runtime的使用分析

    首先,项目有点老 但是运行还是没有问题的.其中很多地方到了runtime,同时也看到了 早期的开发人员 基本没用pod 第三方也很少用,除了微信登录,整个项目还没看到集成的第三方SDK.然后慢慢梳理 ...

  3. 从小白开始学习iOS开发

    从事iOS开发不经意间,已经两年过去了,记得当初看到OC是,我根本就不知道那些个东西是什么?从开始学习开机,到一个个英文开始,为了能找到工作,愣是耐下心去坚持看下去. 现在回想起来,很是庆幸我没有放弃 ...

  4. caffe学习4——net

    参考文献 1 The net jointly defines a function and its gradient by composition and auto-differentiation. ...

  5. 删除rz上传失败乱码的文件

    [摘要:经过rz上传文件失利时,会发生巨细为0的治码的文件,以下 ls-l -rw-rr1rootroot4703112-1513:48???.htm 这类范例的文件可用以下敕令 find.-maxd ...

  6. How to input the newline in Numbers of Mac?

    newline control+enter

  7. int('x', base)中的base参数

    >>> int('12', 16) 16表示'12'就是16进制数,int()要将这个16进制数转化成10进制.

  8. 自动化测试入门指南(3)-- 入门demo

    按照 自动化测试入门指南(2)-- 环境搭建搭建好环境后,我们继续一步步实现一个简单的入门例子 Step0. 安装Firefox浏览器(http://pan.baidu.com/s/1c00bw8g中 ...

  9. 命令“"xxx.exe" xxx”已退出,代码为 n。这些错误是什么意思?(3 / 123 / 9009)

    命令“”xxx.exe” xxx”已退出,代码为 n. 我们在 cmd 中输入常见命令的时候,如果命令输入错误或使用错误,cmd 中会提示错误原因,帮助我们定位并解决问题.然而如果相同的命令放到了 V ...

  10. 语义耦合(Semantic Coupling)

    跟小伙伴一起重构一段 UI,试图将用户界面和业务代码分离的时候,小伙伴试图在业务代码中直接调用 UI.我们当然都知道这会产生耦合,于是小伙伴试图定义一些属性.变量或接口来解决这个耦合.虽然在代码的静态 ...