【Linux开发】基于ALSA库实现音量调节
基于ALSA库实现音量调节
- ALSA库实现音量调节
- 1、使用alsamixer工具查看音频接口
- 2、完整代码
- 2.1、snd_mixer_open
- 2.2、snd_mixer_attach、
- 2.3、snd_mixer_selem_register
- 2.4、snd_mixer_load
- 2.5、snd_mixer_first_elem/snd_mixer_elem_next
- 2.6、snd_mixer_selem_get_playback_volume_range/snd_mixer_selem_get_capture_volume_range
- 2.7、snd_mixer_selem_set_playback_volume_all
- 3、完整程序
- 4、注意细节
- 4.1、初始化顺序
- 4.2、声卡设备的选择
- 4.3、元素查找
- 4.4、单双通道音量设置
ALSA库实现音量调节
1、使用alsamixer工具查看音频接口
首先可以通过alsamixer工具图形化查看声卡的接口名,也可以使用该工具通过图形尝试调节音频大小,能帮助你后面更好的实现从应用层去调节,直接输入alsamixer即可自动弹出图形界面,如下图,Speaker是我播放的元素名称,上面的55是音量大小,通过键盘的上下键即可调节大小,这两个参数在后面应用层时都会用到:

2、完整代码
2.1、snd_mixer_open
- 打开并实例化一个空的混音器
2.2、snd_mixer_attach、
- 连接到选择的声卡控制设备
2.3、snd_mixer_selem_register
- 注册混音器
int snd_mixer_selem_register(snd_mixer_t *mixer,struct snd_mixer_selem_regopt *options,snd_mixer_class_t **classp);
2.4、snd_mixer_load
- 加载混音器
2.5、snd_mixer_first_elem/snd_mixer_elem_next
- 找到混音器的第一个元素/查找下一个元素
2.6、snd_mixer_selem_get_playback_volume_range/snd_mixer_selem_get_capture_volume_range
- 获取指定元素的音量范围
int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem,long *min,long *max);
int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem,long *min,long *max);
2.7、snd_mixer_selem_set_playback_volume_all
- 一次性设置指定元素所有声道的音量
3、完整程序
下面的函数实现音量的获取和调节,通过ALSA库的API接口,注册一个混音器设备对象,使用该对象连接到想要控制的声卡,然后开始查找该声卡中的元素,找到想要控制的元素,然后对元素进行get和set,本函数实现对Speaker元素的调节控制扬声器声音大小,通过应用程序调节完音量后,可以使用alsamixer工具查看音量是否成功调节。
/* volume control init */
void volume_control_init(void)
{snd_mixer_t *mixer;snd_mixer_elem_t *elem;debug_msg(snd_mixer_open(&mixer,0),"opening mixer"); // 打开混音器设备debug_msg(snd_mixer_attach(mixer, "hw:1"),"attaching mixer"); // 连接到默认的声卡debug_msg(snd_mixer_selem_register(mixer, NULL, NULL),"registering mixer"); // 载入声卡配置debug_msg(snd_mixer_load(mixer),"load mixer");// 循环找到自己想要的elementelem = snd_mixer_first_elem(mixer);while(elem){// find element name(此处要找的就是上面看的speaker元素)if(strcmp("Speaker",snd_mixer_selem_get_name(elem)) == 0){printf("elem name : %s\n",snd_mixer_selem_get_name(elem));break;}elem = snd_mixer_elem_next(elem);}if(!elem){printf("snd_mixer_find_selem Error\n");snd_mixer_close(mixer);mixer = NULL;return;}long min, max;snd_mixer_selem_get_playback_volume_range(elem, &min, &max);printf("volume range: %ld -- %ld\n", min, max);long lVal, rVal;snd_mixer_handle_events(mixer); // 确保混音器状态和应用程序状态的同步snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &lVal);snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_RIGHT, &rVal);printf("currnet volume: leftVal = %ld, rightVal = %ld\n", lVal, rVal);snd_mixer_selem_set_playback_volume_all(elem, 25);// 释放资源snd_mixer_close(mixer);
}
4、注意细节
4.1、初始化顺序
在初始化混音器设备时,需要先初始化好PCM声卡设备,不然PCM初始化时会重置导致音频设置失效
4.2、声卡设备的选择
程序中通过调用snd_mixer_attach选择声卡设备,选择时需要注意跟PCM选择声卡设备时不同,PCM初始化时选择的是声卡几设备几,比如声卡1,设备0,那么PCM初始化打开设备时要传入snd_pcm_open(&pb_handle, "plughw:1,0",SND_PCM_STREAM_PLAYBACK, 0),而mixer初始化时只需要选择声卡而不用详细到设备,依然是声卡1,设备0,那么mixer连接到声卡时只需要传入snd_mixer_attach(mixer, "hw:1")。
4.3、元素查找
在mixer中,有很多的element(元素),也就是最开始通过图形化看到的各种元素,在ALSA中好像没有函数能够直接查找到某个元素,只能通过snd_mixer_first_elem找到第一个元素,然后通过snd_mixer_elem_next开始查找下一个元素一直查下去,直到通过snd_mixer_selem_get_name发现当前的元素是你想要调节的元素为止(你可以选择将这种方式封装起来成为一个能指定查找的函数)。
4.4、单双通道音量设置
你可以通过snd_mixer_selem_is_playback_mono查询该声卡是否是单通道(mono:单,stereo:双),然后通过snd_mixer_selem_set_capture_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, volume)的第2个参数来指定左右通道的音量,但是我没什么时间深究,所以直接选择snd_mixer_selem_set_capture_volume_all来设置总音量。
同时需要注意一下音量的调节,虽然在alsamixer工具的图形化中可以看到音量能从0调节到100,但是程序中使用snd_mixer_selem_get_playback_volume获取音量时会发现范围在0-30,并且如果你使用amixer get 'DAC HPOUT Left'get一下元素的值查看时就会发现limits的值也为0-30,因此在设置音量时也要注意设置的值不要超过这个范围,不能以图形化中的范围去设置。
root@firefly:~/twoway# amixer get 'DAC HPOUT Left'
Simple mixer control 'DAC HPOUT Left',0Capabilities: volume volume-joinedPlayback channels: MonoCapture channels: MonoLimits: 0 - 30Mono: 30 [100%] [6.00dB]
相关文章:
【Linux开发】基于ALSA库实现音量调节
基于ALSA库实现音量调节 ALSA库实现音量调节1、使用alsamixer工具查看音频接口2、完整代码2.1、snd_mixer_open2.2、snd_mixer_attach、2.3、snd_mixer_selem_register2.4、snd_mixer_load2.5、snd_mixer_first_elem/snd_mixer_elem_next2.6、snd_mixer_selem_get_playback_vol…...
代理IP在未来将面临哪些挑战?
今天我们来聊聊代理IP在未来可能会面临的挑战。虽然代理IP技术目前应用广泛,但随着科技的发展和网络环境的变化,代理IP也将面临一些新的挑战。让我们一起来看看这些挑战是什么吧! 1. 更严格的网络封锁和检测 现代社会各行各业都在飞速发展&…...
FineBI在线学习资源-数据处理
FineBI在线学习资源汇总: 学习资源 视频课程 帮助文档 问答 数据处理学习文档: 相关资料: 故事背景概述-https://help.fanruan.com/finebi6.0/doc-view-1789.html 基础表处理-https://help.fanruan.com/finebi6.0/doc-view-1791.html …...
【代码随想录算法训练营第37期 第四十五天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III】
代码随想录算法训练营第37期 第四十五天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III 一、198.打家劫舍 解题代码C: class Solution { public:int rob(vector<int>& nums) {if (nums.size() 0) return 0;if (nums.size() 1) return num…...
Elasticsearch查询上下文和_source
查询上下文 {"took": 1,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation"…...
golang实现网卡流量监控
获取当前时刻一分钟前的网卡流量排序 package mainimport ("fmt""github.com/mackerelio/go-osstat/network""log""net/http""sort""strconv""time" )var arr []map[string]int var arr2 []map[string]…...
技术分享:直播平台如何开发并接入美颜SDK
本篇文章,笔者将分享直播平台如何开发并接入美颜SDK的技术细节与步骤。 一、选择合适的美颜SDK 首先,选择一款适合的美颜SDK非常重要。市面上有很多优秀的美颜SDK供应商,选择时应考虑以下因素: 功能丰富性:支持美白…...
左耳听风_114_113_Go编程模式修饰器
你好,我是陈浩,我名多尔多house.之前呢我写过一篇文章叫做python修饰器的函数式编程。 那这种模式呢可以很轻松的把一些函数啊装配到另外一些函数上。 让你的代码呢更加简单,也可以让一些小功能性的代码复用性更高。 让代码中的函数呢可以…...
Java实习手册(小白也看得懂)
秃狼说 距离俺发布的学习路线已经六个月了,那我给小伙伴的学习周期是四五个月左右,我相信大多的小伙伴已经学习的差不多了。正好赶上暑期实习的阶段,在暑期找到实习就成为暑期的头等大事。 实习经验在校招的起到决定性的作用,所…...
Elasticsearch 分析器(Analyzer)的作用和配置
在Elasticsearch中,分析器(Analyzer)是文本处理的核心组件,它负责将输入的文本转换为可用于搜索和索引的词项(tokens)。这一过程涉及多个步骤,包括字符过滤、分词和标记过滤,共同决定…...
SpringBoot(一)创建一个简单的SpringBoot工程
Spring框架常用注解简单介绍 SpringMVC常用注解简单介绍 SpringBoot(一)创建一个简单的SpringBoot工程 SpringBoot(二)SpringBoot多环境配置 SpringBoot(三)SpringBoot整合MyBatis SpringBoot(四…...
简述Vue中的数据双向绑定原理
Vue中的数据双向绑定原理是Vue框架的核心特性之一,它通过数据劫持结合发布者-订阅者模式来实现。下面将详细阐述Vue中数据双向绑定的原理,并尽量按照清晰的结构进行归纳: 一、数据劫持 使用Object.defineProperty(): Vue在组件…...
C++STL函数对象的应用
STL函数对象 文章目录 STL函数对象1.基本概念2.使用方法1. 简单函数对象示例2. 函数对象作为算法参数3. Lambda表达式作为函数对象 2.一元谓词和二元谓词1.一元谓词2.二元谓词3.总结 3.算术仿函数1.使用示例2.Lambda表达式的替代 4.关系仿函数5.逻辑仿函数 C中的函数对象&#…...
AJAX-day1:
注:文件布局: 一、AJAX的概念: AJAX是浏览器与服务器进行数据通信的技术 >把数据变活 二、AJAX的使用: 使用axios库,与服务器进行数据通信 基于XMLHttpRequest封装,代码简单 Vue,React项目使用 学习…...
昆虫学(书籍学习资料)
包括昆虫分类(上下册)、昆虫生态大图鉴等书籍资料。...
springboot + mybatis 多数据源切换
参考的b站博主写的 配置文件: spring:datasource:db1:jdbc-url: jdbc:mysql://localhost:3306/interview_database?useUnicodetrue&characterEncodingutf-8&useSSLfalseusername: rootpassword: 12345driver-class-name: com.mysql.cj.jdbc.Driverdb2:jdbc-url: jdbc…...
windows电脑网络重置后wifi列表消失怎么办?
我们的电脑网络偶尔会出现异常,我们通常会下意识选择网络诊断,运行完诊断后一般会让我们选择重置网络,然而,重置后wifi列表突然消失,无法愉快地上网了,找了一圈,都说是更改适配器选项࿰…...
Python + 在线 + 文生音,音转文(中文文本转为英文语音,语音转为中文文本)
开源模型 平台:https://huggingface.co/ars-语言转文本: pipeline("automatic-speech-recognition", model"openai/whisper-large-v3", device0 ) hf: https://huggingface.co/openai/whisper-large-v3 github: https://github.com/openai/wh…...
哏号分治,CF103D - Time to Raid Cowavans
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 103D - Time to Raid Cowavans 二、解题报告 1、思路分析 想了半天数据结构最终选择根号分治 我们考虑 大于 550 的公差直接暴力 小于550 的公差的所有询问,我们直接计算该公差后缀和…...
基于深度学习的图像背景剔除
在过去几年的机器学习领域,我一直想打造真正的机器学习产品。 几个月前,在参加了精彩的 Fast.AI 深度学习课程后,似乎一切皆有可能,我有机会:深度学习技术的进步使许多以前不可能实现的事情成为可能,而且开…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
