Changeset 576:f2803c2445ba


Ignore:
Timestamp:
12/07/14 15:08:00 (9 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
hg-Phase:
(<MercurialRepository 1 'hg:/home/ivaradi/mlx/hg' '/'>, 'public')
Message:

Reworked the Linux sound handling to use GStreamer

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • runmlx.sh

    r574 r576  
    66export PYTHONPATH
    77
    8 LD_LIBRARY_PATH="${HOME}/local/opt/OpenAL/lib:${LD_LIBRARY_PATH}"
    9 export LD_LIBRARY_PATH
    10 
    118exec python -m runmlx "$@"
  • src/mlx/sound.py

    r573 r576  
    180180else: # os.name!="nt"
    181181    import threading
     182    import time
    182183    try:
    183         import pyglet
    184 
    185         class SoundThread(threading.Thread):
    186             """A thread executing the pyglet event loop that directs the
    187             playback of the sound files."""
    188             class Player(pyglet.media.ManagedSoundPlayer):
    189                 """Player which handles the end-of-stream condition
    190                 properly."""
    191 
    192                 def __init__(self, finishCallback, extra):
    193                     """Construct the player with the given data."""
    194                     super(SoundThread.Player, self).__init__()
    195 
    196                     self._finishCallback = finishCallback
    197                     self._extra = extra
    198 
    199                 def _on_eos(self):
    200                     if self._finishCallback is not None:
    201                         self._finishCallback(True, self._extra)
    202                     return super(SoundThread.Player, self)._on_eos()
    203 
    204             class EventLoop(pyglet.app.EventLoop):
    205                 """Own implementation of the event loop that collects the
    206                 requested sound files and plays them."""
    207 
    208                 def __init__(self, soundsDirectory):
    209                     """Construct the event loop."""
    210                     super(SoundThread.EventLoop, self).__init__()
    211 
    212                     self._soundsDirectory = soundsDirectory
    213 
    214                     self._lock = threading.Lock()
    215                     self._requestedSounds = []
    216 
    217                 def startSound(self, name, finishCallback, extra):
    218                     """Add the sound with the given name"""
    219                     with self._lock:
    220                         path = os.path.join(self._soundsDirectory, name)
    221                         self._requestedSounds.append( (path,
    222                                                        finishCallback, extra) )
    223 
    224                 def idle(self):
    225                     """The idle callback."""
    226                     with self._lock:
    227                         requestedSounds = self._requestedSounds
    228                         self._requestedSounds = []
    229 
    230                     for (path, finishCallback, extra) in requestedSounds:
    231                         try:
    232                             media = pyglet.media.load(path)
    233                             player = SoundThread.Player(finishCallback, extra)
    234                             player.queue(media)
    235                             player.play()
    236                         except Exception, e:
    237                             print "mlx.SoundThread.EventLoop.idle: " + str(e)
    238                             if finishCallback is not None:
    239                                 finishCallback(False, extra)
    240 
    241                     timeout = super(SoundThread.EventLoop, self).idle()
    242                     return 0.1 if timeout is None else min(timeout, 0.1)
    243 
    244             def __init__(self, soundsDirectory):
    245                 """Construct the sound playing thread with the given
    246                 directory."""
    247                 super(SoundThread, self).__init__()
    248 
    249                 self.daemon = False
    250                 self.eventLoop = SoundThread.EventLoop(soundsDirectory)
    251 
    252             def run(self):
    253                 """Run the event loop."""
    254                 self.eventLoop.run()
    255 
    256             def startSound(self, name, finishCallback = None, extra = None):
    257                 """Start the playback of the given sound."""
    258                 self.eventLoop.startSound(name, finishCallback, extra)
    259 
    260         _thread = None
     184        from common import gst, gobject, gst_element_factory_make
     185        from common import GST_STATE_PLAYING, GST_MESSAGE_EOS
     186
     187        _soundsDirectory = None
     188        _bins = set()
    261189
    262190        def initializeSound(soundsDirectory):
    263191            """Initialize the sound handling with the given directory containing
    264192            the sound files."""
    265             global _thread
    266             _thread = SoundThread(soundsDirectory)
    267             _thread.start()
    268 
     193            gst.init()
     194            global _soundsDirectory
     195            _soundsDirectory = soundsDirectory
    269196
    270197        def startSound(name, finishCallback = None, extra = None):
    271198            """Start playing back the given sound."""
    272             _thread.startSound(name, finishCallback = finishCallback,
    273                                extra = extra)
     199            try:
     200                playBin = gst_element_factory_make("playbin")
     201
     202                bus = playBin.get_bus()
     203                bus.enable_sync_message_emission()
     204                bus.add_signal_watch()
     205                bus.connect("message", _handlePlayBinMessage,
     206                            playBin, finishCallback, extra)
     207
     208                path = os.path.join(_soundsDirectory, name)
     209                playBin.set_property( "uri", "file://%s" % (path,))
     210
     211                playBin.set_state(GST_STATE_PLAYING)
     212                _bins.add(playBin)
     213            except Exception, e:
     214                print "mlx.sound.startSound: " + str(e)
     215                if finishCallback is not None:
     216                    finishCallback(False, extra)
    274217
    275218        def finalizeSound():
    276219            """Finalize the sound handling."""
    277             pyglet.app.exit()
     220            pass
     221
     222        def _handlePlayBinMessage(bus, message, bin, finishCallback, extra):
     223            """Handle the end of the playback of a sound file."""
     224
     225            # if message.type==GST_MESSAGE_EOS:
     226            #     _bins.remove(bin)
     227            #     if finishCallback is not None:
     228            #         finishCallback(True, extra)
    278229
    279230    except:
    280         print "The pyglet library is missing from your system. It is needed for sound playback on Linux"
     231        print "The Gst library is missing from your system. It is needed for sound playback on Linux"
     232        traceback.print_exc()
    281233        def initializeSound(soundsDirectory):
    282234            """Initialize the sound handling with the given directory containing
Note: See TracChangeset for help on using the changeset viewer.