Skip to content

Instantly share code, notes, and snippets.

@robbie01
Last active December 27, 2021 01:44
Show Gist options
  • Save robbie01/f14c230d291f3cbdb562000ce2ddb699 to your computer and use it in GitHub Desktop.
Save robbie01/f14c230d291f3cbdb562000ce2ddb699 to your computer and use it in GitHub Desktop.
void+sndio volume controller and manager script
#!/usr/bin/perl
# i wouldn't recommend using this in its current state. because it uses sndioctl instead
# of using libsndio directly, there's pretty much no way to detect server restarts &c.
# this will be rewritten as a small C program soon.
# this is intended to be run as a per-user service
# https://docs.voidlinux.org/config/services/user-services.html
use strict;
use warnings;
use IO::Socket::UNIX;
use File::Slurper qw(read_text write_text);
my $vol;
sub detect_output {
# this is extremely platform dependent. figure out how to muck with /proc/asound for your machine
open(my $codec, "<", "/proc/asound/PCH/codec#0");
my $hit = 0;
while (<$codec>) {
/Node 0x1b/ and $hit = 1;
if ($hit && /Pin-ctls/) {
$vol = /OUT/ ? "./vol_spkr" : "./vol_hp";
last;
}
}
close $codec;
}
sub run_cmd {
my $cmd = shift;
my $out = `sndioctl $cmd`;
$? and die "sndiod is down";
write_text $vol, $out;
}
sub restore_vol {
my $cmd = read_text($vol);
run_cmd $cmd;
}
detect_output;
restore_vol;
my $acpi = IO::Socket::UNIX->new(
Type => SOCK_STREAM(),
Peer => "/run/acpid.socket"
);
while (<$acpi>) {
chomp;
my @event = split;
if ($event[0] eq "button/volumedown") { run_cmd "output.level=-0.05"; }
elsif ($event[0] eq "button/volumeup") { run_cmd "output.level=+0.05"; }
elsif ($event[0] eq "jack/headphone") {
if ($event[2] eq "unplug") { $vol = "./vol_spkr"; }
elsif ($event[2] eq "plug") { $vol = "./vol_hp"; }
restore_vol;
}
# TODO: implement simulated mute, run detect_output on wakeup, visual feedback, etc.
}
output.level=0.3
output.level=0.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment