Alsa里面恶心的DAPM

相关文章

音频系统,Alsa 里面的buff 是怎么计算的?

为什么需要超过48k的采样音频?

我在MTK平台下调试音频ALSA

音频几个重要的参数

openwrt 音频开发

(干货)Ai音箱和Linux音频驱动小谈

Android 音频数据流分析之程序员干架产品经理


正文

做音频的很多初学者对这个概念真的非常懵,我也是非常懵,所以写个文章概述一下,以后遇到问题的时候可以回来看看。

DAPM 从字面上看是和电源相关的,但是我们实际代码里面有非常多的结构体和函数是跟这个又没有多少关系,动态调整电源是最终的目的,那些使用的结构体,路由,小控件,都是用来协助完成这个事情的。

#我们用到的一些结构体和函数

这是小控件的结构体,也可以理解成一个开关,是一个通路里面的一个节点。

struct snd_soc_dapm_widget //一个整理数组
struct snd_kcontrol_new //一个小控件

下面这个是路由的结构体,路由一般在machine里面和codec里面存在,就是确定音频通路设置。

struct snd_soc_dapm_route

路由设置的是 sink sourcecontrol

sink 可以理解成输出,source 是数据源头,control 就是输出是打到哪个通路的开关的。这里有必要说一下,我们正常的source 一般理解是在左边,但是这里source 在右边。

下面是设置小控件的一些宏,不同类型的控件节点需要用到不同的宏

SND_SOC_DAPM_INPUT
SND_SOC_DAPM_SUPPLY_S
SND_SOC_DAPM_SWITCH

#实例

#硬件连接图

#实现开关选项control

static const struct snd_kcontrol_new wm8900_loutmix_controls[] = {
SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0),
SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0),
SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0),
SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0),
SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0),
};

#实现widget,可以理解把contrl整合到 snd_soc_dapm_widget  结构体里面

static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {
/* Output */SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0,wm8900_loutmix_controls,ARRAY_SIZE(wm8900_loutmix_controls)),};

#实现路由通路配置

static const struct snd_soc_dapm_route audio_map[] = {{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},};

可以观察下 Left Input Mixer Switch 这个字符串就用来制定control 打向了哪个开关,跟 wm8900_loutmix_controls 里面的值对应。

合起来就是通过Left Input Mixer Switch 开关把数据源 Left Input Mixer连接到 Left Output Mixer 输输出口。

#将上面设置的widget、route和kcontrols串联起来

static int wm8900_add_widgets(struct snd_soc_codec *codec)
{snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,ARRAY_SIZE(wm8900_dapm_widgets));snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));snd_soc_dapm_new_widgets(codec);return 0;
} 

大概就这样能够把目标、源、控制开关串联起来。我在看MTK内核代码的时候,里面的实现跟这个有些不一样,主要是新加了一个结构体,但是本质还是串联这些东西。

MTK平台差异部分

##Kcontrol

static const struct snd_kcontrol_new mt8167_afe_o13_mix[] = {SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_GAIN1_CONN2, 4, 1, 0),SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_GAIN1_CONN2, 9, 1, 0),
};

##widget

static const struct snd_soc_dapm_widget mt8167_afe_pcm_widgets[] = {SND_SOC_DAPM_MIXER("O13", SND_SOC_NOPM, 0, 0,mt8167_afe_o13_mix, ARRAY_SIZE(mt8167_afe_o13_mix)),
};

##route

static const struct snd_soc_dapm_route mt8167_afe_pcm_routes[] = {{"O13", "I15 Switch", "I15"},
};

##串联注册

static const struct snd_soc_component_driver mt8167_afe_pcm_dai_component = {.name = "mtk-afe-pcm-dai",.dapm_widgets = mt8167_afe_pcm_widgets,.num_dapm_widgets = ARRAY_SIZE(mt8167_afe_pcm_widgets),.dapm_routes = mt8167_afe_pcm_routes,.num_dapm_routes = ARRAY_SIZE(mt8167_afe_pcm_routes),
};
ret = snd_soc_register_component(&pdev->dev,&mt8167_afe_pcm_dai_component,mt8167_afe_pcm_dais,ARRAY_SIZE(mt8167_afe_pcm_dais));

实在话,看英语原文感觉还是很舒服的。

英语原文翻译如下:

Dynamic Audio Power Management for Portable Devices
===================================================1. Description
==============Dynamic Audio Power Management (DAPM) is designed to allow portable
Linux devices to use the minimum amount of power within the audio
subsystem at all times. It is independent of other kernel PM and as
such, can easily co-exist with the other PM systems.DAPM is also completely transparent to all user space applications as
all power switching is done within the ASoC core. No code changes or
recompiling are required for user space applications. DAPM makes power
switching decisions based upon any audio stream (capture/playback)
activity and audio mixer settings within the device.DAPM spans the whole machine. It covers power control within the entire
audio subsystem, this includes internal codec power blocks and machine
level power systems.There are 4 power domains within DAPM1. Codec domain – VREF, VMID (core codec and audio power)
Usually controlled at codec probe/remove and suspend/resume, although
can be set at stream time if power is not needed for sidetone, etc.2. Platform/Machine domain – physically connected inputs and outputs
Is platform/machine and user action specific, is configured by the
machine driver and responds to asynchronous events e.g when HP
are inserted3. Path domain – audio susbsystem signal paths
Automatically set when mixer and mux settings are changed by the user.
e.g. alsamixer, amixer.4. Stream domain – DACs and ADCs.
Enabled and disabled when stream playback/capture is started and
stopped respectively. e.g. aplay, arecord.All DAPM power switching decisions are made automatically by consulting an audio
routing map of the whole machine. This map is specific to each machine and
consists of the interconnections between every audio component (including
internal codec components). All audio components that effect power are called
widgets hereafter.2. DAPM Widgets
===============Audio DAPM widgets fall into a number of types:-o Mixer      – Mixes several analog signals into a single analog signal.
o Mux        – An analog switch that outputs only one of many inputs.
o PGA        – A programmable gain amplifier or attenuation widget.
o ADC        – Analog to Digital Converter
o DAC        – Digital to Analog Converter
o Switch     – An analog switch
o Input      – A codec input pin
o Output     – A codec output pin
o Headphone  – Headphone (and optional Jack)
o Mic        – Mic (and optional Jack)
o Line       – Line Input/Output (and optional Jack)
o Speaker    – Speaker
o Supply     – Power or clock supply widget used by other widgets.
o Pre        – Special PRE widget (exec before all others)
o Post       – Special POST widget (exec after all others)(Widgets are defined in include/sound/soc-dapm.h)Widgets are usually added in the codec driver and the machine driver. There are
convenience macros defined in soc-dapm.h that can be used to quickly build a
list of widgets of the codecs and machines DAPM widgets.Most widgets have a name, register, shift and invert. Some widgets have extra
parameters for stream name and kcontrols.2.1 Stream Domain Widgets
————————-Stream Widgets relate to the stream power domain and only consist of ADCs
(analog to digital converters) and DACs (digital to analog converters).Stream widgets have the following format:-SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),NOTE: the stream name must match the corresponding stream name in your codec
snd_soc_codec_dai.e.g. stream widgets for HiFi playback and captureSND_SOC_DAPM_DAC(“HiFi DAC”, “HiFi Playback”, REG, 3, 1),
SND_SOC_DAPM_ADC(“HiFi ADC”, “HiFi Capture”, REG, 2, 1),2.2 Path Domain Widgets
———————–Path domain widgets have a ability to control or affect the audio signal or
audio paths within the audio subsystem. They have the following form:-SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)Any widget kcontrols can be set using the controls and num_controls members.e.g. Mixer widget (the kcontrols are declared first)/* Output Mixer */
static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
SOC_DAPM_SINGLE(“Line Bypass Switch”, WM8731_APANA, 3, 1, 0),
SOC_DAPM_SINGLE(“Mic Sidetone Switch”, WM8731_APANA, 5, 1, 0),
SOC_DAPM_SINGLE(“HiFi Playback Switch”, WM8731_APANA, 4, 1, 0),
};SND_SOC_DAPM_MIXER(“Output Mixer”, WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
ARRAY_SIZE(wm8731_output_mixer_controls)),If you dont want the mixer elements prefixed with the name of the mixer widget,
you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
as for SND_SOC_DAPM_MIXER.2.3 Platform/Machine domain Widgets
———————————–Machine widgets are different from codec widgets in that they don’t have a
codec register bit associated with them. A machine widget is assigned to each
machine audio component (non codec) that can be independently powered. e.g.o Speaker Amp
o Microphone Bias
o Jack connectorsA machine widget can have an optional call back.e.g. Jack connector widget for an external Mic that enables Mic Bias
when the Mic is inserted:-static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
{
gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
return 0;
}SND_SOC_DAPM_MIC(“Mic Jack”, spitz_mic_bias),2.4 Codec Domain
—————-The codec power domain has no widgets and is handled by the codecs DAPM event
handler. This handler is called when the codec powerstate is changed wrt to any
stream event or by kernel PM events.2.5 Virtual Widgets
——————-Sometimes widgets exist in the codec or machine audio map that don’t have any
corresponding soft power control. In this case it is necessary to create
a virtual widget – a widget with no control bits e.g.SND_SOC_DAPM_MIXER(“AC97 Mixer”, SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),This can be used to merge to signal paths together in software.After all the widgets have been defined, they can then be added to the DAPM
subsystem individually with a call to snd_soc_dapm_new_control().3. Codec Widget Interconnections
================================Widgets are connected to each other within the codec and machine by audio paths
(called interconnections). Each interconnection must be defined in order to
create a map of all audio paths between widgets.This is easiest with a diagram of the codec (and schematic of the machine audio
system), as it requires joining widgets together via their audio signal paths.e.g., from the WM8731 output mixer (wm8731.c)The WM8731 output mixer has 3 inputs (sources)1. Line Bypass Input
2. DAC (HiFi playback)
3. Mic Sidetone InputEach input in this example has a kcontrol associated with it (defined in example
above) and is connected to the output mixer via it’s kcontrol name. We can now
connect the destination widget (wrt audio signal) with it’s source widgets./* output mixer */
{“Output Mixer”, “Line Bypass Switch”, “Line Input”},
{“Output Mixer”, “HiFi Playback Switch”, “DAC”},
{“Output Mixer”, “Mic Sidetone Switch”, “Mic Bias”},So we have :-Destination Widget  <=== Path Name <=== Source WidgetOr:-Sink, Path, SourceOr :-“Output Mixer” is connected to the “DAC” via the “HiFi Playback Switch”.When there is no path name connecting widgets (e.g. a direct connection) we
pass NULL for the path name.Interconnections are created with a call to:-snd_soc_dapm_connect_input(codec, sink, path, source);Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and
interconnections have been registered with the core. This causes the core to
scan the codec and machine so that the internal DAPM state matches the
physical state of the machine.3.1 Machine Widget Interconnections
———————————–
Machine widget interconnections are created in the same way as codec ones and
directly connect the codec pins to machine level widgets.e.g. connects the speaker out codec pins to the internal speaker./* ext speaker connected to codec pins LOUT2, ROUT2  */
{“Ext Spk”, NULL , “ROUT2”},
{“Ext Spk”, NULL , “LOUT2”},This allows the DAPM to power on and off pins that are connected (and in use)
and pins that are NC respectively.4 Endpoint Widgets
===================
An endpoint is a start or end point (widget) of an audio signal within the
machine and includes the codec. e.g.o Headphone Jack
o Internal Speaker
o Internal Mic
o Mic Jack
o Codec PinsWhen a codec pin is NC it can be marked as not used with a call tosnd_soc_dapm_set_endpoint(codec, “Widget Name”, 0);The last argument is 0 for inactive and 1 for active. This way the pin and its
input widget will never be powered up and consume power.This also applies to machine widgets. e.g. if a headphone is connected to a
jack then the jack can be marked active. If the headphone is removed, then
the headphone jack can be marked inactive.5 DAPM Widget Events
====================Some widgets can register their interest with the DAPM core in PM events.
e.g. A Speaker with an amplifier registers a widget so the amplifier can be
powered only when the spk is in use./* turn speaker amplifier on/off depending on use */
static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
{
gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
return 0;
}/* corgi machine dapm widgets */
static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
SND_SOC_DAPM_SPK(“Ext Spk”, corgi_amp_event);Please see soc-dapm.h for all other widgets that support events.5.1 Event types
—————The following event types are supported by event widgets./* dapm event types */
#define SND_SOC_DAPM_PRE_PMU 0x1  /* before widget power up */
#define SND_SOC_DAPM_POST_PMU 0x2  /* after widget power up */
#define SND_SOC_DAPM_PRE_PMD 0x4  /* before widget power down */
#define SND_SOC_DAPM_POST_PMD 0x8  /* after widget power down */
#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */

  推荐阅读:

    专辑|Linux文章汇总

    专辑|程序人生

    专辑|C语言

嵌入式Linux

微信扫描二维码,关注我的公众号 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467329.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 屏幕关闭 eofexception,android EOFException异常解决办法 (SharedPreferences保存对象)...

SharePreferences可以保存String 但是不能保存对象这不符合面向对象。为此可以通过序列化和反序列化将Serializable对象和字符串相互转化所以可以将Serizlizable对象转化为字符串保存到SharedPreferences中SharedPreferences.Editor localEditor settings.edit();localEditor.…

软件开发能力成熟度模型CMM介绍

软件开发能力的成熟度模型(Capability Manurity Model for Software&#xff0c;CMM)是软件工程协会SEI(Software Engineering Institution)在卡内基.梅隆大学开发完成的对一个组织软件开发能力进行评价的标准&#xff0c;它侧重于对软件开发过程和开发方法论的考察。CMM包括五…

POJ 3461Oulipo KMP模板

KMP之所以线性,因为匹配的时候i是不往回走的 我们只用调整j的位置 假设在s中找t 用二元组(i,j)表示s串的[i-j1,i] 与t串的[1,j]匹配 假设s[i1]和t[j]匹配上了,就j 如果不匹配的话,我们就想办法调整j, 直到找到一个满足二元组条件的j并且t[j1]s[i] 快速调整j就是利用nxt数组的过…

从Linus Torvalds一封发飙的电邮开始谈设备树究竟是棵什么树?

[导读] 新版的U-Boot以及内核都引入了设备树&#xff0c;那么这究竟是棵什么样的树呢&#xff1f;长啥样&#xff1f;有啥用&#xff1f;为啥弄个这样的树&#xff1f;本文基于对设备树标准的理解&#xff0c;来学习整理一下相关的要点&#xff0c;供大家参考。Linux为啥要设备…

html两个div间有白线,html-在特定浏览器宽度下,白线出现在渐变填充div的末尾

我有一个ID为#gradient_div的div,其背景图像设置为线性渐变.仅在某些浏览器窗口宽度下,线性渐变的末尾与div #gradient_div的末尾之间才出现缝隙.当我拉伸和收缩浏览器窗口时,这条白线消失并重新出现.似乎与边距有关&#xff1a;>当我将边距设置为margin&#xff1a;0 1&…

递归多线程实现前缀和

http://blog.csdn.net/qq_21361539/article/details/51577263转载于:https://www.cnblogs.com/NEU-2015/p/7857668.html

[Classic] 日文版《出师表》

臣亮言す.先帝业を创めて未だ半ばならずして,中道にして崩祖せり.今天下三分すれども, 益州は疲弊す.此れ诚に危急存亡の秋なり.然れども侍卫の臣,内に懈らず,忠志の士,身を 外に忘るるは,盖し先帝の殊遇を追いて,之を陛下に报いんと欲すればなり.诚に宜しく圣聴 を开张して…

为什么读书了,还不如那些初中毕业的同学

今天群里特别热闹&#xff0c;大家聊了很多&#xff0c;我在旁边看着&#xff0c;很舒服&#xff0c;可能也有人跟我一样&#xff0c;看着这些B神吹牛。像读书时候的卧谈会&#xff0c;大家都聊的很嗨&#xff0c;听的人更嗨&#xff0c;我就是那个喜欢听大家吹牛的人&#xff…

html判断整数小数点后两位小数点,js控制input框只能输入数字和一位小数点且小数点后面只有两位小数...

js控制input框只能输入数字和一位小数点且小数点后面只有两位小数js控制input框只能输入数字和一位小数点且小数点后面只有两位小数212或 0.66; 过滤 00000,1.10,0.00function clearNoNum(obj){obj.value obj.value.replace(/[^\d.]/g,""); //清除“数字”和“.”以…

为什么说卷积神经网络,是深度学习算法应用最成功的领域之一?

目前&#xff0c;作为深度学习的代表算法之一&#xff0c;卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;CNN&#xff09;在计算机视觉、分类等领域上&#xff0c;都取得了当前最好的效果。后来&#xff0c;基于深度神经网络和搜索树的智能机器人“AlphaG…

C语言博客作业--函数

C语言博客作业--函数 一&#xff0c;PTA实验作业 6-2 简单实现x的n次方 1.本题PTA提交列表 2.设计思路 double mypow( double x, int n )函数&#xff08;1&#xff09;定义y1&#xff0c;i用于循环变量&#xff08;2&#xff09;for(i1;i<n;i){ yy*x}用循环实现x的n次方&am…

linux下软件的基本安装和卸载

Linux软件的安装和卸载一直是困扰许多新用户的难题。在Windows中&#xff0c;我们可以使用软件自带的安装卸载程序或在控制面板中的“添加/删除程序”来实现。与其相类似&#xff0c;在Linux下有一个功能强大的软件安装卸载工具&#xff0c;名为RPM。它可以用来建立、安装、查询…

计算机应用基础课程编制标准,计算机应用基础课程标准.doc

计算机应用基础课程标准《计算机应用基础》课程标准一、前言《计算机应用基础》课程是高职院校必修的一门基础课&#xff0c;具有很强的实用性和实践性&#xff0c;是各行各业从事现代化办公&#xff0c;计算机设计及应用领域人才所必须具备的理论知识和时间技能&#xff0c;通…

Linux系统编程 / triggerhappy 源码分析(3.select 的应用)

哈喽&#xff0c;我是老吴&#xff0c;继续记录我的学习心得。一、进步的滞后性我们期望进步是线性&#xff1a;每一个人付出一些努力后&#xff0c;都希望它有立竿见影的效果。现实是&#xff1a;做出努力后&#xff0c;结果的显现往往滞后。只有在几个月或几年后&#xff0c;…

node中定时器, process.nextTick(), setImediate()的区别与联系

1.定时器 setTimeout()和setInterval()与浏览器中的API是一致的&#xff0c;定时器的问题在于&#xff0c;他并非精确的&#xff08;在容忍范围内&#xff09;。尽管事件循环十分快&#xff0c;但是如果某一次循环占用的时间较多&#xff0c;那么下次循环时&#xff0c;他也许已…

[转载]关于NETBIOS理清楚概念的文章

有关网上邻居的问题&#xff0c;问的人一直比较多&#xff0c;在理解上存在的误区也普遍较为严重。鉴于Microsoft的NETBIOS文档不是很细致&#xff0c;我四处收集了一些相关资料加上自己的实践经验写了这个系列&#xff0c;希望能对大家有所帮助&#xff0e; 本来想为了增加可读…

form.html,HTML表单form

前面我们讲了HTML的各种数据输入方式&#xff0c;数据输入之后&#xff0c;一般来说应该提交给后台处理&#xff0c;HTML通过表单form来提交数据。form包含1个或多个数据输入&#xff0c;如input&#xff0c;单选&#xff0c;复选&#xff0c;文件等等form将其包含的输入项&…

今天,给我妈打电话聊了我爸

晚上&#xff0c;给我妈打电话&#xff0c;我爸前两天病了&#xff0c;前几年的大病虽然慢慢康复&#xff0c;但是因为年纪大了&#xff0c;身体机能也慢慢变弱&#xff0c;总是有一些大大小小的问题。前两天我发消息给我爸&#xff0c;我说我们要进新房子了&#xff0c;虽然房…

A Simple Note on P4FPGA: A Rapid Prototyping Framework for P4

论文&#xff1a;P4FPGA: A Rapid Prototyping Framework for P4 Github&#xff1a;https://github.com/p4fpga Reference: Han Wang, Robert Soule ́, Huynh Tu Dang, Ki Suh Lee, Vishal Shrivastav, Nate Foster, and Hakim Weatherspoon. 2017. P4FPGA : A Rapid Prototy…

客户端回调

Client Callback 是ASP.NET 2.0新增的一个特性。简单的说&#xff0c;就是在不刷新页面的情况下&#xff0c;用javascript向服务器端传递参数、调用服务器端的方法、并且得到服务器端的返回值进行处理。 1> Why Client Callback HTTP是无状态的协议。在HTTP协议之上开发的…