【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]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41429.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41429.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41429.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux下php的psr.so擴展源碼安裝

cd /usr/local/src git clone https://github.com/jbboehr/php-psr.git cd php-psr /usr/local/php/bin/phpize ./configure --with-php-config/usr/local/php/bin/php-config make make install在php.ini中添加extensionpsr.so 重啟php-fpm /etc/init.d/php-fpm relo…

打卡第3天---鏈表相關

除了每天自己寫博客總結我個人的學習收獲情況之外,我也會看其他錄友寫的博客文章,對于其他錄友的博客內容在代碼隨想錄的訓練營都是開誠布公的,都能互相看到。彼此學習,彼此參照,有一位錄友思路很清晰呀,用畫圖軟件把自己對題的思路畫的特別清晰,我 應該向他們學習;除此…

從零開始使用 Docsify 搭建文檔站點

引言 在當今的技術環境中,擁有一份易于訪問和美觀的文檔是至關重要的。Docsify 是一個非常適合快速搭建文檔站點的工具,它簡單易用,且不需要生成靜態文件。本文將帶你一步步從零開始使用 Docsify 搭建一個文檔站點。 1. 安裝 Node.js 和 np…

【ARMv8/v9 GIC 系列 5.1 -- GIC GICD_CTRL Enable 1 of N Wakeup Function】

請閱讀【ARM GICv3/v4 實戰學習 】 文章目錄 GIC Enable 1 of N Wakeup Function基本原理工作機制配置方式應用場景小結GIC Enable 1 of N Wakeup Function 在ARM GICv3(Generic Interrupt Controller第三代)規范中,引入了一個名為"Enable 1 of N Wakeup"的功能。…

上海市計算機學會競賽平臺2023年2月月賽丙組區間的并

題目描述 給定一個數軸上的 𝑛n 個閉區間,第 𝑖i 個閉區間的兩端點為[𝑎𝑖,𝑏𝑖][ai?,bi?],它們的并集可以表示為若干不相交的閉區間,請按照左端點從小到大的順序輸出…

(一)Docker基本介紹

部署項目的發展 傳統部署適合需要最大性能和可靠性的場景,但在資源利用和管理方面有顯著劣勢。虛擬化部署提供了良好的資源利用率和隔離性,適用于需要靈活擴展和多租戶環境的場景,但存在性能開銷。容器部署在輕量級、可移植性和資源利用率方面…

適合金融行業的國產傳輸軟件應該是怎樣的?

對于金融行業來說,正常業務開展離不開文件傳輸場景,一般來說,金融行業常用的文件傳輸工具有IM通訊、郵件、自建文件傳輸系統、FTP應用、U盤等,這些傳輸工具可以基礎實現金融機構的文件傳輸需求,但也存在如下問題&#…

【Java10】成員變量與局部變量

Java中的變量只有兩種:成員變量和局部變量。 和C不同,沒有全局變量了。 成員變量,field,我習慣稱之為**”屬性“**(但這些年,因為attribute更適合被叫做屬性,所以漸漸不這么叫了)。 …

google 郵件信息收集

主要介紹通過google和fofax對目標進行郵件信息收集 chrome插件 email-whatsapp-extractor link-klipper-extract-all bulk-url-opener-extension email-whatsapp-extractor 使用正則表達式,獲取訪問頁面內所有的email郵箱和whatsapp號碼,以表格的形式導…

el-table封裝點擊列篩選行數據功能,支持篩選,搜索,排序功能

數據少的話&#xff0c;可以前端實現&#xff0c;如果多的話&#xff0c;建議還是請求接口比較合理父組件&#xff1a; <template> <div class"home"> <!-- <img alt"Vue logo" src"../assets/logo.png"> <HelloWorld …

Hilbert編碼 思路和scala 代碼

需求&#xff1a; 使用Hilbert 曲線對遙感影像瓦片數據進行編碼&#xff0c;獲取某個區域的編碼值即可 Hilbert 曲線編碼方式 思路 大致可以對四個方向的數據進行歸類 左下左上右上右下 這個也對應著編碼的順序 思考在不同Hilbert深度&#xff08;階&#xff09;情況下的…

【fastadmin開發實戰】經營數據自動識別錄入

項目場景描述&#xff1a;每日錄入各個門店的員工經營數據&#xff0c;直接從微信復制報數、系統識別錄入。 解決方案&#xff1a;各個門店按照固定的匯報模板進行匯報&#xff08;如福田店有員工1、2、3、4、5號員工&#xff0c;每個員工按模板報數&#xff09; 例如&#xf…

Qt學習:Qt窗口組件以及窗口類型

一、Qt的窗口組件有哪些 Qt是一個跨平臺的C應用程序開發框架&#xff0c;它的窗口組件&#xff0c;也稱為用戶界面元素&#xff0c;為開發者提供了豐富的可視化界面設計選項。在Qt中&#xff0c;窗口組件主要包括&#xff1a; 窗口&#xff08;Window&#xff09;&#xff1a;…

JMH320【親測】【御劍九歌】唯美仙俠手游御劍九歌+WIN學習手工端+視頻教程+開服清檔+運營后臺+授權GM物品充值后臺

資源介紹&#xff1a; 這也是仙夢奇緣的一個游戲 注意&#xff1a;外網14位IP或域名 ———————————————————————————————————– ps后臺介紹: 1區運營后臺&#xff1a;http://ip:9981/admin/admintool/ 2區運營后臺&#xff1a;http://ip…

Day44:LeedCode 188.買賣股票的最佳時機IV 309.最佳買賣股票時機含冷凍期 714.買賣股票的最佳時機含手續費

188. 買賣股票的最佳時機 IV 給你一個整數數組 prices 和一個整數 k &#xff0c;其中 prices[i] 是某支給定的股票在第 i 天的價格。 設計一個算法來計算你所能獲取的最大利潤。你最多可以完成 k 筆交易。也就是說&#xff0c;你最多可以買 k 次&#xff0c;賣 k 次。 注意&…

[深度學習]卷積理解

單通道卷積 看這個的可視化就很好理解了 https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md 多通道卷積 當輸入有多個通道時,卷積核需要擁有相同的通道數. 假設輸入有c個通道,那么卷積核的每個通道分別于相應的輸入數據通道進行卷積,然后將得到的特征圖對…

51單片機STC89C52RC——14.1 直流電機調速

目錄 目的/效果 1&#xff1a;電機轉速同步LED呼吸燈 2 通過獨立按鍵 控制直流電機轉速。 一&#xff0c;STC單片機模塊 二&#xff0c;直流電機 2.1 簡介 2.2 驅動電路 2.2.1 大功率器件直接驅動 2.2.2 H橋驅動 正轉 反轉 2.2.3 ULN2003D 引腳、電路 2.3 PWM&…

智能光伏開發都能用到什么軟件和工具?

隨著全球對可再生能源的日益重視和光伏技術的快速發展&#xff0c;智能光伏開發已成為推動能源轉型的重要力量。在光伏項目的全生命周期中&#xff0c;從設計、建設到運營管理&#xff0c;各種軟件和工具的應用發揮著至關重要的作用。 一、光伏系統設計軟件 1、PVsyst PVsyst…

Linux 端口

什么是虛擬端口 計算機程序之間的通訊&#xff0c;通過IP只能鎖定計算機&#xff0c;但是無法鎖定具體的程序。通過端口可以鎖定計算機上具體的程序&#xff0c;確保程序之間進行溝通。 IP地址相當于小區地址&#xff0c;在小區內可以有許多用戶&#xff08;程序&#xff09;&…

java并發編程 JUC-基礎篇 快速入門

1.進程與線程的概念 &#xff08;1&#xff09;進程 程序有指令與數據組成&#xff0c;指令要運行&#xff0c;數據要讀寫&#xff0c;就必須指令加載到CPU。數據加載到內容&#xff0c;指令運行需要用到磁盤。 當一個程序被運行時&#xff0c;從磁盤加載這個程序的代碼至內…