davemds pushed a commit to branch master.

http://git.enlightenment.org/enlightenment/modules/edgar.git/commit/?id=ac8f0d942c1336cc8b948ed97057fcd9debe3bb7

commit ac8f0d942c1336cc8b948ed97057fcd9debe3bb7
Author: Dave Andreoli <d...@gurumeditation.it>
Date:   Sat May 2 12:10:39 2020 +0200

    Audio: Better support for stereo channels
    
    Also start to factorize Players and Channels, in preparation for
    the upcoming MPD support
---
 gadgets/audio/__init__.py | 99 +++++++++++++++++++++++++++++++----------------
 1 file changed, 65 insertions(+), 34 deletions(-)

diff --git a/gadgets/audio/__init__.py b/gadgets/audio/__init__.py
index 8019029..216e936 100644
--- a/gadgets/audio/__init__.py
+++ b/gadgets/audio/__init__.py
@@ -1,7 +1,6 @@
 # This python file use the following encoding: utf-8
 
 import os
-import sys
 import dbus
 from urllib.parse import unquote as url_unquote
 
@@ -24,14 +23,48 @@ __gadget_vapi__ = 2
 __gadget_opts__ = {'popup_on_desktop': True}
 
 
-# def DBG(msg):
-#    print("AUDIO: %s" % msg)
-#    sys.stdout.flush()
+def DBG(*args):
+    import sys
+    print("AUDIO:", *args)
+    sys.stdout.flush()
 
 
 _instance = None
 
 
+class PlayerBase(object):
+    """ Define the interface that players must implement  """
+    name = 'Player name'
+    label = 'Player label'
+    metadata = {}  # metadata dict as per mpris2 specs
+    playback_status = 'Stopped'  # or 'Playing' or 'Paused'
+
+    def play(self):
+        raise NotImplemented
+
+    def prev(self):
+        raise NotImplemented
+
+    def next(self):
+        raise NotImplemented
+
+    def rais(self):
+        raise NotImplemented
+
+
+class ChannelBase(object):
+    """ Define the interface that volume channels must implement  """
+    name = 'Channel name'
+    volumes = [0.0, 0.0]  # left/right channels, range: 0.0 - 1.0
+    muted = True
+
+    def volume_set(self, vols):
+        raise NotImplemented
+
+    def mute_toggle(self):
+        raise NotImplemented
+
+
 class Gadget(e.Gadget):
 
     def __init__(self):
@@ -67,20 +100,21 @@ class Gadget(e.Gadget):
     def speaker_update(self, speaker):
         if self.pulse and len(self.pulse.channels) > 0:
             ch = self.pulse.channels[0]
-            left = right = ch.volume / 655
+            left, right = ch.volumes[0] * 100, ch.volumes[1] * 100
             speaker.message_send(0, (ch.muted, left, right))
 
     def speaker_wheel_cb(self, obj, sig, source):
         if self.pulse.channels:
             ch = self.pulse.channels[0]
-            vol = ch.volume
+            vol = (ch.volumes[0] + ch.volumes[1]) / 2
             if sig == 'mouse,wheel,0,1':
-                new_vol = vol - 3000
+                new_vol = vol - 0.03
             elif sig == 'mouse,wheel,0,-1':
-                new_vol = vol + 3000
+                new_vol = vol + 0.03
             else:
                 return
-            ch.volume_set(min(max(0, new_vol), 65500))
+            new_vol = min(max(0.0, new_vol), 1.0)
+            ch.volume_set([new_vol, new_vol])
 
     def popup_created(self, elm_parent):
         # DBG("POPUP CREATED")
@@ -100,11 +134,11 @@ class Gadget(e.Gadget):
         main_box.data['players_box'] = players_box
         main_box.data['volumes_box'] = volumes_box
 
-        # add all the available players to the popup edje box
+        # add all the available mpris players to the popup edje box
         for player in self.mpris.players:
             self.popup_player_add(main_box, player)
 
-        # add all the channel sliders
+        # add all the pulse channels sliders
         if self.pulse.conn is not None:
             for ch in self.pulse.channels:
                 self.popup_volume_add(main_box, ch)
@@ -162,7 +196,7 @@ class Gadget(e.Gadget):
         self.player_objs[player].append(o)
 
     def player_changed(self, player):
-        # the mpris player has changed, update all the relative edje objects
+        # the player has changed, update all the relative edje objects
         for o in self.player_objs.get(player, []):
             self.player_update(o, player)
 
@@ -213,11 +247,11 @@ class Gadget(e.Gadget):
                 pass
 
     def popup_volume_add(self, popup, channel):
-        sl = elm.Slider(popup, text=channel.name, min_max=(0, 65500),
+        sl = elm.Slider(popup, text=channel.name, min_max=(0.0, 1.0),
                         span_size=150, indicator_show=False,
                         size_hint_expand=EXPAND_HORIZ,
                         size_hint_fill=FILL_HORIZ)
-        sl.value = channel.volume
+        sl.value = (channel.volumes[0] + channel.volumes[1]) / 2
         sl.disabled = True if channel.muted else False
         sl.callback_changed_add(self.popup_slider_changed_cb, channel)
         sl.callback_slider_drag_start_add(self.popup_slider_drag_start_cb)
@@ -236,7 +270,7 @@ class Gadget(e.Gadget):
 
     @staticmethod
     def popup_slider_changed_cb(slider, channel):
-        channel.volume_set(slider.value)
+        channel.volume_set([slider.value, slider.value])
 
     @staticmethod
     def popup_slider_click_cb(slider, event, channel):
@@ -256,7 +290,7 @@ class Gadget(e.Gadget):
         if channel in self.channel_objs:
             for sl in self.channel_objs[channel]:
                 if 'dragging' not in sl.data:
-                    sl.value = channel.volume
+                    sl.value = (channel.volumes[0] + channel.volumes[1]) / 2
         # update all the speakers
         for speaker in self._instances:
             self.speaker_update(speaker)
@@ -318,7 +352,7 @@ class Mpris2_Client(object):
                 break
 
 
-class Mpris2_Player(object):
+class Mpris2_Player(PlayerBase):
     MAIN_IFACE = 'org.mpris.MediaPlayer2'
     PLAYER_IFACE = 'org.mpris.MediaPlayer2.Player'
 
@@ -362,21 +396,22 @@ class Mpris2_Player(object):
         self.proxy.Raise(dbus_interface=self.MAIN_IFACE)
 
 
-class AudioChannel(object):
-    def __init__(self, obj, iface, name, volume, muted):
+class PulseAudioChannel(ChannelBase):
+    def __init__(self, obj, iface, name, volumes, muted):
         self.obj = obj
         self.iface = iface
         self.name = name
-        self.volume = int(volume[0])
+        self.volumes = [float(volumes[0]) / 65536, float(volumes[1]) / 65536]
         self.muted = muted
 
         # This do not work, only connection on the main pulse obj work...
         #   so for the moment dispatch the callback from there
         # obj.connect_to_signal('VolumeUpdated', self.volume_changed_signal_cb)
 
-    def volume_set(self, value):
-        self.volume = value
-        self.obj.Set(self.iface, 'Volume', [dbus.UInt32(value)],
+    def volume_set(self, vols):  # values 0.0 - 1.0
+        self.volumes = vols
+        values = [dbus.UInt32(vols[0] * 65536), dbus.UInt32(vols[1] * 65536)]
+        self.obj.Set(self.iface, 'Volume', values,
                      dbus_interface=dbus.PROPERTIES_IFACE)
 
     def mute_toggle(self):
@@ -385,17 +420,13 @@ class AudioChannel(object):
                      dbus_interface=dbus.PROPERTIES_IFACE)
 
     def volume_changed_signal_cb(self, volume):
-        self.volume = int(volume[0])
+        self.volumes = [volume[0] / 65536, volume[1] / 65536]
         _instance.volume_changed(self)
 
     def mute_changed_signal_cb(self, muted):
         self.muted = muted
         _instance.mute_changed(self)
 
-    def __str__(self):
-        return '[%s]: "%s" volume: %s' % \
-               (self.iface.split('.')[-1], self.name, self.volume[:])
-
 
 class PulseAudio_Client(object):
     PULSE_OBJ = '/org/pulseaudio/core1'
@@ -541,8 +572,8 @@ class PulseAudio_Client(object):
     def stream_add(self, obj_path):
         try:
             obj = self.conn.get_object(self.STREAM_IFACE, obj_path)
-            volume = obj.Get(self.STREAM_IFACE, 'Volume',
-                             dbus_interface=dbus.PROPERTIES_IFACE)
+            volumes = obj.Get(self.STREAM_IFACE, 'Volume',
+                              dbus_interface=dbus.PROPERTIES_IFACE)
             mute = obj.Get(self.STREAM_IFACE, 'Mute',
                            dbus_interface=dbus.PROPERTIES_IFACE)
             props = obj.Get(self.STREAM_IFACE, 'PropertyList',
@@ -555,7 +586,7 @@ class PulseAudio_Client(object):
         except:
             name = 'Unknown app'
 
-        ch = AudioChannel(obj, self.STREAM_IFACE, name, volume, mute)
+        ch = PulseAudioChannel(obj, self.STREAM_IFACE, name, volumes, mute)
         self.channels.append(ch)
         _instance.channel_added(ch)
         return ch
@@ -563,8 +594,8 @@ class PulseAudio_Client(object):
     def sink_add(self, obj_path):
         try:
             obj = self.conn.get_object(self.DEVICE_IFACE, obj_path)
-            volume = obj.Get(self.DEVICE_IFACE, 'Volume',
-                             dbus_interface=dbus.PROPERTIES_IFACE)
+            volumes = obj.Get(self.DEVICE_IFACE, 'Volume',
+                              dbus_interface=dbus.PROPERTIES_IFACE)
             mute = obj.Get(self.DEVICE_IFACE, 'Mute',
                            dbus_interface=dbus.PROPERTIES_IFACE)
             props = obj.Get(self.DEVICE_IFACE, 'PropertyList',
@@ -580,7 +611,7 @@ class PulseAudio_Client(object):
             except:
                 name = 'Unknown device'
 
-        ch = AudioChannel(obj, self.DEVICE_IFACE, name, volume, mute)
+        ch = PulseAudioChannel(obj, self.DEVICE_IFACE, name, volumes, mute)
         self.channels.append(ch)
         _instance.channel_added(ch)
         return ch

-- 


Reply via email to