evisum/src/tingle/volctl

143 lines
2.9 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
my $OS = $^O;
sub Error {
my ($str) = @_;
print STDERR "Error: $str\n";
exit (0 << 1);
}
sub mixer_levels_get {
my ($left, $right) = @_;
my $pipe_cmd = "";
if ($OS eq "openbsd" || $OS eq "netbsd")
{
$pipe_cmd = "mixerctl outputs.master|";
}
elsif ($OS eq "freebsd" || $OS eq "dragonfly")
{
$pipe_cmd = "mixer vol|";
}
elsif ($OS eq "darwin")
{
$pipe_cmd = "osascript -e 'get volume settings'|";
}
elsif ($OS eq "linux")
{
$pipe_cmd = "amixer get Master|";
}
open P, "$pipe_cmd" || die "Unable to determine mixer!\n";
my @lines = <P>;
close P;
my $have_mixer = 0;
foreach my $line (@lines)
{
if ($line =~ m/Left:.*\[(\d+)%\]/)
{
$$left = $1;
$have_mixer = 1;
}
if ($line =~ m/Right:.*\[(\d+)%\]/)
{
$$right = $1;
$have_mixer = 1;
}
if ($line =~ m/\Aoutput\svolume:(\d+),/)
{
$$left = $$right = $1;
return 1;
}
elsif ($line =~ m/(\d+),(\d+)/ || $line =~ m/(\d+):(\d+)/)
{
$$left = $1;
$$right = $2;
return 1;
}
}
return $have_mixer;
}
sub mixer_levels_set {
my ($new_left, $new_right) = @_;
my $cmd = "";
close (STDOUT);
if ($OS eq "openbsd" || $OS eq "netbsd")
{
$cmd = "mixerctl outputs.master=$new_left,$new_right";
}
elsif ($OS eq "freebsd" || $OS eq "dragonfly")
{
$cmd = "mixer $new_left:$new_right"
}
elsif ($OS eq "darwin")
{
my $greatest = $new_left > $new_right ? $new_left : $new_right;
my $ratio = 7 / 100;
my $volume = $greatest * $ratio;
$cmd = "osascript -e 'set volume $volume'";
}
elsif ($OS eq "linux")
{
my $greatest = $new_left > $new_right ? $new_left : $new_right;
$cmd = "amixer set \"Master\" $greatest%";
}
return system($cmd);
}
sub main {
my (@args) = @_;
my $argc = scalar(@args);
my ($inc, $dec) = (0, 0);
my ($left, $right) = (0, 0);
for (my $i = 0; $i < $argc; $i++)
{
if ($args[$i] =~ /\+(\d+)/)
{
$inc = $1;
}
if ($args[$i] =~ /\-(\d+)/)
{
$dec = $1
}
}
if (!mixer_levels_get(\$left, \$right))
{
Error("couldn't get current volumes");
}
$left -= $dec; $right -= $dec;
$left += $inc; $right += $inc;
if ($OS eq "linux" || $OS eq "darwin" || $OS eq "freebsd" || $OS eq "dragonfly")
{
if ($left < 0) { $left = 0; };
if ($left > 100) { $left = 100; };
if ($right < 0) { $right = 0; };
if ($right > 100) { $right = 100 };
}
return mixer_levels_set($left, $right);
}
exit(main(@ARGV));