当前位置: 首页 > news >正文

【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&#xff1a; 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

本篇文章&#xff0c;笔者将分享直播平台如何开发并接入美颜SDK的技术细节与步骤。 一、选择合适的美颜SDK 首先&#xff0c;选择一款适合的美颜SDK非常重要。市面上有很多优秀的美颜SDK供应商&#xff0c;选择时应考虑以下因素&#xff1a; 功能丰富性&#xff1a;支持美白…...

左耳听风_114_113_Go编程模式修饰器

你好&#xff0c;我是陈浩&#xff0c;我名多尔多house.之前呢我写过一篇文章叫做python修饰器的函数式编程。 那这种模式呢可以很轻松的把一些函数啊装配到另外一些函数上。 让你的代码呢更加简单&#xff0c;也可以让一些小功能性的代码复用性更高。 让代码中的函数呢可以…...

Java实习手册(小白也看得懂)

秃狼说 距离俺发布的学习路线已经六个月了&#xff0c;那我给小伙伴的学习周期是四五个月左右&#xff0c;我相信大多的小伙伴已经学习的差不多了。正好赶上暑期实习的阶段&#xff0c;在暑期找到实习就成为暑期的头等大事。 实习经验在校招的起到决定性的作用&#xff0c;所…...

Elasticsearch 分析器(Analyzer)的作用和配置

在Elasticsearch中&#xff0c;分析器&#xff08;Analyzer&#xff09;是文本处理的核心组件&#xff0c;它负责将输入的文本转换为可用于搜索和索引的词项&#xff08;tokens&#xff09;。这一过程涉及多个步骤&#xff0c;包括字符过滤、分词和标记过滤&#xff0c;共同决定…...

SpringBoot(一)创建一个简单的SpringBoot工程

Spring框架常用注解简单介绍 SpringMVC常用注解简单介绍 SpringBoot&#xff08;一&#xff09;创建一个简单的SpringBoot工程 SpringBoot&#xff08;二&#xff09;SpringBoot多环境配置 SpringBoot&#xff08;三&#xff09;SpringBoot整合MyBatis SpringBoot&#xff08;四…...

简述Vue中的数据双向绑定原理

Vue中的数据双向绑定原理是Vue框架的核心特性之一&#xff0c;它通过数据劫持结合发布者-订阅者模式来实现。下面将详细阐述Vue中数据双向绑定的原理&#xff0c;并尽量按照清晰的结构进行归纳&#xff1a; 一、数据劫持 使用Object.defineProperty()&#xff1a; Vue在组件…...

C++STL函数对象的应用

STL函数对象 文章目录 STL函数对象1.基本概念2.使用方法1. 简单函数对象示例2. 函数对象作为算法参数3. Lambda表达式作为函数对象 2.一元谓词和二元谓词1.一元谓词2.二元谓词3.总结 3.算术仿函数1.使用示例2.Lambda表达式的替代 4.关系仿函数5.逻辑仿函数 C中的函数对象&#…...

AJAX-day1:

注&#xff1a;文件布局&#xff1a; 一、AJAX的概念&#xff1a; AJAX是浏览器与服务器进行数据通信的技术 >把数据变活 二、AJAX的使用&#xff1a; 使用axios库&#xff0c;与服务器进行数据通信 基于XMLHttpRequest封装&#xff0c;代码简单 Vue,React项目使用 学习…...

昆虫学(书籍学习资料)

包括昆虫分类&#xff08;上下册&#xff09;、昆虫生态大图鉴等书籍资料。...

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列表消失怎么办?

我们的电脑网络偶尔会出现异常&#xff0c;我们通常会下意识选择网络诊断&#xff0c;运行完诊断后一般会让我们选择重置网络&#xff0c;然而&#xff0c;重置后wifi列表突然消失&#xff0c;无法愉快地上网了&#xff0c;找了一圈&#xff0c;都说是更改适配器选项&#xff0…...

Python + 在线 + 文生音,音转文(中文文本转为英文语音,语音转为中文文本)

开源模型 平台&#xff1a;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 的公差的所有询问&#xff0c;我们直接计算该公差后缀和&#xf…...

基于深度学习的图像背景剔除

在过去几年的机器学习领域&#xff0c;我一直想打造真正的机器学习产品。 几个月前&#xff0c;在参加了精彩的 Fast.AI 深度学习课程后&#xff0c;似乎一切皆有可能&#xff0c;我有机会&#xff1a;深度学习技术的进步使许多以前不可能实现的事情成为可能&#xff0c;而且开…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...