Index: src/mlx/sound.py
===================================================================
--- src/mlx/sound.py	(revision 133)
+++ src/mlx/sound.py	(revision 170)
@@ -4,4 +4,5 @@
 
 import os
+import traceback
 
 #------------------------------------------------------------------------------
@@ -50,15 +51,15 @@
 
             self._requestCondition = threading.Condition()
-            self._requestedPaths = []
-            self._pendingAliases = []
+            self._requests = []
+            self._pending = []
             self._count = 0
 
             self.daemon = True
 
-        def requestSound(self, name):
+        def requestSound(self, name, finishCallback = None, extra = None):
             """Request the playback of the sound with the given name."""
             path = os.path.join(self._soundsDirectory, name)
             with self._requestCondition:
-                self._requestedPaths.append(path)
+                self._requests.append((path, (finishCallback, extra)))
                 self._requestCondition.notify()
 
@@ -72,8 +73,8 @@
             while True:
                 with self._requestCondition:
-                    if not self._requestedPaths:
-                        if self._pendingAliases:
-                            timeout = max(time.time() -
-                                          self._pendingAliases[0][0], 0.0)
+                    if not self._requests:
+                        if self._pending:
+                            timeout = max(time.time() - self._pending[0][0],
+                                          0.0)
                         else:
                             timeout = 10.0
@@ -81,18 +82,19 @@
                         self._requestCondition.wait(timeout)
 
-                    requestedPaths = []
-                    for path in self._requestedPaths:
-                        requestedPaths.append((path, self._count))
+                    requests = []
+                    for (path, finishData) in self._requests:
+                        requests.append((path, finishData, self._count))
                         self._count += 1
-                    self._requestedPaths = []
+                    self._requests = []
 
                     now = time.time()
-                    aliasesToClose = []
-                    while self._pendingAliases and \
-                          self._pendingAliases[0][0]<=now:
-                        aliasesToClose.append(self._pendingAliases[0][1])
-                        del self._pendingAliases[0]
+                    toClose = []
+                    while self._pending and \
+                          self._pending[0][0]<=now:
+                        toClose.append(self._pending[0][1])
+                        del self._pending[0]
 
-                for alias in aliasesToClose:
+                for (alias, (finishCallback, extra)) in toClose:
+                    success = True
                     try:
                         print "Closing", alias
@@ -101,6 +103,13 @@
                     except Exception, e:
                         print "Failed closing " + alias + ":", str(e)
+                        success = False
 
-                for (path, counter) in requestedPaths:
+                    if finishCallback is not None:
+                        try:
+                            finishCallback(success, extra)
+                        except:
+                            traceback.print_exc()
+
+                for (path, finishData, counter) in requests:
                     try:
                         alias = "mlxsound%d" % (counter,)
@@ -117,9 +126,15 @@
                         timeout = time.time() + length / 1000.0
                         with self._requestCondition:
-                            self._pendingAliases.append((timeout, alias))
-                            self._pendingAliases.sort()
+                            self._pending.append((timeout, (alias, finishData)))
+                            self._pending.sort()
                         print "Started to play", path
                     except Exception, e:
-                        print "Failed to start playing " + path + ":", str(e)
+                        print "Failed to start playing " + path + ":", str(e)                        
+                        (finishCallback, extra) = finishData
+                        if finishCallback is not None:
+                            try:
+                                finishCallback(None, extra)
+                            except:
+                                traceback.print_exc()
 
     _thread = None
@@ -132,10 +147,11 @@
         _thread.start()
 
-    def startSound(name):
+    def startSound(name, finishCallback = None, extra = None):
         """Start playing back the given sound.
         
         name should be the name of a sound file relative to the sound directory
         given in initializeSound."""
-        _thread.requestSound(name)
+        _thread.requestSound(name, finishCallback = finishCallback,
+                             extra = extra)
         
 #------------------------------------------------------------------------------
@@ -147,5 +163,5 @@
         pass
 
-    def startSound(name):
+    def startSound(name, finishCallback = None, extra = None):
         """Start playing back the given sound.
 
@@ -157,12 +173,15 @@
 
 if __name__ == "__main__":
+    def callback(result, extra):
+        print "callback", result, extra
+    
     initializeSound("e:\\home\\vi\\tmp")
-    startSound("malev.mp3")
+    startSound("malev.mp3", finishCallback = callback, extra="malev.mp3")
     time.sleep(5)
-    startSound("ding.wav")
+    startSound("ding.wav", finishCallback = callback, extra="ding1.wav")
     time.sleep(5)
-    startSound("ding.wav")
+    startSound("ding.wav", finishCallback = callback, extra="ding2.wav")
     time.sleep(5)
-    startSound("ding.wav")
+    startSound("ding.wav", finishCallback = callback, extra="ding3.wav")
     time.sleep(50)
 
