#!/usr/bin/perl # powermixer 1.0 # (c) 2002 Alex Efros # %mixer = Mixer(); # GET # %mixer = Mixer(%mixer); # SET sub Mixer { my %MIXER = @_; # from /usr/include/linux/soundcard.h : my $SOUND_MIXER_READ_DEVMASK = 0x80044dfe; my $SOUND_MIXER_READ_STEREODEVS = 0x80044dfb; my $SOUND_MIXER_NRDEVICES = 25; my $MIXER_READ = 0x80044d00; my $MIXER_WRITE = 0xc0044d00; my @SOUND_DEVICE_NAMES = (qw(vol bass treble synth pcm speaker line mic cd mix pcm2 rec igain ogain line1 line2 line3 dig1 dig2 dig3 phin phout video radio monitor)); my @SOUND_DEVICE_LABELS = (qw(Vol Bass Trebl Synth Pcm Spkr Line Mic CD Mix Pcm2 Rec IGain OGain Line1 Line2 Line3 Digital1 Digital2 Digital3 PhoneIn PhoneOut Video Radio Monitor)); # open mixer open my $MIXER, '+< /dev/mixer' or die "open: $!"; ioctl $MIXER, $SOUND_MIXER_READ_DEVMASK, $devmask or die "SOUND_MIXER_READ_DEVMASK"; ioctl $MIXER, $SOUND_MIXER_READ_STEREODEVS, $stereod or die "SOUND_MIXER_READ_STEREODEVS"; my $devmask = unpack "V", $devmask; my $stereod = unpack "V", $stereod; die "No device found.\n" unless $devmask; # set mixer for (values %MIXER) { next unless exists $_->{id} and $_->{id} >= 0 and $_->{id} < $SOUND_MIXER_NRDEVICES; next unless $_->{exist} and ($devmask & (1 << $_->{id})); $_ = ($_ < 0) ? 0 : ($_ > 100) ? 100 : $_ for $_->{left}, $_->{right}; my $val = pack "V", ($stereod & (1 << $_->{id})) ? ($_->{left} | ($_->{right} << 8)) : $_->{left}; ioctl $MIXER, $MIXER_WRITE | $_->{id}, $val or die "MIXER_WRITE"; } # get mixer %MIXER = map { $SOUND_DEVICE_LABELS[$_] => { id => $_, label => $SOUND_DEVICE_LABELS[$_], name => $SOUND_DEVICE_NAMES[$_], exist => 0, stereo => 0, left => 0, right => 0, } } 0 .. ($SOUND_MIXER_NRDEVICES-1); for (values %MIXER) { next unless $_->{exist} = ($devmask & (1 << $_->{id})) ? 1 : 0; ioctl $MIXER, $MIXER_READ | $_->{id}, my $val or die "MIXER_READ"; $val = unpack "V", $val; $_->{left} = $val & 0x007f; $_->{right} = ($val & 0x7f00) >> 8 if $_->{stereo} = ($stereod & (1 << $_->{id})) ? 1 : 0; } close $MIXER or die "close: $!"; return %MIXER; } my %m = Mixer(); # restore mixer from /etc/aumixrc for (`/bin/cat /etc/aumixrc`) { my ($name, $left, $right) = split /:/; ($_->{left}, $_->{right}) = ($left, $right) for grep {$_->{name} eq $name} values %m; } Mixer(%m);