# Support for mixer controls
# Written by: Dominique Michel <dominique_libre@sourceforge.net>
#
# This file contain code for all the mixers.
#
# The original mixers are ALSA mixer (alsamixer, alsamixergui and
# alsamixerguis (a script part of bmpdj)),
# audacious, aumix, cdcd, cmus, mpd, quodlibet and xmms2.
#
# The original controls was written by Maciej Delmanowski <harnir@linux.net.pl>
# at the exception of alsamixer, bindings for multimadia keys
# and dB support by Dominique Michel,
# audacious control by Rafael Antonio Porras Samaniego <spoek@distrobit.net>
# and xmms2 control by Michal Gorny <peres.fvxm@mailnull.com>
#
# Only alsamixer do have direct dB control. It will be approximated for the other mixers.
#
# Alsamixer support up to eight sound cards. You can chosse the one in the prefs.
#
# TODO: Change the default Mixer preference to amixer into the preferences directory.
#       Test for Master control for all the mixers when possible.
#	Add support for several sound cards with the other mixers.
#	Make a pref setting with the Volume step.
#       Internationalisation.
#
# To call the functions, in the menus, it is part of "Popup /Music"
# Button 1: Mouse 4 "Change-Volume-Up"; Mouse 5 "Change-Volume-Down"
# Button 2: Mouse 3 "Menu /Mixer"
#
# At that time and for what I know, only amixer do have a native dB support.
# This is a must have feature for a professional audio mixer.

# Preferences {{{1
# If there is no selected mixer, load the default
LoadPreferences DefaultMixer
CheckPreferences DefaultMixer "InfoStoreAdd Mixer amixer"
# If there is no selected sound card, load the default
LoadPreferences DefaultSoundCard
CheckPreferences DefaultSoundCard "InfoStoreAdd SoundCard 0"

# Value for volume steps in dB. With alsamixer, the default value for my sound card
# is 1.5 dB steps. This will work with amixer and most sound cards. With the other
# mixers, the result will vary. Use only decimal . as separator or bc will bail:
InfoStoreAdd Vol_Step "1.5"

# Initialisations {{{1
# amixer {{{2
# Set VolControl: Test if a MASTER mixer exist, fallback to PCM
PipeRead "if [ $[infostore.Mixer] = amixer ] ; then NVolControl=`amixer -c $[infostore.SoundCard] get Master \ 2>/dev/null | grep Master -c`; echo InfoStoreAdd VolControl `if [ $NVolControl = 0 ]; then echo PCM; else echo Master; fi`; fi"

# Set SnddB: >0 = control in dB
PipeRead "if [ $[infostore.Mixer] = amixer ] ; then echo InfoStoreAdd SnddB `amixer -c $[infostore.SoundCard] get $[infostore.VolControl] \| grep dB -c` \
    else echo InfoStoreAdd SnddB 0 ; fi"

# aumix {{{2
# Set VolControl: Test if MASTER mixer exist, fallback to PCM
PipeRead "if [ $[infostore.Mixer] = aumix ] ; then NVolControl=`aumix -d /dev/mixer$[infostore.SoundCard] -q | grep master -c` ; echo InfoStoreAdd VolControl `if [ $NVolControl = 0 ]; then echo w; else echo v ; fi` ; fi"

# Memorize the volume
#PipeRead 'tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:" -e "s:\\[::" -e "s:\\]::"`; echo "InfoStoreAdd CurrentVolume $tmpval2"'

# Mute = off
InfoStoreAdd MixerMute 0
InfoStoreAdd MixerMuteAP 0
InfoStoreAdd MixerMuteCdcd 0
InfoStoreAdd MixerMuteMP 0
InfoStoreAdd MixerMuteMP2 0

# Basics functions {{{1
# Mixer-Volume <value> {{{2
DestroyFunc Mixer-Volume
AddToFunc Mixer-Volume
+ I PipeRead 'case $[infostore.Mixer] in \\
	amixer)		exec amixer -c $[infostore.SoundCard] set \'$[infostore.VolControl]\' $[0] > /dev/null ;; \\
	aumix)		exec aumix -d /dev/mixer$[infostore.SoundCard] -\'$[infostore.VolControl]\' $[0] ;; \\
	audacious)	exec audtool set-volume $[0] ;; \\
	cdcd)		exec cdcd setvol $[0] > /dev/null ;; \\
	cmus)		exec cmus-remote --volume $[0]% > /dev/null ;; \\
	mpd)		exec mpc volume $[0] > /dev/null ;; \\
	quodlibet)	exec quodlibet --volume $[0] > /dev/null ;; \\
	xmms2)		exec xmms2 config output.volume $[0]/$[0] ;; \\
	*)		exec amixer -c $[infostore.SoundCard] set '$[infostore.VolControl]' $[0] > /dev/null ;; \\
esac'

# Change-Volume-Up <step> {{{2
DestroyFunc Change-Volume-Up
AddToFunc Change-Volume-Up
+ I PipeRead 'case $[infostore.Mixer] in \\
	amixer)		exec amixer -c $[infostore.SoundCard] set '$[infostore.VolControl]' $[infostore.Vol_Step]dB+ >/dev/null ; \\
			tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:"`; echo "InfoStoreAdd CurrentVolume $tmpval2" ;; \\
	aumix)		step=$(echo $[infostore.Vol_Step]*2|bc -l) ; exec aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]' +${step} ;; \\
	audacious)	exec audtool set-volume +$[0] ;; \\
	cdcd)		echo Nop ;; \\
	cmus)		exec cmus-remote --volume +$[0]% > /dev/null ;; \\
	mpd)		exec mpc volume +$[0] > /dev/null ;; \\
	quodlibet)	exec quodlibet --volume-up > /dev/null ;; \\
	xmms2)		echo Nop ;; \\
	*)		echo Nop ;; \\
esac'

# Change-Volume-Down <value> {{{2
DestroyFunc Change-Volume-Down
AddToFunc Change-Volume-Down
+ I PipeRead 'case $[infostore.Mixer] in \\
	amixer)		exec amixer -c $[infostore.SoundCard] set '$[infostore.VolControl]' $[infostore.Vol_Step]dB- >/dev/null ; \\
			tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:"`; echo "InfoStoreAdd CurrentVolume $tmpval2" ;; \\
	aumix)		step=$(echo $[infostore.Vol_Step]*2|bc -l) ; exec aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]' -"${step}" ;; \\
	audacious)	exec audtool set-volume -$[0] ;; \\
	cdcd)		echo Nop ;; \\
	cmus)		exec cmus-remote --volume -$[0]% > /dev/null ;; \\
	mpd)		exec mpc volume -$[0] > /dev/null ;; \\
	quodlibet)	exec quodlibet --volume-down > /dev/null ;; \\
	xmms2)		echo Nop ;; \\
	*)		echo Nop ;; \\
esac'

# Mixer volume toggle mute {{{2
# Selected player will toggle the pause.
# If alsamixer or aumix is selected, it will mute toggle too. 
DestroyFunc Mixer-Volume-Toggle
AddToFunc Mixer-Volume-Toggle
+ I PipeRead 'if [ $[infostore.Mixer] = amixer ]; then \\
	if [ $[infostore.MixerMute] = 0 ]; then tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:" -e "s:\\[::" -e "s:\\]::"`; echo "InfoStoreAdd CurrentVolume $tmpval2"; amixer -c $[infostore.SoundCard] -- set $[infostore.VolControl] 0 > /dev/null; echo "InfoStoreAdd MixerMute 1"; else amixer -c $[infostore.Soundcard] -- set $[infostore.VolControl] $[infostore.CurrentVolume] > /dev/null; echo "InfoStoreAdd MixerMute 0"; fi; fi'
+ I PipeRead 'if [ $[infostore.Mixer] = aumix ]; then \\
	if [ $[infostore.MixerMute] = 0 ]; then echo "InfoStoreAdd MixerMute 1"; tmpval=`aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]'q | sed -e "s:.*, ::"`; echo "InfoStoreAdd CurrentVolume $tmpval"; exec aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]' 0 > /dev/null; else echo "InfoStoreAdd MixerMute 0"; exec aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]' $[infostore.CurrentVolume] > /dev/null; fi; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] = audacious ]; then \\
	exec audtool playback-playpause > /dev/null; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] = cdcd ]; then \\
	if [ $[infostore.MixerMuteCdcd] = 0 ]; then echo "InfoStoreAdd MixerMuteCdcd 1"; exec cdcd pause > /dev/null; else echo "InfoStoreAdd MixerMuteCdcd 0"; cdcd resume > /dev/null; fi; fi'
+ I PipeRead 'if [ $[infostore.Musicplayer] =  cmus ]; then \\
	exec cmus-remote --pause > /dev/null; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  mpd ]; then \\
	exec mpc toggle > /dev/null; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  quodlibet ]; then \\
	exec quodlibet --play-pause > /dev/null; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  xmms2 ]; then \\
	exec xmms2 toggle > /dev/null; fi'
# the other players
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  alsaplayer ]; then \\
	if [ $[infostore.MixerMuteAP] = 0 ]; then echo "InfoStoreAdd MixerMuteAP 1";	exec alsaplayer --speed 0; else echo "InfoStoreAdd MixerMuteAP 0"; exec alsaplayer --speed $[infostore.speed]; fi; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  mocp ]; then \\
	exec mocp --sync --toggle-pause; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  mplayer ]; then \\
	if [ $[infostore.MixerMuteMP] = 0 ]; then echo "InfoStoreAdd MixerMuteMP 1";	echo "Exec exec echo pause > /home/$[infostore.USERDIR]/.mplayer/pipe"; else echo "InfoStoreAdd MixerMuteMP 0"; echo "Exec exec echo pause > /home/$[infostore.USERDIR]/.mplayer/pipe"; fi; fi'
+ I PipeRead 'if [ $[infostore.MusicPlayer] =  mplayer2 ]; then \\
	if [ $[infostore.MixerMuteMP2] = 0 ]; then echo "InfoStoreAdd MixerMuteMP2 1"; echo "Exec exec echo pause > /home/$[infostore.USERDIR]/.mplayer/pipe"; else echo "InfoStoreAdd MixerMuteMP2 0"; echo "Exec exec echo pause > /home/$[infostore.USERDIR]/.mplayer/pipe"; fi; fi'

# Mixer volume mute toggle mute {{{2
# Toggle only alsamixer or aumix if selected. 
DestroyFunc Mixer-Mute-Toggle
AddToFunc Mixer-Mute-Toggle
+ I PipeRead 'if [ $[infostore.Mixer] = amixer ]; then \\
	if [ $[infostore.MixerMute] = 0 ]; then tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:" -e "s:\\[::" -e "s:\\]::"`; echo "InfoStoreAdd CurrentVolume $tmpval2"; amixer -c $[infostore.SoundCard] -- set $[infostore.VolControl] 0 > /dev/null; echo "InfoStoreAdd MixerMute 1"; else amixer -c $[infostore.Soundcard] -- set $[infostore.VolControl] $[infostore.CurrentVolume] > /dev/null; echo "InfoStoreAdd MixerMute 0"; fi; fi'
+ I PipeRead 'if [ $[infostore.Mixer] = aumix ]; then \\
	if [ $[infostore.MixerMute] = 0 ]; then echo "InfoStoreAdd MixerMute 1"; tmpval=`aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]'q | sed -e "s:.*, ::"`; echo "InfoStoreAdd CurrentVolume $tmpval"; exec aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]' 0 > /dev/null; else echo "InfoStoreAdd MixerMute 0"; exec aumix -d /dev/mixer$[infostore.SoundCard] -'$[infostore.VolControl]' $[infostore.CurrentVolume] > /dev/null; fi; fi'
+

# Mixer-Volume-dB <value>dB {{{2
DestroyFunc Mixer-Volume-dB
AddToFunc Mixer-Volume-dB
+ I Exec exec amixer -c $[infostore.SoundCard] -- set '$[infostore.VolControl]' $0 > /dev/null
+ I PipeRead 'tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:"`; echo "InfoStoreAdd CurrentVolume $tmpval2"'

# Show/Hide the GUI {{{2
DestroyFunc Mixer-GUI
AddToFunc Mixer-GUI
PipeRead 'case $[infostore.Mixer] in \\
	amixer)		echo "+ I All (\\\"ALSA Mixer\\\") Close" ; \\
			echo "+ I TestRc (Match) Break" ; \\
			echo "+ I TestRc (NoMatch) None (\\\"ALSA Mixer\\\") Test (x alsamixerguis) X alsamixerguis" ; \\
			echo "+ I TestRc (Match) None (\\\'ALSA Mixer\\\') AT \\\"ALSA Mixer\\\" \\\"alsamixer -c $[infostore.SoundCard]\\\"" ;; \\
	aumix)		echo "+ I All (aumix) Close" ; \\
			echo "+ I TestRc (NoMatch) X aumix -d /dev/mixer$[infostore.SoundCard] -I" ;; \\
	audacious)	echo "+ I Nop" ;; \\
	cdcd)		echo "+ I Nop" ;; \\
	cmus)		echo "+ I Nop" ;; \\
	mpd)		echo "+ I Nop" ;; \\
	quodlibet)	echo "+ I Nop" ;; \\
	xmms2)		echo "+ I Nop" ;; \\
	*)		echo "+ I Nop" ;; \\
esac'

# Menus {{{1
# Mixer menu {{{2
DestroyMenu /Mixer
AddToMenu /Mixer
+ '%22x22/fvwm-crystal/mixer-2.png%$[gt.Show main mixer]' Mixer-GUI
+ '%22x22/fvwm-crystal/mixer.png%$[gt.Audio mixer]'		Popup /Preferences/Mixer
PipeRead 'for i in 0 -3 -6 -9 -12 -15 -18 -24 -30 -36 -42 -48 -54 -60 -100 ; \\
	do	if [ $[infostore.SnddB] != 0 ] ; \\
			then echo \"+ \\\"${i} dB\\\" Mixer-Volume-dB ${i}dB\" ; \\
		else	case $i in \\
				0)	vol=100;; \\
				-3)	vol=95;; \\
				-6)	vol=91;; \\
				-9)	vol=86;; \\
				-12)	vol=81;; \\
				-15)	vol=76;; \\
				-18)	vol=72;; \\
				-24)	vol=62;; \\
				-30)	vol=53;; \\
				-36)	vol=43;; \\
				-42)	vol=34;; \\
				-48)	vol=24;; \\
				-54)	vol=15;; \\
				-60)	vol=6;; \\
				-100)	vol=0;; \\
				*)	vol=50;; \\
			esac; \\
			echo \"+ \\\"${i} dB\\\" Mixer-Volume ${vol}\" ; \\
		fi ; done'

# Volume tooltip
################
# Initialize the variable
#Test (EnvMatch Mixer amixer) Test (!EnvMatch SnddB 0) PipeRead \
#    'tmpval=`amixer -c $[infostore.SoundCard] get $[infostore.VolControl]`; \
#    tmpval2=`echo $tmpval|sed -e "s:\\(.*\\)\\(\\[.*dB]\\):\\2:"`; \
#    echo "InfoStoreAdd CurrentVolume $tmpval2"'

# Show the volume tooltip
#DestroyFunc Volume-Tooltip
#AddToFunc Volume-Tooltip
#+ I PointerWindow (FvwmButtons-Media1) FvwmButtons-Tooltip "Volume" "Main volume" "$[infostore.CurentVolume]" "+4-40" "20" "750"

# Wrapper function
#DestroyFunc Show-Volume
#AddToFunc Show-Volume
#+ I DestroyModuleConfig FvwmEvent-Volume-Tooltip: *
#+ I *FvwmEvent-Volume-Tooltip: enter_window Volume-Tooltip
#+ I Module FvwmEvent FvwmEvent-Volume-Tooltip
#Test (EnvMatch Mixer amixer) Test (!EnvMatch SnddB 0) Show-Volume

# Show tooltip on volume change
#DestroyFunc Mixer-Volume-Up
#AddToFunc Mixer-Volume-Up
#+ I Change-Volume-Up $[infostore.Vol_Step]
##+ I Test (EnvMatch Mixer amixer) Test (!EnvMatch SnddB 0) Volume-Tooltip

#DestroyFunc Mixer-Volume-Down
#AddToFunc Mixer-Volume-Down
#+ I Change-Volume-Down $[infostore.Vol_Step]
##+ I Test (EnvMatch Mixer amixer) Test (!EnvMatch SnddB 0) Volume-Tooltip

# vim:ft=fvwm
