# Functions for setting up sound on the live CD. # This library is released under the GNU General Public License, # and it incorporates code from the /etc/init.d/alsa-utils included with # Ubuntu 8.04. Proper credit also goes to Debian. # Start code copied from Debian / Ubuntu: bugout () { printf "/etc/rc.d/livecdsound: programming error" stat_fail } echo_card_indices() { if [ -f /proc/asound/cards ] ; then sed -n -e's/^[[:space:]]*\([0-7]\)[[:space:]].*/\1/p' /proc/asound/cards fi } filter_amixer_output() { sed \ -e '/Unable to find simple control/d' \ -e '/Unknown playback setup/d' \ -e '/^$/d' } # The following functions try to set many controls. # No card has all the controls and so some of the attempts are bound to fail. # Because of this, the functions can't return useful status values. # $1 # $2 # $CARDOPT unmute_and_set_level() { { [ "$2" ] && [ "$CARDOPT" ] ; } || bugout amixer $CARDOPT -q set "$1" "$2" unmute 2>&1 | filter_amixer_output || : return 0 } # $1 # $CARDOPT mute_and_zero_level() { { [ "$1" ] && [ "$CARDOPT" ] ; } || bugout amixer $CARDOPT -q set "$1" "0%" mute 2>&1 | filter_amixer_output || : return 0 } # $1 # $2 "on" | "off" # $CARDOPT switch_control() { { [ "$2" ] && [ "$CARDOPT" ] ; } || bugout amixer $CARDOPT -q set "$1" "$2" 2>&1 | filter_amixer_output || : return 0 } # $1 sanify_levels_on_card() { CARDOPT="-c $1" unmute_and_set_level "Front" "80%" unmute_and_set_level "Master" "80%" unmute_and_set_level "Master Mono" "80%" unmute_and_set_level "Master Digital" "80%" # E.g., cs4237B unmute_and_set_level "Playback" "80%" unmute_and_set_level "Headphone" "100%" unmute_and_set_level "PCM" "80%" unmute_and_set_level "PCM,1" "80%" # E.g., ess1969 unmute_and_set_level "DAC" "80%" # E.g., envy24, cs46xx unmute_and_set_level "DAC,0" "80%" # E.g., envy24 unmute_and_set_level "DAC,1" "80%" # E.g., envy24 unmute_and_set_level "Synth" "80%" unmute_and_set_level "CD" "80%" unmute_and_set_level "PC Speaker" "100%" mute_and_zero_level "Mic" mute_and_zero_level "IEC958" # Ubuntu #19648 # Intel P4P800-MX switch_control "Master Playback Switch" on switch_control "Master Surround" on # Trident/YMFPCI/emu10k1: unmute_and_set_level "Wave" "80%" unmute_and_set_level "Music" "80%" unmute_and_set_level "AC97" "80%" # DRC: unmute_and_set_level "Dynamic Range Compression" "80%" # Required for HDA Intel (hda-intel): unmute_and_set_level "Front" "80%" # Required for SB Live 7.1/24-bit (ca0106): unmute_and_set_level "Analog Front" "80%" # Required at least for Via 823x hardware on DFI K8M800-MLVF Motherboard switch_control "IEC958 Capture Monitor" off # Required for hardware allowing toggles for AC97 through IEC958, # valid values are 0, 1, 2, 3. Needs to be set to 0 for PCM1. unmute_and_set_level "IEC958 Playback AC97-SPSA" "0" # Required for newer Via hardware unmute_and_set_level "VIA DXS,0" "80%" unmute_and_set_level "VIA DXS,1" "80%" unmute_and_set_level "VIA DXS,2" "80%" unmute_and_set_level "VIA DXS,3" "80%" # Required on some notebooks with ICH4: switch_control "Headphone Jack Sense" off switch_control "Line Jack Sense" off # Some machines need one or more of these to be on; # others need one or more of these to be off: # # switch_control "External Amplifier" on switch_control "Audigy Analog/Digital Output Jack" on switch_control "SB Live Analog/Digital Output Jack" on # D1984 -- Thinkpad T61/X61 switch_control "Speaker" on switch_control "Headphone" on # HDA-Intel w/ "Digital" capture mixer (See Ubuntu #193823) unmute_and_set_level "Digital" "80%" return 0 } # $1 | "all" sanify_levels() { TTSDML_RETURNSTATUS=0 case "$1" in all) for CARD in $(echo_card_indices) ; do sanify_levels_on_card "$CARD" || TTSDML_RETURNSTATUS=1 done ;; *) sanify_levels_on_card "$1" || TTSDML_RETURNSTATUS=1 ;; esac return $TTSDML_RETURNSTATUS } # $1 preinit_levels_on_card() { CARDOPT="-c $1" # Silly dance to activate internal speakers by default on PowerMac # Snapper and Tumbler id=`cat /proc/asound/card$1/id 2>/dev/null` if [ "$id" = "Snapper" -o "$id" = "Tumbler" ]; then switch_control "Auto Mute" off switch_control "PC Speaker" off switch_control "Auto Mute" on fi } # $1 | "all" preinit_levels() { TTSDML_RETURNSTATUS=0 case "$1" in all) for CARD in $(echo_card_indices) ; do preinit_levels_on_card "$CARD" || TTSDML_RETURNSTATUS=1 done ;; *) preinit_levels_on_card "$1" || TTSDML_RETURNSTATUS=1 ;; esac return $TTSDML_RETURNSTATUS } # End copied code. # List all cards that *should* be usable for PCM audio. In my experience, # the console speaker (handled by the pcsp driver) isn't a suitable playback # device, so we'll exclude it. list_non_pcsp_cards() { for card in $(echo_card_indices); do local cardfile="/proc/asound/card${card}/id" if [ -r "$cardfile" -a -f "$cardfile" ] && \ [ "$(cat "$cardfile")" != pcsp ]; then echo "$card" fi done }