Skip to content

Instantly share code, notes, and snippets.

@dasl-
Last active September 17, 2022 22:38
Show Gist options
  • Save dasl-/7e8145f0f8f16e3a94f045b85f7c2733 to your computer and use it in GitHub Desktop.
Save dasl-/7e8145f0f8f16e3a94f045b85f7c2733 to your computer and use it in GitHub Desktop.
# card 2
pi@raspberrypi:~/pifi $ aplay --list-devices
**** List of PLAYBACK Hardware Devices ****
card 0: b1 [bcm2835 HDMI 1], device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
card 2: Device [USB Audio Device], device 0: USB Audio [USB Audio]
Subdevices: 0/1
Subdevice #0: subdevice #0
# numid 6
pi@raspberrypi:~/pifi $ amixer -c 2 controls
numid=10,iface=CARD,name='Keep Interface'
numid=3,iface=MIXER,name='Mic Playback Switch'
numid=4,iface=MIXER,name='Mic Playback Volume'
numid=7,iface=MIXER,name='Mic Capture Switch'
numid=8,iface=MIXER,name='Mic Capture Volume'
numid=9,iface=MIXER,name='Auto Gain Control'
numid=5,iface=MIXER,name='Speaker Playback Switch'
numid=6,iface=MIXER,name='Speaker Playback Volume'
numid=2,iface=PCM,name='Capture Channel Map'
numid=1,iface=PCM,name='Playback Channel Map'
diff --git a/pifi/volumecontroller.py b/pifi/volumecontroller.py
index b579fee..b85f741 100644
--- a/pifi/volumecontroller.py
+++ b/pifi/volumecontroller.py
@@ -6,17 +6,18 @@ import math
class VolumeController:
# Anything higher than 0 dB may result in clipping.
- __LIMITED_MAX_VOL_VAL = 0
+ __LIMITED_MAX_VOL_VAL = 30
# amixer output: ; type=INTEGER,access=rw---R--,values=1,min=-10239,max=400,step=0
# These values are in millibels.
- GLOBAL_MIN_VOL_VAL = -10239
- GLOBAL_MAX_VOL_VAL = 400
+ GLOBAL_MIN_VOL_VAL = 0
+ GLOBAL_MAX_VOL_VAL = 30
# gets a perceptual loudness %
# returns a float in the range [0, 100]
def get_vol_pct(self):
mb_level = self.get_vol_millibels()
+ return mb_level / 30 * 100
if mb_level <= self.GLOBAL_MIN_VOL_VAL:
return 0
@@ -31,8 +32,12 @@ class VolumeController:
# takes a perceptual loudness %.
# vol_pct should be a float in the range [0, 100]
def set_vol_pct(self, vol_pct):
- mb_level = round(VolumeController.pct_to_millibels(vol_pct))
- subprocess.check_output(('amixer', 'cset', 'numid=1', '--', str(mb_level)))
+ vol_pct = max(0, vol_pct)
+ vol_pct = min(100, vol_pct)
+
+ val_to_set = round(vol_pct / 100 * 30)
+
+ subprocess.check_output(('amixer', '-c', '2', 'cset', 'numid=6', '--', str(val_to_set)))
# increments volume percentage by the specified increment. The increment should be a float in the range [0, 100]
# Returns the new volume percent, which will be a float in the range [0, 100]
@@ -44,16 +49,16 @@ class VolumeController:
self.set_vol_pct(new_vol_pct)
return new_vol_pct
- # Return volume in millibels. Returns an integer in the range [self.GLOBAL_MIN_VOL_VAL, 0]
+ # Return volume in millibels. Returns an integer in the range [self.GLOBAL_MIN_VOL_VAL, self.__LIMITED_MAX_VOL_VAL]
def get_vol_millibels(self):
- res = subprocess.check_output(('amixer', 'cget', 'numid=1')).decode("utf-8")
+ res = subprocess.check_output(('amixer', '-c', '2', 'cget', 'numid=6')).decode("utf-8")
m = re.search(r" values=(-?\d+)", res, re.MULTILINE)
if m is None:
return self.GLOBAL_MIN_VOL_VAL
mb_level = int(m.group(1))
mb_level = max(self.GLOBAL_MIN_VOL_VAL, mb_level)
- mb_level = min(0, mb_level)
+ mb_level = min(self.__LIMITED_MAX_VOL_VAL, mb_level)
return mb_level
# Map the volume from [0, 100] to [0, 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment