ALSA Volume Script
From Superk
(Redirected from ASLA Volume Script)
#! /usr/bin/perl -w
#
# Adjust ALSA master volume up/down or report current volume. Can also
# mute or unmute the volume.
#
# Written by Ewen McNeill <ewen@naos.co.nz>, 2003/10/11
#---------------------------------------------------------------------------
use strict;
my $MIXER='/usr/bin/amixer';
my $UNMUTE="numid=1,iface=MIXER,name='Master Playback Switch'";
my $VOLUME="numid=2,iface=MIXER,name='Master Playback Volume'";
my %ACTION_DECODE =
(
'up' => 'up',
'+1' => 'up',
'+' => 'up',
'down' => 'down',
'-1' => 'down',
'-' => 'down',
'mute' => 'mute',
'0' => 'mute',
'unmute' => 'unmute',
'1' => 'unmute',
'toggle' => 'toggle',
'show' => 'show'
);
my $USAGE="$0 {up|down|mute|unmute|toggle|show}";
#---------------------------------------------------------------------------
# Get existing mixer settings
#
# Input: path to a (complex) mixer setting
#
# Returns: minimum value, maximum value, current value (left then right,
# or one value for mono)
#
# NOTE: Boolean values are cooerced into 0 or 1 (true/false)
#
# Example output from mixer command:
#
# $ amixer cget numid=1,iface=MIXER,name='Master Playback Switch'
# numid=1,iface=MIXER,name='Master Playback Switch'
# ; type=BOOLEAN,access=rw---,values=1
# : values=on
#
# $ amixer cget numid=2,iface=MIXER,name='Master Playback Volume'
# numid=2,iface=MIXER,name='Master Playback Volume'
# ; type=INTEGER,access=rw---,values=2,min=0,max=31,step=0
# : values=24,23
#
sub get_mixer_value
{
my ($control)=@_;
return undef unless defined($control);
open(MIXER, "$MIXER cget $control|") or
do { warn "Cannot run $MIXER!\n"; return undef; };
my ($min, $max, $left, $right);
while(<MIXER>)
{
# Boolean
if (/^\s*:.*values=on/) { $left=1; $min=0; $max=1; }
if (/^\s*:.*values=off/) { $left=0; $min=0; $max=1; }
# Integer
if (/^\s*;.*min=(\d+)/) { $min=$1; }
if (/^\s*;.*max=(\d+)/) { $max=$1; }
if (/^\s*:.*values=(\d+),(\d+)/) { ($left,$right)=($1,$2); next; }
if (/^\s*:.*values=(\d+)/) { ($left)=($1); next; }
}
close(MIXER);
return ($min, $max, $left, $right);
}
#---------------------------------------------------------------------------
# Set a mixer value
#
# Input: name of (complex) mixer control, value(s) to set
#
sub set_mixer_value
{
my ($control,@values) = @_;
return undef unless (defined($control) && defined($values[0]));
# warn ("$MIXER cset $control " . join(",", @values) . ">/dev/null\n");
system("$MIXER cset $control " . join(",", @values) . " >/dev/null");
return 1;
}
#---------------------------------------------------------------------------
# Mainline
#
my ($mmin, $mmax, $mleft, $mright) = get_mixer_value($UNMUTE);
my ($vmin, $vmax, $vleft, $vright) = get_mixer_value($VOLUME);
#
my $action=$ARGV[0];
$action=$ACTION_DECODE{$action} if (defined($action));
if (defined($action))
{
if ($action eq 'up')
{
set_mixer_value($VOLUME, $vleft+1, $vright+1);
set_mixer_value($UNMUTE, 1);
}
if ($action eq 'down')
{
set_mixer_value($VOLUME, (($vleft-1 > 0) ? ($vleft-1) : 0),
(($vright-1 > 0) ? ($vright-1) : 0));
set_mixer_value($UNMUTE, 1);
}
if ($action eq 'mute')
{
set_mixer_value($UNMUTE, 0);
}
if ($action eq 'unmute')
{
set_mixer_value($UNMUTE, 1);
}
if ($action eq 'toggle')
{
set_mixer_value($UNMUTE, (! $mleft));
}
# Reload mixer values after changes
($mmin, $mmax, $mleft, $mright) = get_mixer_value($UNMUTE);
($vmin, $vmax, $vleft, $vright) = get_mixer_value($VOLUME);
}
elsif (defined($ARGV[0]))
{
warn "Unrecognised option: $ARGV[0]\n$USAGE\n";
}
#
printf "Master Volume: left: %d (%d%%); right: %d (%d%%)%s\n",
$vleft, int(($vleft-$vmin)*100/($vmax-$vmin)),
$vright, int(($vright-$vmin)*100/($vmax-$vmin)),
($mleft ? "" : " (*MUTED*)");
