I have a SB 5.1 digital card and using the analog output for 6 speakers. Problem: it is not a 5.1 speaker system with its own remote control. Rear is connected to a hifi-system, front to an active stereo speaker-set, front is the tv itself and subwoofer an active subwoofer.
How to control all these speakers at once ? I would like to use my happauge remote or my keyboard, but freevo allows only control over one audio ctrl. Any ideas to control IGaine, Digital, OGaine and Volume at once ?
This is a small mixer plugin for freevo. the idea was to control more than one mixer slider at a time and control sliders that are not present in the ossmixer like IEC958 (digital output).
You can simply put the script in src/plugins
and activate it with:
plugin.activate('alsa_mixer').
Be sure to remove the old one with: plugin.remove('mixer').You then need a config line like this: MAJOR_AUDIO_CTRLS = ['Master','Surround','IEC958']
some problems: - the volume in/decreases not so fast than in the original mixer - in digital audio control in/decreasing isnt supported so it only can mute the channel
Good luck.
Mike
#if 0 /* # ----------------------------------------------------------------------- # Freevo - A Home Theater PC framework # Copyright (C) 2002 Krister Lagerstrom, et al. # Please see the file freevo/Docs/CREDITS for a complete list of authors. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MER- # CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ----------------------------------------------------------------------- */ #endif """Simple ALSA mixer """
import fcntl
import struct
import os
import popen2
import config
import rc
import plugin
from event import *
class PluginInterface(plugin.DaemonPlugin):
# These magic numbers were determined by writing a C-program using the
# macros in /usr/include/linux/... and printing the values.
# They seem to work on my machine. XXX Is there a real python interface?
SOUND_MIXER_WRITE_VOLUME = 0xc0044d00
SOUND_MIXER_WRITE_PCM = 0xc0044d04
SOUND_MIXER_WRITE_LINE = 0xc0044d06
SOUND_MIXER_WRITE_MIC = 0xc0044d07
SOUND_MIXER_WRITE_RECSRC = 0xc0044dff
SOUND_MIXER_LINE = 7
SOUND_MASK_LINE = 64
def __init__(self):
plugin.DaemonPlugin.__init__(self)
self.plugin_name = 'MIXER'
self.mixfd = None
self.muted = 0
# If you're using ALSA or something and you don't set the mixer, why are
# we trying to open it?
if config.DEV_MIXER:
try:
self.mixfd = open(config.DEV_MIXER, 'r')
except IOError:
print 'Couldn\'t open mixer %s' % config.DEV_MIXER
return
if 0:
self.mainVolume = 0
self.pcmVolume = 0
self.lineinVolume = 0
self.micVolume = 0
self.igainVolume = 0 # XXX Used on SB Live
self.ogainVolume = 0 # XXX Ditto
if self.mixfd:
data = struct.pack( 'L', self.SOUND_MASK_LINE )
try:
fcntl.ioctl( self.mixfd.fileno(), self.SOUND_MIXER_WRITE_RECSRC,
data )
except IOError:
_debug_('IOError for ioctl')
pass
if config.MAJOR_AUDIO_CTRL == 'VOL':
self.setMainVolume(config.DEFAULT_VOLUME)
if config.CONTROL_ALL_AUDIO:
self.setPcmVolume(config.MAX_VOLUME)
# XXX This is for SB Live cards should do nothing to others
# XXX Please tell if you have problems with this.
self.setOgainVolume(config.MAX_VOLUME)
elif config.MAJOR_AUDIO_CTRL == 'PCM':
self.setPcmVolume(config.DEFAULT_VOLUME)
if config.CONTROL_ALL_AUDIO:
self.setMainVolume(config.MAX_VOLUME)
# XXX This is for SB Live cards should do nothing to others
# XXX Please tell if you have problems with this.
self.setOgainVolume(config.MAX_VOLUME)
else:
_debug_("No appropriate audio channel found for mixer")
if config.CONTROL_ALL_AUDIO:
self.setLineinVolume(0)
self.setMicVolume(0)
def eventhandler(self, event = None, menuw=None, arg=None):
"""
eventhandler to handle the VOL events
"""
if event == MIXER_VOLUP:
if config.MAJOR_AUDIO_CTRL == 'VOL':
self.incMainVolume(event.arg)
rc.post_event(Event(OSD_MESSAGE, arg=_('Volume: %s%%') %
self.getVolume()))
elif config.MAJOR_AUDIO_CTRL == 'PCM':
self.incPcmVolume(event.arg)
rc.post_event(Event(OSD_MESSAGE, arg=_('Volume: %s%%') %
self.getVolume()))
return True
elif event == MIXER_VOLDOWN:
if( config.MAJOR_AUDIO_CTRL == 'VOL' ):
self.decMainVolume(event.arg)
rc.post_event(Event(OSD_MESSAGE, arg=_('Volume: %s%%') %
self.getVolume()))
elif( config.MAJOR_AUDIO_CTRL == 'PCM' ):
self.decPcmVolume(event.arg)
rc.post_event(Event(OSD_MESSAGE, arg=_('Volume: %s%%') %
self.getVolume()))
return True
elif event == MIXER_MUTE:
if self.getMuted() == 1:
rc.post_event(Event(OSD_MESSAGE, arg=_('Volume: %s%%') %
self.getVolume()))
self.setMuted(0)
else:
rc.post_event(Event(OSD_MESSAGE, arg=_('Mute')))
self.setMuted(1)
return True
return False
def _setVolume(self, device, volume):
if self.mixfd:
if volume < 0:
volume = 0
if volume > 100:
volume = 100
vol = (volume << 8) | (volume)
data = struct.pack('L', vol)
try:
fcntl.ioctl(self.mixfd.fileno(), device, data)
except IOError:
_debug_('IOError for ioctl')
pass
def _setVolumeAlsa(self, volume):
cmd = ""
for slider in config.MAJOR_AUDIO_CTRLS:
cmd += 'amixer -q set %s %s%% &' % (slider, volume)
popen2.Popen3(cmd)
def setMuted(self, mute):
self.muted = mute
cmd = ""
if self.muted == 1:
for slider in config.MAJOR_AUDIO_CTRLS:
cmd += 'amixer -q set %s mute &' % (slider)
else:
for slider in config.MAJOR_AUDIO_CTRLS:
cmd += 'amixer -q set %s unmute &' % (slider)
popen2.Popen3(cmd)
def getMuted(self):
return(self.muted)
# def setMuted(self, mute):
# self.muted = mute
# self._setMuted()
def getVolume(self):
#if config.MAJOR_AUDIO_CTRL == 'VOL':
# return self.mainVolume
#elif config.MAJOR_AUDIO_CTRL == 'PCM':
# return self.pcmVolume
return self.mainVolume
def getMainVolume(self):
return(self.mainVolume)
def setMainVolume(self, volume):
self.mainVolume = volume
self._setVolumeAlsa(self.mainVolume)
def incMainVolume(self, step=5):
self.mainVolume += step
if self.mainVolume > 100:
self.mainVolume = 100
self._setVolumeAlsa(self.mainVolume)
def decMainVolume(self, step=5):
self.mainVolume -= step
if self.mainVolume < 0:
self.mainVolume = 0
self._setVolumeAlsa(self.mainVolume)
def getPcmVolume(self):
return self.pcmVolume
def setPcmVolume(self, volume):
self.pcmVolume = volume
self._setVolume(self.SOUND_MIXER_WRITE_PCM, volume)
def incPcmVolume(self, step=5):
self.pcmVolume += step
if self.pcmVolume > 100:
self.pcmvolume = 100
self._setVolume( self.SOUND_MIXER_WRITE_PCM, self.pcmVolume )
def decPcmVolume(self, step=5):
self.pcmVolume -= step
if self.pcmVolume < 0:
self.pcmVolume = 0
self._setVolume( self.SOUND_MIXER_WRITE_PCM, self.pcmVolume )
def setLineinVolume(self, volume):
if config.CONTROL_ALL_AUDIO:
self.lineinVolume = volume
self._setVolume(self.SOUND_MIXER_WRITE_LINE, volume)
def getLineinVolume(self):
return self.lineinVolume
def setMicVolume(self, volume):
if config.CONTROL_ALL_AUDIO:
self.micVolume = volume
self._setVolume(self.SOUND_MIXER_WRITE_MIC, volume)
def setIgainVolume(self, volume):
"""For Igain (input from TV etc) on emu10k cards"""
if config.CONTROL_ALL_AUDIO:
if volume > 100:
volume = 100
elif volume < 0:
volume = 0
self.igainVolume = volume
os.system('aumix -i%s > /dev/null 2>&1 &' % volume)
def getIgainVolume(self):
return self.igainVolume
def decIgainVolume(self, step=5):
self.igainVolume -= step
if self.igainVolume < 0:
self.igainVolume = 0
os.system('aumix -i-%s > /dev/null 2>&1 &' % step)
def incIgainVolume(self, step=5):
self.igainVolume += step
if self.igainVolume > 100:
self.igainVolume = 100
os.system('aumix -i+%s > /dev/null 2>&1 &' % step)
def setOgainVolume(self, volume):
"""For Ogain on SB Live Cards"""
if volume > 100:
volume = 100
elif volume < 0:
volume = 0
self.ogainVolume = volume
os.system('aumix -o%s > /dev/null 2>&1' % volume)
def reset(self):
if config.CONTROL_ALL_AUDIO:
self.setLineinVolume(0)
self.setMicVolume(0)
if config.MAJOR_AUDIO_CTRL == 'VOL':
self.setPcmVolume(config.MAX_VOLUME)
elif config.MAJOR_AUDIO_CTRL == 'PCM':
self.setMainVolume(config.MAX_VOLUME)
self.setIgainVolume(0) # SB Live input from TV Card.
