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个参数表明第几个通道

转载于:https://www.cnblogs.com/alan666/p/8311864.html

ALSA声卡12_从零编写之添加音量控制_学习笔记相关推荐

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

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

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

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

  3. 原生JS零魂之问(上)学习笔记‍

    作为一个普通的JS初学者,从神三元大佬的知识梳理文章中受益匪浅,写下我的学习笔记吧. JS数据类型 function test(person) {person.age = 26person = {na ...

  4. oracle拆分分区语法详解大全_学习笔记:Oracle分区表 添加 删除 合并 删除 交换 拆分等分区表的操作案例...

    天萃荷净 Oracle分区表管理,记录关于Oracle分区表的管理案例:创建.删除.合并.拆分.交换.更改分区表的操作方法 1.添加创建分区表 1.1)增加分区(add partition) 语法是: ...

  5. 【PM学习笔记】酸梅干超人 - 零基础学B端UI设计 学习笔记

    学习笔记目录 0 先导片 1.1 B端是什么?和C端有什么区别? 1.2 完整走一遍B端项目流程 1.3 B端产品经理介绍 PM都在做什么? 0 先导片 B端业务类型 举例:云服务.智慧系统.数据BI ...

  6. Android入门到精通|安卓/Android开发零基础系列Ⅱ【职坐标】-学习笔记(1)-- 常用控件及资源介绍

    前言 为了巩固Android基础知识,回顾一下学习内容,才有此学习笔记. IDE Androdi Studio 4 + Genymotion 创建项目 修改项目的 build.gradle,添加国内镜 ...

  7. java给界面添加滚动条_Java Swing学习笔记:要求会默写或熟练的,GUI,控件,设置列或行,加滚动条,新界面...

    GUI:Java的图形化用户界面 学习其控件的使用 JLabel(文本控件),JTextField(文本框),JPassworldField(密码框),JButton(普通按钮) JRadioButt ...

  8. Python零基础入门(三)——函数[学习笔记]

    目录: 一.函数: 1.内置函数 2.定义函数 二.函数参数: 1.必选参数 2.默认参数 3.可变参数/任意参数 4.关键字参数 三.return语句 四.函数封装 1.导入整个模块 2.导入特定的 ...

  9. 《零基础学C语言》读后感学习笔记

    校招即将开始,突然翻到了4年前的C语言读书笔记,放在此处做个存档吧,只是整理了当时的重点部分. 第三章 C语言基础 1.所有标识符必须以字母或下划线开头,而不能以数字或者符号开头: 2.标识符不能是关 ...

最新文章

  1. 崩溃!双十一第 4 天,某互联网公司黄了?
  2. linux下安装部署ansible
  3. Modern C++ Design 学习笔记-第3章
  4. jsp 获取项目路径,java获取项目路径
  5. 神策数据荣获“2017金融科技·大数据优秀案例之最佳实践案例奖”
  6. 清除number输入框的上下箭头
  7. Netty学习笔记(三)EventLoopGroup开篇
  8. python 分布式队列_〖Python〗-- Celery分布式任务队列
  9. 京东商城上市带来的利与益
  10. stc15w4k32s4芯片引脚图片_单片机引脚功能初识及提高(3)
  11. prd移动端通用产品需求文档+Axure高保真app社交订餐通用prd文档+产品业务说明+PRD功能性需求+移动端公工通用模板说明+需求分析+竞品分析+产品结构图+产品业务流程图+产品信息图+餐饮系统
  12. struts html form提交加密,strutshtml:form标签有关问题  解决立即给分
  13. Github上热搜的Java开源商城项目合集,这个是真的好
  14. html文字段落i排版,i排版怎么修改字体?i排版字体排版详细介绍
  15. 深信服php面经,深信服面经
  16. 【头歌实验】五、Python循环结构
  17. HotSpot GC及参数设置
  18. TIOBE 3 月编程语言排行榜刚刚出炉
  19. js给网页中所有p元素添加onclick事件
  20. Vue+Element UI完成新建调查问卷

热门文章

  1. Linux命令 - watch
  2. stylus之方法(Functions)
  3. 几个有趣的python技巧
  4. python selenium 处理弹窗_python+selenium 抓取弹出对话框信息
  5. SQLServer之事务简介
  6. [BZOJ 1452] Count
  7. C高级第一次PTA作业(2)
  8. Java面向对象---重写(Override)与重载(Overload)
  9. 做一个常规的banner图——负边距的使用、banner图的拼法
  10. Linux 安装 OpenOffice