Matt Fiddles

Life's so vast, there's just so much to do...

User Tools

Site Tools


Sidebar

"The young man knows the rules, but the old man knows the exceptions."



Where will you go today?

"Arthur hoped and prayed that there wasn't an afterlife. Then he realised there was a contradiction there and merely hoped that there wasn't an afterlife."

- Arthur realising that he's in a certain death situation with a supernova bomb that is shaped like a cricket ball.
computers:linux:fix-audio-volume

Fix Audio Volume

I have an audio player that likes to change the volume for some songs. Sure, I told it not to, but it just won't listen. When it tries to lower the volume, it sends the Master volume to 0%, muting it. So I wrote a quick bash script to fix that.

Uses amixer to fix the audio. You'll prob have to modify it for your needs, but it's a nice starting point.

Perl version:

fix-audio-volume.pl
#!/usr/bin/perl
 
# useful commands to get info:
# amixer scontrols
# amixer info
# for main card:
# amixer -c 0 scontrols
# amixer -c 0 scontents
 
# required that right and left channels be the same. Just so you know...
 
use strict;
 
# increase volume if already off
my $master_min=2;
my $master_default=9;
 
# sub to get the volume for a card's control (or pulse by default)
sub get_volume_for {
	my ($device,$control)=@_;
	# print "amixer $device sget $control\n";
	my $output=`amixer $device sget \'$control\'`;
	# print $output;
	foreach ($output) {
		# find the first [xy%]
		if ( m/\[(\d+)%\]/ ) {
			# print "$1\n";
			return int($1);
		}
	}
	return 0;
}
 
my ($master_saved,$pcm_saved,$headphone_saved,$master_pulse_saved)=0;
my ($master_test,$pcm_test,$headphone_test,$master_pulse_test)=0;
 
# main
while ( 1 ) {
 
  # get current master volume
  $master_test=get_volume_for("-c 0",'Master');
  $pcm_test=get_volume_for("-c 0",'PCM');
  $headphone_test=get_volume_for("-c 0",'Headphone');
  # get master for pulseaudio. Note that we don't specify a card
  $master_pulse_test=get_volume_for("",'Master');
  # save if its not below min
  # print "Test: $master_test Min: $master_min Saved: $master_saved\n";
  if ( $master_test > $master_min ) {
    $master_saved=$master_test;
  }
  else {
    # otherwise reset to what it was before, or above min
    # check that master is greater than the min (ie, did we save it?)
    $master_saved=$master_default if ( $master_saved < $master_min );
    # reset volume
    print "Reset master volume to $master_saved\n";
    print "PCM was at $pcm_saved - now at $pcm_test\n";
    print "Headphone was at $headphone_saved - now at $headphone_test\n";
    print "Master (pulse) was at $master_pulse_saved - now at $master_pulse_test\n";
    system("amixer","-c","0","sset",'Master',"${master_saved}%");
  }
  $master_pulse_saved=$master_pulse_test;
  $pcm_saved=$pcm_test;
  $headphone_saved=$headphone_test;
 
  sleep 10;
 
}

Old bash version:

fix-audio-volume
#!/bin/bash
 
# useful commands to get info:
# amixer scontrols
# amixer info
# for main card:
# amixer -c 0 scontrols
# amixer -c 0 scontents
 
# set minimum volume
master_min=2
# what it set it to if we haven't saved it
master_default=9
 
 
# main
master_saved=0
while [ 1 ] ; do
 
  # get current master volume
  master_test=$($amixer -c 0 sget 'Master' | grep '%' | head -n 1 | \
     cut -f2 -d'[' | cut -f1 -d']' | sed 's/%//' )
  master_pulse_test=$($amixer sget 'Master' | grep '%' | head -n 1 | \
     cut -f2 -d'[' | cut -f1 -d']' | sed 's/%//' )
  pcm_test=$($amixer -c 0 sget 'PCM' | grep '%' | head -n 1 | \
     cut -f2 -d'[' | cut -f1 -d']' | sed 's/%//' )
  headphone_test=$($amixer -c 0 sget 'Headphone' | grep '%' | head -n 1 | \
     cut -f2 -d'[' | cut -f1 -d']' | sed 's/%//' )
  # save if its not below min
  if [ $master_test -ge $master_min ] ; then
    master_saved=$master_test
  else
    # otherwise reset to what it was before, or above min
    # check that master is greater than the min (ie, did we save it?)
    [ $master_saved -ge $master_min ] || master_saved=$master_default
    # reset volume
    echo "Reset master volume to $master_saved"
    echo "PCM was at $pcm_saved - now at $pcm_test"
    echo "Headphone was at $headphone_saved - now at $headphone_test"
    echo "Master (pulse) was at $master_pulse_saved - now at $master_pulse_test"
    $amixer -c 0 sset 'Master' ${master_saved}%
  fi
  master_pulse_saved=$master_pulse_test
  pcm_saved=$pcm_test
  headphone_saved=$headphone_test
 
  sleep 10
 
done
computers/linux/fix-audio-volume.txt · Last modified: May 31, 2014 (4 years ago) by Matt Bagley