Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

When I press the volume up/down keys on my keyboard, the volume changes too much. How can I make the step size smaller so that I have finer control?

share|improve this question

5 Answers 5

up vote 7 down vote accepted
+50

11.10/12.04

From this bug-report it appears the volume-step key disappeared in 11.10 and has not (as yet) reappeared.

Thus, there isn't a simple straightforward configuration change that you can make to reduce the volume step.

Post #18 in the link gives an interesting workaround which involves using alsamixer increment and decrement capability together with sending notifications to the desktop.

However I couldn't get it to work - thus my take on the solution is based upon that post.

With this solution, the default volume step will be reduced to two-percent steps.


How to

Install the xbindkeys package (using Synaptic, or with sudo apt-get install xbindkeys).

Using your favourite text editor, create a file in your home folder called .volumeHack.sh and copy and paste the contents below into that file i.e.

gedit ~/.volumeHack.sh

Run chmod a+x .volumeHack.sh to make it executable.

Then edit the file ~/.xbindkeysrc and copy & paste the text below at the bottom of this file. i.e.

gedit ~/.xbindkeysrc

Logout and login

.xbindkeysrc

# Increase volume
#"amixer set Master playback 1+"
"sh ~/.volumeHack.sh -c up -i 2% -m Master"
    m:0x0 + c:123
    XF86AudioRaiseVolume

# Decrease volume
"sh ~/.volumeHack.sh -c down -i 2% -m Master"
    m:0x0 + c:122
    XF86AudioLowerVolume

# Toggle mute - this is not used here
#"amixer set Master toggle"
# m:0x0 + c:121
# XF86AudioMute

.volumeHack.sh

#!/bin/sh

usage="usage: $0 -c {up|down|mute} [-i increment] [-m mixer]"
command=
increment=5%
mixer=Master

while getopts c:i:m:h o
do case "$o" in
    c) command=$OPTARG;;
    i) increment=$OPTARG;;
    m) mixer=$OPTARG;;
    h) echo "$usage"; exit 0;;
    ?) echo "$usage"; exit 0;;
esac
done

#echo "command:$command"
#echo "increment:$increment"
#echo "mixer:$mixer"

if [ "$command" = "" ]; then
    shift $(($OPTIND - 1))
    command=$1
    exit 0;
fi

if [ "$command" = "" ]; then
    echo "usage: $0 {up|down|mute} [increment]"
    exit 0;
fi

display_volume=0

if [ "$command" = "up" ]; then
    display_volume=$(amixer set $mixer $increment+ unmute | grep -m 1 "%]" | cut -d "[" -f2|cut -d "%" -f1)
fi

if [ "$command" = "down" ]; then
    display_volume=$(amixer set $mixer $increment- unmute | grep -m 1 "%]" | cut -d "[" -f2|cut -d "%" -f1)
fi

icon_name=""

if [ "$command" = "mute" ]; then
    if amixer get Master | grep "\[on\]"; then
        display_volume=0
        icon_name="notification-audio-volume-muted"
        amixer set $mixer mute
    else
        display_volume=$(amixer set $mixer unmute | grep -m 1 "%]" | cut -d "[" -f2|cut -d "%" -f1)
    fi
fi

if [ "$icon_name" = "" ]; then
    if [ "$display_volume" = "0" ]; then
        icon_name="notification-audio-volume-off"
    else
        if [ "$display_volume" -lt "33" ]; then
            icon_name="notification-audio-volume-low"
        else
            if [ "$display_volume" -lt "67" ]; then
                icon_name="notification-audio-volume-medium"
            else
                icon_name="notification-audio-volume-high"
            fi
        fi
    fi
fi
notify-send " " -i $icon_name -h int:value:$display_volume -h string:synchronous:volume

#echo "icon: $icon_name and $display_volume"
share|improve this answer
    
delty's answer worked for me once I disabled gnome's keyboard shortcuts for volume up/down. This warning from xbindkeys was the clue I needed: *** Warning *** Please verify that there is not another program running which captures one of the keys captured by xbindkeys. It seems that there is a conflict, and xbindkeys can't grab all the keys defined in its configuration file. –  user74498 Jul 2 '12 at 6:10

You can do this with CompizConfig Settings Manager. Use the command sudo apt-get install compizconfig-settings-manager if you haven't installed it already.

Now open the CompizConfig Settings Manager and go to Commands in the General section. Check the Enable commands checkbox to the right. In the Commands tab, enter the following two commands separately as two commands:

amixer set Master 5%+ -q

amixer set Master 5%- -q

Assign two keyboard shortcuts for the commands in the Key bindings tab. I use the Super+[ and Super+] combination. Now close the CompizConfig Settings Manager and this should work.

I'm not sure if you can assign the commands to the in-built volume controllers of the computer though.

share|improve this answer
1  
Does amixer need Compiz? –  Takkat Oct 31 '10 at 14:00
    
You can do that using Keyboard Shortcuts in Preferences too. Anyway the one in Compiz manager gives more options, including assigning click events, etc –  thameera Oct 31 '10 at 14:21
2  
The amixer command is wonderful, but there is no need for you to instruct readers to install CompizConfig Settings Manager. –  ændrük Nov 14 '10 at 3:58
2  
At first this worked for me, but the good result was not stable. For no obvious reason my 12.04 system went back to its original behavior with volume increments much too large, even though my new settings were still set and enabled in CCSM. I also tried deleting and re-creating them to no avail. I found another 12.04-friendly way to do this and will post it as another answer. –  cdaddr Nov 11 '12 at 19:17

10.04/10.10/11.04

I just discovered that gconf-editor has a setting for "Volume step as percentage of volume":

/apps/gnome_settings_daemon/volume_step

Much more elegant, and it works with the OSD volume notifications.

share|improve this answer

12.04 (and possibly 11.10)

If you want to control the pulseaudio volume directly rather than go the ALSA route, you can use the following script. While it should also be possible to control the volume via DBUS as detailed in this Stackoverflow answer, I however could not find a way to make this work in Ubuntu 12.04.

As is said in the script itself, it uses this Stackoverflow answer on how to programmatically change volume in Ubuntu and expands the idea into a script which takes the volume change as a command line argument and also shows an OSD notification. I have tried to model it as closely as possible to the default Ubuntu (12.04) behavior.

The script takes volume changes as either an absolute or relative number or percent value. So for instance:

  • pavol.sh 2000 sets the volume to 2000,
  • pavol.sh 30% sets the volume to 30 percent,
  • pavol.sh +1000 increases the volume by 1000 and
  • pavol.sh -5% decreases the volume by 5 percent.

It is also quite liberally commented in the hopes that it is useful for further tweaking.

HowTo

Use your favorite text editor to create a file in your home folder (or anywhere else really - just remember the path) called pavol.sh and copy and paste the contents below into that file, i.e.

gedit ~/pavol.sh

Run chmod a+x ~/pavol.sh to make it executable.

Then open Sytem Settings, go to the Keyboard settings and switch to the Shortcuts tab. There click on Custom Shortcuts and create two new keyboard shortcuts with the plus button.

Give each one a name and as command enter something like this: /home/username/pavol.sh "+3%" It is important to enter the full path to the pavol.sh script (unless the script lies in a folder that is included in the PATH environment variable). Also use quote signs "" around the volume value or the keyboard shortcut will not work.

After that click on the right side of each entry to set a key combination or multimedia key. If the desired combination or key is already assigned to another shortcut, the program will ask if you want to reassign it.

pavol.sh

#!/bin/bash --

## This script expands upon this answer on stackoverflow:
## http://stackoverflow.com/a/10739764
##



## GLOBAL VARIABLES

# restrict usable commands
PATH="/bin:/usr/bin"

# this script changes the volume of the default sink (as set, for instance, via the Ubuntu sound menu);
# use "pactl info" to display these settings neatly in a terminal
DEFAULT_SINK=$(pacmd dump | grep 'set-default-sink' | cut -d ' ' -f 2)

# get max. volume from the DEFAULT_SINK
MAX_VOL=$(pacmd list-sinks | grep -A 20 "name: <${DEFAULT_SINK}>" | grep "volume steps:" | tr -d '[:space:]' | cut -d ':' -f 2)

# show debug messages?
# 0 means no debug messages; 1 prints the current volume to the console at the end of the script; 2 switches on bash debugging via "set -x"
DEBUG=0



## FUNCTIONS

# generate trace output if DEBUG is 2 or higher
if [ ${DEBUG} -gt 1 ]; then set -x; fi

# use poor man's return buffer via this variable (This is not stackable!)
RETVAL=""


# print simple usage text to console
show_usage() {
    echo "Usage: $(basename ${0}) [+|-][number|percentage]"
}


# return (via RETVAL) the current pulseaudio volume as hexadecimal value
get_cur_vol() {
    RETVAL=$(pacmd dump | grep "set-sink-volume ${DEFAULT_SINK}" | cut -d ' ' -f 3)
}


# change the pulseaudio volume as set in the first parameter variable, i.e. ${1};
# this can either be an absolute percentage or normal value, for instance 20% or 2000,
# or a relative percentage or normal value, for instance +3% or -5% or +200 or -1000
change_vol() {
    step=${1}

    relative=${step:0:1} # extract first character
    percent=${step: -1}  # extract last character

    # cut off first character for easier calculations, if it is either a "+" or "-"
    if [ "${relative}" = "+" -o "${relative}" = "-" ]; then step=${step:1}; fi

    # if the last character of ${step} was, in fact, a percent sign...
    if [ "${percent}" = "%" ]; then
        step=${step:0:-1}        # cut off last character for easier calculations
        step=$[step*MAX_VOL/100] # change percentage into fixed value via MAX_VOL
    fi

    # save current volume in ${old_vol}
    get_cur_vol
    old_vol=$[RETVAL+0] # the dummy calculation turns the hexadecimal number to a decimal one

    # calculate the new volume value ${new_vol} with the operand that was extracted earlier
    if [ "${relative}" = "+" ]; then
        new_vol=$[old_vol+step]
    else
        if [ "${relative}" = "-" ]; then
            new_vol=$[old_vol-step]
        else
            # no operand found, so ${step} must be an absolute value
            new_vol=${step}
        fi
    fi

    # check boundaries - don't go below 0 and above MAX_VOL
    if [ ${new_vol} -lt 0 ]; then new_vol=0; fi
    if [ ${new_vol} -gt ${MAX_VOL} ]; then new_vol=${MAX_VOL}; fi

    # set the new volume
    pactl -- set-sink-volume "${DEFAULT_SINK}" "${new_vol}"

    # mute the sink if the new volume drops to 0 ...
    if [ ${new_vol} -le 0 ]; then
        pactl -- set-sink-mute "${DEFAULT_SINK}" yes
    else
        # ... or unmute the sink if the new volume is greater than the old
        if [ ${new_vol} -gt ${old_vol} ]; then
            pactl -- set-sink-mute "${DEFAULT_SINK}" no
        fi
    fi
}


# show an OSD notification
notify_osd() {
    # get current volume
    get_cur_vol
    cur_vol_percent=$[RETVAL*100/MAX_VOL]

    # get mute state (gives "yes" or "no")
    muted=$(pacmd dump | grep "set-sink-mute ${DEFAULT_SINK}" | cut -d ' ' -f 3)

    # choose suitable icon (modeled after the default Ubuntu 12.04 behavior):
    # muted-icon if volume is muted
    if [ "${muted}" = "yes" ]; then
        icon="notification-audio-volume-muted"
    else
        # icon with loudspeaker and 1 of the 3 circle segments filled if volume is less than 34%
        if [ ${cur_vol_percent} -lt 34 ]; then
            icon="notification-audio-volume-low"
        else
            # icon with loudspeaker and 2 of the 3 circle segments filled if volume is between 34% and 66%
            if [ ${cur_vol_percent} -lt 67 ]; then
                icon="notification-audio-volume-medium"
            else
                # icon with loudspeaker and all 3 of the 3 circle segments filled if volume is higher than 66%
                icon="notification-audio-volume-high"
            fi
        fi
    fi

    # show notification
    notify-send "Volume" -i ${icon} -h int:value:${cur_vol_percent} -h string:synchronous:volume
}


# fake main function, that gets called first and kicks off all the other functions
main() {
    # only change volume if input is a number with either a +/- prefix and/or a % suffix
    if [[ "${1}" =~ ^[+-]?[0-9]+[%]?$ ]]; then
        change_vol ${1}
    else
        show_usage
    fi

    # show volume osd
    notify_osd

    # show the new - now current - volume in hexadecimal, decimal and percentage if DEBUG is greater than 0
    if [ ${DEBUG} -gt 0 ]; then
        get_cur_vol
        echo "${RETVAL} - $[RETVAL+0] - $[RETVAL*100/MAX_VOL]%"
    fi
}



## REAL MAIN

# run the fake main function and pass on all command line arguments; then exit the script
main ${@}
exit 0
share|improve this answer
    
this works well except for it accumulating OSD notify-send when using gnome-shell. Every press adds a new OSD and the previous one doesn't go away. OSD is nice, but not essential for me. I tried commenting out the show OSD notification but that broke the script for me. –  Kendor Sep 30 '12 at 20:28
    
Sorry @kendor that it did not work for you. I did only test it with Unity. Have you tried the workaroud from the comment in this bug report: https://bugzilla.redhat.com/show_bug.cgi?id=693207#c3 ? Just add --hint=int:transient:1 before "Volume" on the line with the notify-send command (should be line number 130). Maybe it helps. –  Kuro Mar 4 '13 at 16:23

This easy solution works for (at least) 12.04 and does not require CCSM.

You will not have on-screen volume bar action when you use the keyboard shortcuts, but you will have however fine-grained volume control as you wish.

  1. System Settings > Keyboard > "Shortcuts" tab > "Sound and Media" category

  2. Disable the existing "Volume Down" and "Volume Up" shortcuts. To do this, on each one click to select it and then press Backspace to clear any key combo associated with it.

  3. Now select the "Custom Shortcuts" category and click the "+" icon to create two new shortcuts as follows:

    Name: Volume Up
    Command: amixer set Master 3%+
    Name: Volume Down
    Command: amixer set Master 3%-

    (Experiment with the percentages. If you need to go extremely fine then omit the % sign and it will use a 0-255 scale rather than percent).

  4. Now assign each of your new shortcuts to a key or key combo: Select a shortcut and type the desired key or keys on your keyboard.

After this, when you use your keyboard volume controls you should have whatever volume increments you specified. You can always go back to the original behavior by disabling your custom shortcuts and re-enabling the premade ones in the "Sound and Media" category.

share|improve this answer
    
Very useful, thanks –  Thomas Boxley Apr 28 '13 at 7:51
    
This worked from the command line and from my key mappings yesterday, but after a reboot, no effect at either command line or key mapping. –  GlenPeterson Oct 29 '13 at 15:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.