[sugar] [PATCH] Fix startup sound playback.

Chris Ball cjb at laptop.org
Thu Nov 1 21:15:17 EDT 2007


Hi,

The sugar startup sound playback broke sound in Joyride, because a
callback for closing the playback pipeline was not registered, and as a
result gstreamer kept the pipeline (and audio device) open for as long
as the process (sugar-shell) stayed running.  I fixed this in two ways
that make sense to me, and one that doesn't:

* We now supply a callback for the "message::eos" signal, and change
  the player state to NULL instead of PLAYING in it.

* I tried doing this with a lambda, but exposed another problem with the
  current function -- Python pulls down variables as a function is
  exited, and our playback function exited before the sound finished (or
  started) playing.  I stuck the player object into main as a property
  so that it sticks around until it can close the pipeline.

* That still didn't fix it; any activities launched retained an open
  pcm device.  I tried calling _shell_started() directly, instead
  of as a gobject_idle_add() callback, and this fixed it.  I don't
  understand why.  The playback happens in roughly the same part
  of the startup sequence as it originally did.
  
All three changes are necessary to get sound working again.
Please review and apply.

---
 bin/sugar-shell |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/bin/sugar-shell b/bin/sugar-shell
index 8f78289..c439085 100755
--- a/bin/sugar-shell
+++ b/bin/sugar-shell
@@ -82,20 +82,29 @@ def check_cm(bus_name):
         pass
     return False
 
-def _shell_started_cb():
+def _eos_cb(bus, message):
+    main.player.set_state(gst.STATE_NULL)
+
+def _error_cb(bus, message):
+    error = message.parse_error()
+    print error[1]
+
+def _shell_started():
     # Unfreeze the display
     hw_manager = hardwaremanager.get_manager()
     hw_manager.set_dcon_freeze(0)
 
     startup_sound = os.path.join(env.get_data_path('startup.flac'))
     if os.path.exists(startup_sound):
-        player = gst.element_factory_make("playbin", "player")
-        player.set_property("uri", "file://" + startup_sound)
-        player.set_state(gst.STATE_PLAYING)
+        main.player = gst.element_factory_make("playbin", "player")
+        main.player.set_property("uri", "file://" + startup_sound)
+        bus = main.player.get_bus()
+        bus.add_signal_watch()
+        bus.connect("message::eos", _eos_cb)
+        bus.connect("message::error", _error_cb)
+        main.player.set_state(gst.STATE_PLAYING)
 
 def main():
-    gobject.idle_add(_shell_started_cb)
-
     logsmanager.setup()
     logger.start('shell')
 
@@ -145,6 +154,7 @@ def main():
     model = ShellModel()
     shell = Shell(model)
     service = ShellService(shell)
+    shell_started()
 
 if __name__ == '__main__':
     # running the gtk.main outside of the main() function allows us to 
-- 
Chris Ball   <cjb at laptop.org>


More information about the Sugar mailing list