153a5a1b3Sopenharmony_ci#!/usr/bin/python 253a5a1b3Sopenharmony_ci 353a5a1b3Sopenharmony_ciimport pygtk, gtk, sys 453a5a1b3Sopenharmony_cifrom ctypes import * 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_citry: 753a5a1b3Sopenharmony_ci libpulse = cdll.LoadLibrary("../.libs/libpulse.so") 853a5a1b3Sopenharmony_ciexcept OSError: 953a5a1b3Sopenharmony_ci try: 1053a5a1b3Sopenharmony_ci libpulse = cdll.LoadLibrary(".libs/libpulse.so") 1153a5a1b3Sopenharmony_ci except OSError: 1253a5a1b3Sopenharmony_ci libpulse = cdll.LoadLibrary("libpulse.so") 1353a5a1b3Sopenharmony_ci 1453a5a1b3Sopenharmony_ciclass ChannelMap(Structure): 1553a5a1b3Sopenharmony_ci _fields_ = [("channels", c_ubyte), 1653a5a1b3Sopenharmony_ci ("map", c_uint * 32)] 1753a5a1b3Sopenharmony_ci 1853a5a1b3Sopenharmony_ci _to_name = libpulse.pa_channel_map_to_name 1953a5a1b3Sopenharmony_ci _to_name.restype = c_char_p 2053a5a1b3Sopenharmony_ci _to_name.argtypes = [c_void_p] 2153a5a1b3Sopenharmony_ci 2253a5a1b3Sopenharmony_ci _to_pretty_name = libpulse.pa_channel_map_to_pretty_name 2353a5a1b3Sopenharmony_ci _to_pretty_name.restype = c_char_p 2453a5a1b3Sopenharmony_ci _to_pretty_name.argtypes = [c_void_p] 2553a5a1b3Sopenharmony_ci 2653a5a1b3Sopenharmony_ci _snprint = libpulse.pa_channel_map_snprint 2753a5a1b3Sopenharmony_ci _snprint.restype = c_char_p 2853a5a1b3Sopenharmony_ci _snprint.argtypes = [c_char_p, c_ulong, c_void_p] 2953a5a1b3Sopenharmony_ci 3053a5a1b3Sopenharmony_ci _position_to_string = libpulse.pa_channel_position_to_string 3153a5a1b3Sopenharmony_ci _position_to_string.restype = c_char_p 3253a5a1b3Sopenharmony_ci _position_to_string.argtypes = [c_uint] 3353a5a1b3Sopenharmony_ci 3453a5a1b3Sopenharmony_ci _position_to_pretty_string = libpulse.pa_channel_position_to_pretty_string 3553a5a1b3Sopenharmony_ci _position_to_pretty_string.restype = c_char_p 3653a5a1b3Sopenharmony_ci _position_to_pretty_string.argtypes = [c_uint] 3753a5a1b3Sopenharmony_ci 3853a5a1b3Sopenharmony_ci _can_balance = libpulse.pa_channel_map_can_balance 3953a5a1b3Sopenharmony_ci _can_balance.restype = c_int 4053a5a1b3Sopenharmony_ci _can_balance.argtypes = [c_void_p] 4153a5a1b3Sopenharmony_ci 4253a5a1b3Sopenharmony_ci _can_fade = libpulse.pa_channel_map_can_fade 4353a5a1b3Sopenharmony_ci _can_fade.restype = c_int 4453a5a1b3Sopenharmony_ci _can_fade.argtypes = [c_void_p] 4553a5a1b3Sopenharmony_ci 4653a5a1b3Sopenharmony_ci _parse = libpulse.pa_channel_map_parse 4753a5a1b3Sopenharmony_ci _parse.restype = c_void_p 4853a5a1b3Sopenharmony_ci _parse.argtypes = [c_void_p, c_char_p] 4953a5a1b3Sopenharmony_ci 5053a5a1b3Sopenharmony_ci def to_name(this): 5153a5a1b3Sopenharmony_ci return this._to_name(byref(this)) 5253a5a1b3Sopenharmony_ci 5353a5a1b3Sopenharmony_ci def to_pretty_name(this): 5453a5a1b3Sopenharmony_ci return this._to_pretty_name(byref(this)) 5553a5a1b3Sopenharmony_ci 5653a5a1b3Sopenharmony_ci def snprint(this): 5753a5a1b3Sopenharmony_ci s = create_string_buffer(336) 5853a5a1b3Sopenharmony_ci r = this._snprint(s, len(s), byref(this)) 5953a5a1b3Sopenharmony_ci 6053a5a1b3Sopenharmony_ci if r is None: 6153a5a1b3Sopenharmony_ci return None 6253a5a1b3Sopenharmony_ci else: 6353a5a1b3Sopenharmony_ci return s.value 6453a5a1b3Sopenharmony_ci 6553a5a1b3Sopenharmony_ci def position_to_string(this, pos): 6653a5a1b3Sopenharmony_ci return this._position_to_string(pos) 6753a5a1b3Sopenharmony_ci 6853a5a1b3Sopenharmony_ci def position_to_pretty_string(this, pos): 6953a5a1b3Sopenharmony_ci return this._position_to_pretty_string(pos) 7053a5a1b3Sopenharmony_ci 7153a5a1b3Sopenharmony_ci def can_balance(this): 7253a5a1b3Sopenharmony_ci return bool(this._can_balance(byref(this))) 7353a5a1b3Sopenharmony_ci 7453a5a1b3Sopenharmony_ci def can_fade(this): 7553a5a1b3Sopenharmony_ci return bool(this._can_fade(byref(this))) 7653a5a1b3Sopenharmony_ci 7753a5a1b3Sopenharmony_ci def parse(this, s): 7853a5a1b3Sopenharmony_ci if this._parse(byref(this), s) is None: 7953a5a1b3Sopenharmony_ci raise Exception("Parse failure") 8053a5a1b3Sopenharmony_ci 8153a5a1b3Sopenharmony_ci 8253a5a1b3Sopenharmony_ciclass CVolume(Structure): 8353a5a1b3Sopenharmony_ci _fields_ = [("channels", c_ubyte), 8453a5a1b3Sopenharmony_ci ("values", c_uint32 * 32)] 8553a5a1b3Sopenharmony_ci 8653a5a1b3Sopenharmony_ci _snprint = libpulse.pa_cvolume_snprint 8753a5a1b3Sopenharmony_ci _snprint.restype = c_char_p 8853a5a1b3Sopenharmony_ci _snprint.argtypes = [c_char_p, c_ulong, c_void_p] 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_ci _max = libpulse.pa_cvolume_max 9153a5a1b3Sopenharmony_ci _max.restype = c_uint32 9253a5a1b3Sopenharmony_ci _max.argtypes = [c_void_p] 9353a5a1b3Sopenharmony_ci 9453a5a1b3Sopenharmony_ci _scale = libpulse.pa_cvolume_scale 9553a5a1b3Sopenharmony_ci _scale.restype = c_void_p 9653a5a1b3Sopenharmony_ci _scale.argtypes = [c_void_p, c_uint32] 9753a5a1b3Sopenharmony_ci 9853a5a1b3Sopenharmony_ci _get_balance = libpulse.pa_cvolume_get_balance 9953a5a1b3Sopenharmony_ci _get_balance.restype = c_float 10053a5a1b3Sopenharmony_ci _get_balance.argtypes = [c_void_p, c_void_p] 10153a5a1b3Sopenharmony_ci 10253a5a1b3Sopenharmony_ci _get_fade = libpulse.pa_cvolume_get_fade 10353a5a1b3Sopenharmony_ci _get_fade.restype = c_float 10453a5a1b3Sopenharmony_ci _get_fade.argtypes = [c_void_p, c_void_p] 10553a5a1b3Sopenharmony_ci 10653a5a1b3Sopenharmony_ci _set_balance = libpulse.pa_cvolume_set_balance 10753a5a1b3Sopenharmony_ci _set_balance.restype = c_void_p 10853a5a1b3Sopenharmony_ci _set_balance.argtypes = [c_void_p, c_void_p, c_float] 10953a5a1b3Sopenharmony_ci 11053a5a1b3Sopenharmony_ci _set_fade = libpulse.pa_cvolume_set_fade 11153a5a1b3Sopenharmony_ci _set_fade.restype = c_void_p 11253a5a1b3Sopenharmony_ci _set_fade.argtypes = [c_void_p, c_void_p, c_float] 11353a5a1b3Sopenharmony_ci 11453a5a1b3Sopenharmony_ci _to_dB = libpulse.pa_sw_volume_to_dB 11553a5a1b3Sopenharmony_ci _to_dB.restype = c_double 11653a5a1b3Sopenharmony_ci _to_dB.argytpes = [c_uint32] 11753a5a1b3Sopenharmony_ci 11853a5a1b3Sopenharmony_ci def snprint(this): 11953a5a1b3Sopenharmony_ci s = create_string_buffer(320) 12053a5a1b3Sopenharmony_ci r = this._snprint(s, len(s), byref(this)) 12153a5a1b3Sopenharmony_ci 12253a5a1b3Sopenharmony_ci if r is None: 12353a5a1b3Sopenharmony_ci return None 12453a5a1b3Sopenharmony_ci else: 12553a5a1b3Sopenharmony_ci return s.raw 12653a5a1b3Sopenharmony_ci 12753a5a1b3Sopenharmony_ci def max(this): 12853a5a1b3Sopenharmony_ci return this._max(byref(this)) 12953a5a1b3Sopenharmony_ci 13053a5a1b3Sopenharmony_ci def scale(this, v): 13153a5a1b3Sopenharmony_ci return this._scale(byref(this), v) 13253a5a1b3Sopenharmony_ci 13353a5a1b3Sopenharmony_ci def get_balance(this, cm): 13453a5a1b3Sopenharmony_ci return this._get_balance(byref(this), byref(cm)) 13553a5a1b3Sopenharmony_ci 13653a5a1b3Sopenharmony_ci def get_fade(this, cm): 13753a5a1b3Sopenharmony_ci return this._get_fade(byref(this), byref(cm)) 13853a5a1b3Sopenharmony_ci 13953a5a1b3Sopenharmony_ci def set_balance(this, cm, f): 14053a5a1b3Sopenharmony_ci return this._set_balance(byref(this), byref(cm), f) 14153a5a1b3Sopenharmony_ci 14253a5a1b3Sopenharmony_ci def set_fade(this, cm, f): 14353a5a1b3Sopenharmony_ci return this._set_fade(byref(this), byref(cm), f) 14453a5a1b3Sopenharmony_ci 14553a5a1b3Sopenharmony_ci def to_dB(this, channel = None): 14653a5a1b3Sopenharmony_ci if channel is None: 14753a5a1b3Sopenharmony_ci return this._to_dB(this.max()) 14853a5a1b3Sopenharmony_ci 14953a5a1b3Sopenharmony_ci return this._to_dB(this.values[channel]) 15053a5a1b3Sopenharmony_ci 15153a5a1b3Sopenharmony_cicm = ChannelMap() 15253a5a1b3Sopenharmony_ci 15353a5a1b3Sopenharmony_ciif len(sys.argv) > 1: 15453a5a1b3Sopenharmony_ci cm.parse(sys.argv[1]) 15553a5a1b3Sopenharmony_cielse: 15653a5a1b3Sopenharmony_ci cm.parse("surround-51") 15753a5a1b3Sopenharmony_ci 15853a5a1b3Sopenharmony_civ = CVolume() 15953a5a1b3Sopenharmony_civ.channels = cm.channels 16053a5a1b3Sopenharmony_ci 16153a5a1b3Sopenharmony_cifor i in range(cm.channels): 16253a5a1b3Sopenharmony_ci v.values[i] = 65536 16353a5a1b3Sopenharmony_ci 16453a5a1b3Sopenharmony_cititle = cm.to_pretty_name() 16553a5a1b3Sopenharmony_ciif title is None: 16653a5a1b3Sopenharmony_ci title = cm.snprint() 16753a5a1b3Sopenharmony_ci 16853a5a1b3Sopenharmony_ciwindow = gtk.Window(gtk.WINDOW_TOPLEVEL) 16953a5a1b3Sopenharmony_ciwindow.set_title(unicode(title)) 17053a5a1b3Sopenharmony_ciwindow.set_border_width(12) 17153a5a1b3Sopenharmony_ci 17253a5a1b3Sopenharmony_civbox = gtk.VBox(spacing=6) 17353a5a1b3Sopenharmony_ci 17453a5a1b3Sopenharmony_cichannel_labels = {} 17553a5a1b3Sopenharmony_cichannel_scales = {} 17653a5a1b3Sopenharmony_cichannel_dB_labels = {} 17753a5a1b3Sopenharmony_ci 17853a5a1b3Sopenharmony_cidef update_volume(update_channels = True, update_fade = True, update_balance = True, update_scale = True): 17953a5a1b3Sopenharmony_ci if update_channels: 18053a5a1b3Sopenharmony_ci for i in range(cm.channels): 18153a5a1b3Sopenharmony_ci channel_scales[i].set_value(v.values[i]) 18253a5a1b3Sopenharmony_ci 18353a5a1b3Sopenharmony_ci if update_scale: 18453a5a1b3Sopenharmony_ci value_scale.set_value(v.max()) 18553a5a1b3Sopenharmony_ci 18653a5a1b3Sopenharmony_ci if update_balance: 18753a5a1b3Sopenharmony_ci balance_scale.set_value(v.get_balance(cm)) 18853a5a1b3Sopenharmony_ci 18953a5a1b3Sopenharmony_ci if update_fade: 19053a5a1b3Sopenharmony_ci fade_scale.set_value(v.get_fade(cm)) 19153a5a1b3Sopenharmony_ci 19253a5a1b3Sopenharmony_ci for i in range(cm.channels): 19353a5a1b3Sopenharmony_ci channel_dB_labels[i].set_label("%0.2f dB" % v.to_dB(i)) 19453a5a1b3Sopenharmony_ci 19553a5a1b3Sopenharmony_ci value_dB_label.set_label("%0.2f dB" % v.to_dB()) 19653a5a1b3Sopenharmony_ci 19753a5a1b3Sopenharmony_cidef fade_value_changed(fs): 19853a5a1b3Sopenharmony_ci v.set_fade(cm, fade_scale.get_value()) 19953a5a1b3Sopenharmony_ci update_volume(update_fade = False) 20053a5a1b3Sopenharmony_ci 20153a5a1b3Sopenharmony_cidef balance_value_changed(fs): 20253a5a1b3Sopenharmony_ci v.set_balance(cm, balance_scale.get_value()) 20353a5a1b3Sopenharmony_ci update_volume(update_balance = False) 20453a5a1b3Sopenharmony_ci 20553a5a1b3Sopenharmony_cidef value_value_changed(fs): 20653a5a1b3Sopenharmony_ci v.scale(int(value_scale.get_value())) 20753a5a1b3Sopenharmony_ci update_volume(update_scale = False) 20853a5a1b3Sopenharmony_ci 20953a5a1b3Sopenharmony_cidef channel_value_changed(fs, i): 21053a5a1b3Sopenharmony_ci v.values[i] = int(channel_scales[i].get_value()) 21153a5a1b3Sopenharmony_ci update_volume(update_channels = False) 21253a5a1b3Sopenharmony_ci 21353a5a1b3Sopenharmony_cifor i in range(cm.channels): 21453a5a1b3Sopenharmony_ci channel_labels[i] = gtk.Label(cm.position_to_pretty_string(cm.map[i])) 21553a5a1b3Sopenharmony_ci channel_labels[i].set_alignment(0, 1) 21653a5a1b3Sopenharmony_ci vbox.pack_start(channel_labels[i], expand=False, fill=True) 21753a5a1b3Sopenharmony_ci 21853a5a1b3Sopenharmony_ci channel_scales[i] = gtk.HScale() 21953a5a1b3Sopenharmony_ci channel_scales[i].set_range(0, 65536*3/2) 22053a5a1b3Sopenharmony_ci channel_scales[i].set_digits(0) 22153a5a1b3Sopenharmony_ci channel_scales[i].set_value_pos(gtk.POS_RIGHT) 22253a5a1b3Sopenharmony_ci vbox.pack_start(channel_scales[i], expand=False, fill=True) 22353a5a1b3Sopenharmony_ci 22453a5a1b3Sopenharmony_ci channel_dB_labels[i] = gtk.Label("-xxx dB") 22553a5a1b3Sopenharmony_ci channel_dB_labels[i].set_alignment(1, 1) 22653a5a1b3Sopenharmony_ci vbox.pack_start(channel_dB_labels[i], expand=False, fill=True) 22753a5a1b3Sopenharmony_ci 22853a5a1b3Sopenharmony_civalue_label = gtk.Label("Value") 22953a5a1b3Sopenharmony_civalue_label.set_alignment(0, .5) 23053a5a1b3Sopenharmony_civbox.pack_start(value_label, expand=False, fill=True) 23153a5a1b3Sopenharmony_civalue_scale = gtk.HScale() 23253a5a1b3Sopenharmony_civalue_scale.set_range(0, 65536*3/2) 23353a5a1b3Sopenharmony_civalue_scale.set_value_pos(gtk.POS_RIGHT) 23453a5a1b3Sopenharmony_civalue_scale.set_digits(0) 23553a5a1b3Sopenharmony_civbox.pack_start(value_scale, expand=False, fill=True) 23653a5a1b3Sopenharmony_civalue_dB_label = gtk.Label("-xxx dB") 23753a5a1b3Sopenharmony_civalue_dB_label.set_alignment(1, 1) 23853a5a1b3Sopenharmony_civbox.pack_start(value_dB_label, expand=False, fill=True) 23953a5a1b3Sopenharmony_ci 24053a5a1b3Sopenharmony_cibalance_label = gtk.Label("Balance") 24153a5a1b3Sopenharmony_cibalance_label.set_alignment(0, .5) 24253a5a1b3Sopenharmony_civbox.pack_start(balance_label, expand=False, fill=True) 24353a5a1b3Sopenharmony_cibalance_scale = gtk.HScale() 24453a5a1b3Sopenharmony_cibalance_scale.set_range(-1.0, +1.0) 24553a5a1b3Sopenharmony_cibalance_scale.set_value_pos(gtk.POS_RIGHT) 24653a5a1b3Sopenharmony_cibalance_scale.set_digits(2) 24753a5a1b3Sopenharmony_civbox.pack_start(balance_scale, expand=False, fill=True) 24853a5a1b3Sopenharmony_ci 24953a5a1b3Sopenharmony_cifade_label = gtk.Label("Fade") 25053a5a1b3Sopenharmony_cifade_label.set_alignment(0, .5) 25153a5a1b3Sopenharmony_civbox.pack_start(fade_label, expand=False, fill=True) 25253a5a1b3Sopenharmony_cifade_scale = gtk.HScale() 25353a5a1b3Sopenharmony_cifade_scale.set_range(-1.0, +1.0) 25453a5a1b3Sopenharmony_cifade_scale.set_value_pos(gtk.POS_RIGHT) 25553a5a1b3Sopenharmony_cifade_scale.set_digits(2) 25653a5a1b3Sopenharmony_civbox.pack_start(fade_scale, expand=False, fill=True) 25753a5a1b3Sopenharmony_ci 25853a5a1b3Sopenharmony_ciwindow.add(vbox) 25953a5a1b3Sopenharmony_ciwindow.set_default_size(600, 50) 26053a5a1b3Sopenharmony_ci 26153a5a1b3Sopenharmony_ciupdate_volume() 26253a5a1b3Sopenharmony_ci 26353a5a1b3Sopenharmony_cifor i in range(cm.channels): 26453a5a1b3Sopenharmony_ci channel_scales[i].connect("value_changed", channel_value_changed, i) 26553a5a1b3Sopenharmony_cifade_scale.connect("value_changed", fade_value_changed) 26653a5a1b3Sopenharmony_cibalance_scale.connect("value_changed", balance_value_changed) 26753a5a1b3Sopenharmony_civalue_scale.connect("value_changed", value_value_changed) 26853a5a1b3Sopenharmony_ci 26953a5a1b3Sopenharmony_civbox.show_all() 27053a5a1b3Sopenharmony_ci 27153a5a1b3Sopenharmony_ciif not cm.can_balance(): 27253a5a1b3Sopenharmony_ci balance_label.hide() 27353a5a1b3Sopenharmony_ci balance_scale.hide() 27453a5a1b3Sopenharmony_ci 27553a5a1b3Sopenharmony_ciif not cm.can_fade(): 27653a5a1b3Sopenharmony_ci fade_label.hide() 27753a5a1b3Sopenharmony_ci fade_scale.hide() 27853a5a1b3Sopenharmony_ci 27953a5a1b3Sopenharmony_ci 28053a5a1b3Sopenharmony_ciwindow.show() 28153a5a1b3Sopenharmony_ci 28253a5a1b3Sopenharmony_cigtk.main() 283