On Wed, 2009-04-08 at 08:42 -0700, bburde...@comcast.net wrote:
> Hi all;
> 
> With SHR-testing the phone seems to be fairly usable.  Battery life is 
> even pretty decent.  However, one thing that is a dealbreaker for me as 
> far as using my freerunner as my main phone is the call volume.  I can 
> make calls just fine from my living room, but in a noisy cafe or inside 
> a car I can't hear very well at all.  I've adjusted the volume before 
> from text config files, but you walk the line between usable call volume 
> and bad echo problems for whoever you're talking to.
> 
> Has anyone been able to address this for themselves?  This is maybe the 
> last major issue that keeps the FR from being my main phone.  But unless 
> this is addressed I can't really recommend the phone to anyone but 
> hobbyists.
> 
> Ben
> 

I wrote an application do control this. It requires python-pyalasaaudio,
FSO and elementary, so should work on SHR or OM distro's. Put the
elmixer.py into /usr/bin and then put volume.desktop
into /usr/share/applications. The CLVL volume that Mickey talks about in
his mail can be adjusted by using the Modem mixer control.

The mixer tracks scenario changes so the call volume controls don't
become active until a call has started. If you want to change call
volumes it is best to start the application before the call starts as it
takes quite a few seconds to start.

Angus

Attachment: volume.desktop
Description: application/desktop

#!/usr/bin/python
#
# copyright 2008 Angus Ainslie <angus.ains...@gmail.com>
#
#    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 3 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
#    MERCHANTABILITY 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, see <http://www.gnu.org/licenses/>.
#

import alsaaudio
import sys
import elementary
import os
import dbus
import e_dbus
#from dbus.mainloop.glib import DBusGMainLoop

class Mixers:
    def __init__( self ):
        return

    def GetMixers( self ) :
        self.mixers = []
        for m in alsaaudio.mixers():
            mixer = alsaaudio.Mixer( m )
            self.mixers.append( mixer ) 
            
class Main:   
    def delete_event(self, widget, event, data=None):
        print "delete event occurred"
        return False

    def destroy(self, widget, data=None, more=None ) :
	elementary.exit()

    def __init__(self):
	#DBusGMainLoop(set_as_default=True)
	#e_dbus.DBusEcoreMainLoop()	

	self.bus = dbus.SystemBus( mainloop=e_dbus.DBusEcoreMainLoop() )

	#usage_obj = self.bus.get_object('org.freesmartphone.ousaged', '/org/freesmartphone/Usage')
	#usage_iface = dbus.Interface(usage_obj, 'org.freesmartphone.Usage')

        gsm_obj = self.bus.get_object('org.freesmartphone.ogsmd', '/org/freesmartphone/GSM/Device')
        self.gsm_iface = dbus.Interface(gsm_obj, 'org.freesmartphone.GSM.Device')

	#device_obj = self.bus.get_object('org.freesmartphone.odeviced', '/org/freesmartphone/Device')
	#device_iface = dbus.Interface(device_obj, 'org.freesmartphone.Device')

        audio_obj = self.bus.get_object('org.freesmartphone.odeviced', '/org/freesmartphone/Device/Audio')
	self.audio_iface = dbus.Interface(audio_obj, 'org.freesmartphone.Device.Audio')

	self.audio_iface.connect_to_signal( "Scenario", self.on_scenario_status)

        input_obj = self.bus.get_object('org.freesmartphone.odeviced', '/org/freesmartphone/Device/Input')
        self.input_iface = dbus.Interface(input_obj, 'org.freesmartphone.Device.Input')

        self.input_iface.connect_to_signal( "Event", self.on_input_event )

	info = self.audio_iface.GetInfo()
	print "Info", info

	scenario = self.audio_iface.GetScenario()
	print "Current Scenario", scenario

	elementary.init()
    	self.window = elementary.Window("mixer", elementary.ELM_WIN_BASIC)
    	self.window.title_set("Mixer")
   	self.window.destroy = self.destroy

        self.mixers = Mixers()
        self.mixers.GetMixers()

	bg = elementary.Background(self.window)
    	self.window.resize_object_add(bg)
    	bg.size_hint_weight_set(1.0, 1.0)
    	bg.show()

        self.main_box = elementary.Box( self.window )
	self.main_box.size_hint_weight_set(1.0, 1.0)
       	self.main_box.show()

	self.on_scenario_status( scenario, "startup" )

	self.window.resize_object_add( self.main_box )
	self.window.resize(480, 640)
	self.window.show()
 
    def on_input_event( self, name, action, seconds ) :
        print "Input event", name
        print "Action", action
        print "time", seconds

#        scenario = self.audio_iface.GetScenario()	
	scenario = 'handset'

        if name == 'HEADSET' :
	    if action == 'pressed' :
		self.on_scenario_status( scenario, 'plugged' )
	    elif action == 'released' :
		self.on_scenario_status( scenario, 'unplugged' )

    def on_scenario_status( self, scenario, reason ) :
	#print "Scenario status change", scenario
	#print "reason", reason

	if reason != 'startup' :
	    self.main_label.delete()
	    self.screen_mixers.delete()

        self.main_label = elementary.Label(self.window)
        if scenario == 'gsmhandset' :
	    print "Handset"
            self.screen_mixers = self.CreateHandsetControls( self.mixers.mixers )
            self.main_label.label_set( '<b>Handset</b>' )
        elif scenario == 'headset' :
	    print "Headset"
            self.screen_mixers = self.CreateWiredHeadsetControls( self.mixers.mixers )
            self.main_label.label_set( '<b>Headset</b>' )
        elif scenario == 'stereoout' :
	    print "StereoOut"
            self.screen_mixers = self.CreateSpeakeroutControls( self.mixers.mixers )
            self.main_label.label_set( '<b>StereoOut</b>' )
        elif scenario == 'btheadset' :
	    print "BT Headset"
            self.screen_mixers = self.CreateBtHeadsetControls( self.mixers.mixers )
            self.main_label.label_set( '<b>BT Headset<\b>' )

        self.main_box.pack_start( self.main_label )
        self.main_box.pack_end( self.screen_mixers )
        self.main_label.show()
        self.main_box.show()
	self.window.resize_object_add( self.screen_mixers )
	self.screen_mixers.show()

    def get_mixer_name( self, mixer_name_idx ) :
        parts = mixer_name_idx.partition( "-" )

        return( parts[0] )

    def get_mixer_idx( self, mixer_name_idx ) :
        parts = mixer_name_idx.partition( "-" )

        if parts[2] == "" : 
            mixer_idx = 0
        else :
            mixer_idx = int( parts[2] )

        return( mixer_idx )

    def get_mixer( self, mixer_name_idx ) :
	mixer_name = self.get_mixer_name( mixer_name_idx )

	for m in self.mixers.mixers:
            if mixer_name == m.mixer() :
	        #print "Mixer ", mixer_name ,": ", m.mixer()
		return( m ) 

        return( None )

    def cb_volume( self, slider, event ) :
#	print "Volume callback", slider, event
#	print "Slider %s Value : %d" % ( slider.name_get(), slider.value )

	if slider.name_get() == 'Modem' :
	    self.gsm_iface.SetSpeakerVolume( int( slider.value ))
	else :
	    mixer = self.get_mixer( slider.name_get() )
            mixer_idx = self.get_mixer_idx( slider.name_get() )
	    actual_volume = self.set_volume( int( slider.value ), mixer, mixer_idx, 'Single' )

	    slider.value = actual_volume

    def set_volume( self, volume, m, idx, style = 'All' ) :
#        print "value changed :", volume, m.mixer(), idx

        volumes = m.getvolume()

        if( style == 'Single' ) :
            for i in range(len(volumes)) :
                m.setvolume(volume,i)
        else :
            m.setvolume(volume,idx)
     
        volumes = m.getvolume()

	return( volumes[idx] )

    def cb_mute( self, button, m, i ) :
        print "event"
        if button.get_active() == False :
            muted = "on"
            m.setmute( 1 )
#            button.set_active( False )
        else :
            muted = "off"
            m.setmute( 0 )
#            button.set_active( True )

        print m.mixer(), "mute", muted
    
    def cb_record( self, button, m, i ) :
        print "event"
        if button.get_active() == False :
            rec = "on"
            m.setrec( 1 )
#            button.set_active( False )
        else :
            rec = "off"
            m.setrec( 0 )
#           button.set_active( True )

        print m.mixer(), "record", rec

    def CreateModemSlider( self ) :
        box0 = elementary.Box(self.window)
        box0.horizontal_set( True )
        box0.size_hint_min_set( 200, 50 )
        label = elementary.Label(self.window)
        label.label_set('Modem')
        label.size_hint_align_set(-1.0, 0)
        label.size_hint_weight_set(0, 1)
        label.scale_set(1)
        box0.pack_end(label)
        label.show()

        box1 = elementary.Box(self.window)
        box1.horizontal_set( True )
        box1.pack_start( box0 )

	volume = self.gsm_iface.GetSpeakerVolume()
	
        slider = elementary.Slider(self.window)
        slider.label_set( '' )
        slider.name_set( 'Modem' )
        slider.span_size_set(100)
        slider.size_hint_align_set(0, 0.5)
        slider.size_hint_weight_set(0, 1)
        slider.unit_format_set(" %3.0f" + ' / %d' % 100 )
        slider.indicator_format_set("%3.0f")
        slider.min_max_set( 0, 100 )
        slider.value = float( volume )
        slider.scale_set(0.8)
        slider.on_mouse_up_add(self.cb_volume)
        box1.pack_end(slider)
        slider.show()

        box0.show()

        return box1

    def CreateMixerSliders( self, m, style = 'All' ) :
        box0 = elementary.Box(self.window)
	box0.horizontal_set( True )
	box0.size_hint_min_set( 200, 50 )
        label = elementary.Label(self.window)
        label.label_set('%s' % m.mixer() )
        label.size_hint_align_set(-1.0, 0)
        label.size_hint_weight_set(0, 1)
        label.scale_set(1)
        box0.pack_end(label)
        label.show()

        box1 = elementary.Box(self.window)
        box1.horizontal_set( True )
	box1.pack_start( box0 )

#        print "Mixer name: '%s' '%d" %( m.mixer(),m.mixerid() )
        volcap = m.volumecap()
        switchcap = m.switchcap()
#        print "Capabilities", volcap + switchcap

        volumes = m.getvolume()
        if volcap and volumes :
            if( style == 'Single' ) :
                slides = 1
            if( style == 'All' ) :
                slides = len(volumes)

            for i in range( slides ):
#                print "Channel %i volume: %i%%"%(i,volumes[i])
                        
	    	slider = elementary.Slider(self.window)
#            	slider.label_set('%s' % m.mixer() )
            	slider.label_set( '' )
		slider.name_set( m.mixer() + "-" + str( i ))
            	slider.span_size_set(100)
            	slider.size_hint_align_set(0, 0.5)
            	slider.size_hint_weight_set(0, 1)
            	slider.unit_format_set(" %3.0f" + ' / %d' % 100 )
            	slider.indicator_format_set("%3.0f")
            	slider.min_max_set( 0, 100 )
            	slider.value = float( volumes[i] )
            	slider.scale_set(0.8)
		slider.on_mouse_up_add(self.cb_volume)
            	box1.pack_end(slider)
            	slider.show()
        else :
            return None

	box0.show()

        return box1
    
    def SaveState( self, arg, stateFile ) :
        oldFile = '/usr/share/openmoko/scenarios/' + stateFile + '.backup'
        newFile = '/usr/share/openmoko/scenarios/' + stateFile

        try :
            os.rename( newFile, oldFile )
        except :
            print 'No old file to backup'
        
        os.system( 'alsactl store 0 -f ' + newFile )

    def SetState( self, arg, stateFile ) :
        path = '/usr/share/openmoko/scenarios/' + stateFile

        os.system( 'alsactl restore 0 -f ' + path )

    def CreateHandsetControls( self , mixers ) :
        inputs = [ 'Mic2', 'Mono Sidetone', 'Mono' ]
        outputs = [ 'Bypass', 'Speaker', 'Modem' ]

        return( self.CreateMixerControls( mixers, inputs, outputs ))

    def CreateWiredHeadsetControls( self , mixers ) :
        inputs = [ 'Mic1', 'Mono Sidetone', 'Mono' ]
        outputs = [ 'Bypass', 'Headphone', 'Modem' ]

        return( self.CreateMixerControls( mixers, inputs, outputs ))

    def CreateSpeakeroutControls( self , mixers ) :
        inputs = [ 'Mic2', 'Mono Sidetone', 'Mono' ]
        outputs = [ 'Bypass', 'Headphone' ]

        return( self.CreateMixerControls( mixers, inputs, outputs ))

    def CreateBtHeadsetControls( self , mixers ) :
        inputs = [ 'Mono Voice Playback Volume', 'Mono' ]
        outputs = [ 'ADC', 'Modem' ]

        return( self.CreateMixerControls( mixers, inputs, outputs ))

    def CreateMixerControls( self , mixers, inputs, outputs ) :
        mixerBox = elementary.Box( self.window )
        mixerBox.size_hint_weight_set(1.0, 1.0)
        mixerBox.size_hint_align_set(-1.0, -1.0)

	label = elementary.Label( self.window )
        label.label_set('<b>Input</b>')
        label.size_hint_align_set(0.1, 0.5)
        label.scale_set(1)
        mixerBox.pack_start(label)
        label.show()

        for m in mixers:
            mixer = False
            id = m.mixerid()
#            print "Mixer ", id ,": ", m.mixer()
            if m.mixer() in inputs :
                mixerControls = self.CreateMixerSliders( m, 'Single' )

                if mixerControls != None :
                    mixerBox.pack_end( mixerControls )
                    mixerControls.show()

        label = elementary.Label( self.window )
        label.label_set('<b>Output</b>')
        label.size_hint_align_set(0.1, 0.5)
        label.scale_set(1)
        mixerBox.pack_end(label)
        label.show()

        for m in mixers:
            if m.mixer() in outputs :
                mixerControls = self.CreateMixerSliders( m, 'Single' )

                if mixerControls != None :
                    mixerBox.pack_end( mixerControls )
                    mixerControls.show()

        if 'Modem' in outputs :
            mixerControls = self.CreateModemSlider()

            if mixerControls != None :
                mixerBox.pack_end( mixerControls )
                mixerControls.show()

        #buttonBox = elementary.Box( self.window )
        #buttonBox.horizontal_set( True )
        #buttonBox.size_hint_weight_set(1.0, 1.0)
        #buttonBox.size_hint_align_set(-1.0, -1.0)
        #self.window.resize_object_add( buttonBox )

        #button = elementary.Button( self.window )
        #button.label_set('Save')
        #button.show()
        #button.clicked = self.SaveState

        #buttonBox.pack_start( button )

        #button = elementary.Button( self.window )
        #button.label_set('Restore')
        #button.show()
        #button.clicked = self.SetState

        #buttonBox.pack_end( button )
        #buttonBox.show()

        #mixerBox.pack_end( buttonBox )

        return( mixerBox )

    def main(self):
        elementary.run()
    	elementary.shutdown()

run = Main()
run.main()
_______________________________________________
support mailing list
support@lists.openmoko.org
https://lists.openmoko.org/mailman/listinfo/support

Reply via email to