如何在命令行中控制均衡器?
所以 Pulseaudio 有一個內置的均衡器
模組均衡器接收器
根據http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Equalizer,您可以使用 qpaeq GUI 控制它。
有沒有辦法在 Xless 系統上配置 PA 均衡器(在會話模式下執行)?
pulseaudio 均衡器正在讀取使用者文件**~/.config/pulse/equalizerrc中的設置**
要顯示它:
cat ~/.config/pulse/equalizerrc
因此,例如,在 eq 的第 5 個波段上給出 10DB 的值,並直接聽到變化:
sed -i '19s/.*/10.0/' ~/.config/pulse/equalizerrc | pulseaudio-equalizer toggle
為了進一步解釋,sed將替換所有編號為19的行,並將其替換為配置文件中的10.0,然後重新啟動/切換均衡器以獲得結果。
這是一個腳本,改編自
qpaeq
Pulseaudio 附帶的腳本:#!/usr/bin/env python # pulse-set-eq import os,math,sys import dbus # Source adapted from utils/qpaeq of PulseAudio def connect(): # copied from qpaeq try: if 'PULSE_DBUS_SERVER' in os.environ: address = os.environ['PULSE_DBUS_SERVER'] else: bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet. server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1') address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties') return dbus.connection.Connection(address) except Exception as e: sys.stderr.write('There was an error connecting to pulseaudio, ' 'please make sure you have the pulseaudio dbus ' 'module loaded, exiting...\n') sys.exit(-1) def get_sink(str): connection=connect() path='/org/pulseaudio/core1/sink%s'%str sink=connection.get_object(object_path=path) return sink args = sys.argv[1:] if len(args)<5: print("Usage: "+sys.argv[0]+" SINK_NUM CHANNEL_NUM PREAMP_VALUE FREQ1 COEF1 [FREQ2 COEF2...]") sys.exit() sinknum = args.pop(0); sink = get_sink(sinknum); prop_iface='org.freedesktop.DBus.Properties' eq_iface='org.PulseAudio.Ext.Equalizing1.Equalizer' sink_props=dbus.Interface(sink,dbus_interface=prop_iface) def get_eq_attr(attr): return sink_props.Get(eq_iface,attr) sample_rate=get_eq_attr('SampleRate') filter_rate=get_eq_attr('FilterSampleRate') nchannels=get_eq_attr('NChannels') sys.stderr.write('channels %d, sample rate: %f, filter sample rate: %f\n'% (nchannels, sample_rate, filter_rate)) channel = int(args.pop(0)); preamp = float(args.pop(0)); freqs = []; coeffs = []; while len(args) > 0: if len(args)==1: sys.stderr.write('Odd number of frequency/amplification arguments (%d)\n'%(len(freqs)*2+1)) sys.exit(-1) sys.stderr.write('(%s, %s)\n'%(args[0],args[1])) freqs.append(float(args.pop(0))) coeffs.append(float(args.pop(0))) #sys.stderr.write("freqs: "+str(freqs)+'\n'); freqs = list([int(round(x*filter_rate/sample_rate)) for x in freqs]) #sys.stderr.write("translated freqs: "+str(freqs)+'\n'); freqs = [0]+freqs+[filter_rate//2]; coeffs = [coeffs[0]]+coeffs+[coeffs[-1]]; #sys.stderr.write("proper freqs: "+str(freqs)+'\n'); # for some reason this fixes the types of the arguments to SeedFilter sink=dbus.Interface(sink,dbus_interface=eq_iface) # set the filter coefficients sink.SeedFilter(channel,freqs,coeffs,preamp)
用法 :
使用 獲取接收器編號
pacmd list-sinks
,然後./pulse-set-eq SINK_NUM CHANNEL_NUM PREAMP_VALUE FREQ1 COEF1 [FREQ2 COEF2 …]
請注意,似乎 CHANNEL_NUM 0 將對應於第一個通道,1 對應於第二個等,如果您使用實際的通道數(例如,如果您有兩個通道,則為 2)它將為所有通道設置均衡。
您可以使用 隨時檢查應用的設置
qpaeq
。先決條件:
請注意,首先您要載入均衡器模組以及 DBus 協議模組:
pactl load-module module-dbus-protocol pactl load-module module-equalizer-sink sink_name=... sink_master=... pactl set-default-sink ...
玩劇本
然後發出一些噪音,或音樂或其他任何東西:
play -n synth pinknoise gain -10
然後使用接收器編號、要應用均衡器的通道索引、前置放大器(縮放)因子和(頻率、係數)對列表呼叫腳本。頻率列表不必很密集,因為它被插值(參見 參考資料
seed_filter
)pulseaudio/src/modules/module-equalizer-sink.c
以獲得濾波器係數。如果您將通道總數指定為通道索引,則更新適用於所有通道。用於pacmd list-sinks
獲取接收器編號。例如,如果接收器編號是 $SINKNUM 並且它有 2 個通道,那麼這會將均衡器重置為全 1,您可以通過打開來驗證
qpaeq
:./pulse-set-eq $SINKNUM 2 1.0 100 1.0
這裡 100 Hz 是任意的;列表不能為空,不能從零開始。頻率必須在 0 到 32768 之間(對我來說是最大值,不確定它是否可配置,請參見
filter_rate
上面的變數 - 這是一半)。該腳本使用命令行中指定的最小和最大頻率的放大係數,分別用於低於和高於這些頻率的頻率,因此在這種情況下,整個頻譜將被分配為 1.0 的放大率。在此設置下,均衡器將保持信號不變(至少理論上如此)。注意不要損壞您的揚聲器,但例如,您可以通過創建粉紅雜訊並將均衡器設置為單個頻率(500Hz)的尖峰(放大 100 倍)來玩弄:
./pulse-set-eq $SINKNUM 2 1.0 499 0 500 100 501 0
當我這樣做時,我可以聽到不同隨機音量的離散連續音調,全部為 500Hz,我認為它們屬於濾波器實現中的連續 DFT 視窗。這有點令人愉快。通過這個過濾器播放音樂很有趣。使用沒有命令行版本的普通圖形均衡器是不可能實現如此清晰的“帶通”的。
下面的例子製作了一個頻率上下波動的濾波器,有點像警報器。顯然,您必須播放一些音樂或噪音或其他東西才能聽到效果。
SINKNUM=12; NCHAN=2; while true; do for i in $(seq 500 10 1500) $(seq 1500 -10 500); do ./pulse-set-eq $SINKNUM $NCHAN 1 \ 0 1 $(( $i - 300 )) 1 \ $i 5 $(( $i + 300 )) 1 \ 32768 1; done; done