Change Volume From a Bash Script

 in

If you use ALSA for sound on your system the functions contained in the script presented here can be used to get and set the volume on your system. You might use this if you had a monitoring script running and wanted to raise the volume when you signal an alarm and then lower it again to the previous volume.

The get function uses amixer to output the information for the simple mixer control "Master" and then uses grep and cut to get the correct value from the output.

The set function also uses amixer to set the volume. It uses the "cset" option to amixer.

The script follows:

#!/bin/bash
#

#####################################################################
# Get current volume.
function get_volume()
{
    mixer=$(amixer get Master | grep 'Front Left:')
    echo $mixer | cut -d ' ' -f 4
}


#####################################################################
# Set volume.
function set_volume()
{
    amixer cset iface=MIXER,name="Master Playback Volume" $1 >/dev/null
}

if [[ $(basename $0 .sh) == 'sound' ]]; then
    sound_file=~/Documents/sounds/notify.wav
    if [[ "$1" ]]; then sound_file="$1"; fi

    ovol=$(get_volume)
    echo "Current volume: $ovol"
    aplay $sound_file
    sleep 2

    vol=40
    echo "Playing at: $vol"
    set_volume $vol
    aplay $sound_file
    sleep 2

    echo "Again at: $ovol"
    set_volume $ovol
    aplay $sound_file
fi
    

# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;

If you save the script as sound.sh and run it directly passing the name of a sound file it will play the file at the current volume, then it raises the volume and plays it again, and finally it restores the volume and plays it one last time. If you open your mixer controls before running the script you should see the master volume control move as the script changes the volume. You can adjust the value in the line vol=40 to get the volume you want.

______________________

Mitch Frazier is an Associate Editor for Linux Journal.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Bug

Andrew P.'s picture

This script breaks the link between the left and right Master Volume control sliders and doesn't restore it after it finishes. There's probably a parameter missing in the set_volume() function.

It's a good start, though. With a little more work it could be something similar to the nifty "Wizmo" utility created by Steve Gibson (www.grc.com) for Windows machines. It allows one to reset the master volume on system startup to a reasonable level each time (I like 60%), so it won't blast out your eardrums when the system startup theme plays.

FYI, my sound system Master Volume reports limits of 0-65535 (min-max).

Only one?

Mitch Frazier's picture

It probably needs more than a little work.

Sounds like a good time to complain about Linux sound stuff in general: it drives me crazy every time I do anything with it. Input devices show up on the output devices page. You can never tell by reading the names of the devices which device is the one that configures the thing you're looking at. Names like "PWM", "IEC958 Defalt PCM" don't help either: am I building an audio device or just using it?

Mitch Frazier is an Associate Editor for Linux Journal.

Re: only one?

Andrew P.'s picture

I agree with your sentiments. I'm in the process of trying to migrate from the Windows world to Linux (Ubuntu 8.10). The system has much to offer and many things work better and are easier to maintain than anything that has recently come out of Redmond, but I'm appalled at how poorly sound is handled. Sound handling worked better in Windows 95, and that was 15 years ago! My system is regularly plagued with sound from any given application suddenly not working anymore, forcing a system reboot. Or, how about all sound no longer working if I log out and log back in, again forcing a reboot. (Gee, it's just like Windows!) Unfortunately, I also find that there's an arrogance and overconfidence among some long-time *nix users, particularly those involved in the various open source projects believing that Unix and Linux are somehow superior. (Don't look now, guys, but you don't need to worry about them nipping at your heels: You've been left in the dust ages ago!) Sometimes it's worth looking over the fence to see what your neighbor is up to.

Couple of possible short cuts

Mitch Frazier's picture

I've had the sound not working problem also but I've generally been able to get around it without re-booting. First thing I try is restarting Thunderbird and Firefox, particularly Thunderbird (although it's been less problematic as of late).

If that doesn't work then I restart the ALSA subsystem. As root do this:

   /etc/init.d/alsasound restart

This will kill your volume control application, but that's easily restarted.

If your system doesn't use ALSA, restarting whatever it uses may work.

Mitch Frazier is an Associate Editor for Linux Journal.

Just test code

Mitch Frazier's picture

The "vol=40" is just for testing.

Although, I must admit that I'm not actually sure what the acceptable volume ranges are, or for that matter if they are the same on all systems.

ps. if you're playing the "Free Software Song" at 99 then you're probably already deaf and won't hear anything anyways. :)

Mitch Frazier is an Associate Editor for Linux Journal.

Great Article, but set_volume() must be scaled

David Rankin's picture

Mitch,

Great article. The only problem is set_volume() doesn't work correctly because amixer volume range is 0-64, not 0-100. So a quick conversion is required for set_volume() to work:

# Set volume.
function set_volume()
{
## Mixer Volume Range (min=0 max=64);
## you must convert Vol. in % to 0-64 mixer volume range
mixerVol=$(($1*64/100))
amixer cset iface=MIXER,name="Master Playback Volume" $mixerVol >/dev/null
}

Also, for people running on a laptop, many times you will not have Left/Right volume but only a Mono setting. If that is the case, you will need to modify get_volume() as follows:

# Get current volume.
function get_volume()
{
mixer=$(amixer get Master | grep 'Mono:' | sed -e 's/^[^\[]*//' -e 's/^.//' -e 's/%.*$//')
echo $mixer
}

Good Idea

Mitch Frazier's picture

I was just getting and setting raw values, not setting a percent of full. If you do it your way you should be scaling get_volume() also so that a value returned by get_volume() can later be passed to set_volume().

Is it always 64? Besides being a power of 2 is there any particular reason it's 64?

Mitch Frazier is an Associate Editor for Linux Journal.

Is it always 64? I

Anonymous's picture
     Is it always 64?

I have two soundcards.

Running the command:

     amixer get Master

One soundcard reports:

     Limits: Playback 0 - 127

The other sound card reports:

     Limits: Playback 0 - 31

Nice idea, but....

deifl's picture

What happens if master-volume is playing the "Free Software Song" with vol=99 ;-) Increasing volume seems better than setting to fixed volume (vol=40).

Isn't it better to save current volume -> play sound -> raise volume (enough to recognize) -> play sound -> restore volume -> play sound. Increasing volume can done with: amixer set 'Master" +

I also like to stop and continue playing music so I added mpc pause at the beginning and mpc toggle at the end of the script.

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState