【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 深度学习课程后,似乎一切皆有可能,我有机会:深度学习技术的进步使许多以前不可能实现的事情成为可能,而且开…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...