OSDN Git Service

update on the audio playing functions
authorShyouzou Sugitani <shy@users.sourceforge.jp>
Thu, 15 Nov 2012 15:23:30 +0000 (00:23 +0900)
committerShyouzou Sugitani <shy@users.sourceforge.jp>
Thu, 15 Nov 2012 15:23:30 +0000 (00:23 +0900)
ChangeLog
lib/ninix/dll/mciaudio.py
lib/ninix/dll/mciaudior.py
lib/ninix/sakura.py

index dbf9669..8ad6e71 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Fri November 16 2012   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * SakuraScriptの\![sound]および\_Vを実装した.
+         再生にはGstreamerを使用する.
+         (\![sound]はplay, cdplay, loop, stop, wait, pause, resume全て対応.)
+       * lib/ninix/dll/mciaudior.py, mciaudio.py:
+         再生状態を独自に管理するのではなく, 情報をGstreamerから
+         取得するように修正した.
+
 Thu November 15 2012   Shyouzou Sugitani <shy@users.sourceforge.jp>
        * OnGhostChangingイベントのReferenceの内容を修正した.
          (Reference0からReference3まで全てに対応した.)
index 3f7fc2e..2c145a6 100644 (file)
@@ -38,7 +38,6 @@ class Saori(SAORI):
         bus.connect('message', self.on_message)
         self.filepath = None
         self.__sakura = None
-        self.state = 0 # 0/1/2 - stop/playing/paused
 
     def need_ghost_backdoor(self, sakura):
         self.__sakura = sakura
@@ -59,12 +58,10 @@ class Saori(SAORI):
             if argv[0] == 'stop':
                 self.player.set_state(Gst.State.NULL)
             elif argv[0] == 'play':
-                if self.state == 2:
-                    self.state = 1
+                if self.player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PAUSED:
                     self.player.set_state(Gst.State.PLAYING)
                     return self.RESPONSE[204]
-                elif self.state == 1:
-                    self.state = 2
+                elif self.player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PLAYING:
                     self.player.set_state(Gst.State.PAUSED)
                     return self.RESPONSE[204]
                 if self.filepath is not None and os.path.isfile(self.filepath):
@@ -89,9 +86,7 @@ class Saori(SAORI):
         t = message.type
         if t == Gst.MessageType.EOS:
             self.player.set_state(Gst.State.NULL)
-            self.state = 0
         elif t == Gst.MessageType.ERROR:
             self.player.set_state(Gst.State.NULL)
             err, debug = message.parse_error()
             logging.error('Error: {0}, {1}'.format(err, debug))
-            self.state = 0
index f5ac53c..98be2d9 100644 (file)
@@ -37,7 +37,6 @@ class Saori(SAORI):
         bus.add_signal_watch()
         bus.connect('message', self.on_message)
         self.filepath = None
-        self.state = 0 # 0/1/2 - stop/playing/paused
         self.loop = False
 
     def check_import(self):
@@ -58,12 +57,10 @@ class Saori(SAORI):
             elif argv[0] in ['play', 'loop']:
                 if argv[0] == 'loop':
                     self.loop = True
-                if self.state == 2:
-                    self.state = 1
+                if self.player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PAUSED:
                     self.player.set_state(Gst.State.PLAYING)
                     return self.RESPONSE[204]
-                elif self.state == 1:
-                    self.state = 2
+                elif self.player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PLAYING:
                     self.player.set_state(Gst.State.PAUSED)
                     return self.RESPONSE[204]
                 if self.filepath is not None and os.path.isfile(self.filepath):
@@ -85,12 +82,8 @@ class Saori(SAORI):
             self.player.set_state(Gst.State.NULL)
             if self.loop:
                 self.player.set_state(Gst.State.PLAYING)
-                self.state = 1
-            else:
-                self.state = 0
         elif t == Gst.MessageType.ERROR:
             self.player.set_state(Gst.State.NULL)
             err, debug = message.parse_error()
             logging.error('Error: {0}, {1}'.format(err, debug))
-            self.state = 0
             self.loop = False
index fbc68ae..6959983 100644 (file)
@@ -77,6 +77,7 @@ class Sakura:
     BROWSE_MODE = 1
     SELECT_MODE = 2
     PAUSE_MODE  = 3
+    WAIT_MODE   = 4 
     # script origins
     FROM_SSTP_CLIENT = 1
     FROM_GHOST       = 2
@@ -133,8 +134,12 @@ class Sakura:
             self.audio_player = Gst.ElementFactory.make('playbin', 'player')
             fakesink = Gst.ElementFactory.make('fakesink', 'fakesink')
             self.audio_player.set_property('video-sink', fakesink)
+            bus = self.audio_player.get_bus()
+            bus.add_signal_watch()
+            bus.connect('message', self.on_audio_message)
         else:
             self.audio_player = None
+        self.audio_loop = False
 
     def set_responsible(self, request_method):
         self.request_parent = request_method
@@ -318,6 +323,25 @@ class Sakura:
     def leave_temp_mode(self):
         self.__temp_mode = 0
 
+    def on_audio_message(self, bus, message):
+        if message is None: # XXX: workaround for Gst Version < 0.11
+            if self.script_mode == self.WAIT_MODE:
+                self.script_mode = self.BROWSE_MODE
+            return
+        t = message.type
+        if t == Gst.MessageType.EOS:
+            self.audio_player.set_state(Gst.State.NULL)
+            if self.script_mode == self.WAIT_MODE:
+                assert not self.audio_loop
+                self.script_mode = self.BROWSE_MODE
+            if self.audio_loop:
+                self.audio_player.set_state(Gst.State.PLAYING)
+        elif t == Gst.MessageType.ERROR:
+            self.audio_player.set_state(Gst.State.NULL)
+            err, debug = message.parse_error()
+            logging.error('Error: {0}, {1}'.format(err, debug))
+            self.audio_loop = False
+
     def set_surface(self, desc, alias, surface, name, surface_dir, tooltips):
         self.surface.new(desc, alias, surface, name, surface_dir, tooltips)
         for side in range(2, self.char):
@@ -1125,6 +1149,7 @@ class Sakura:
         self.balloon.finalize()
         if self.audio_player is not None:
             self.audio_player.set_state(Gst.State.NULL)
+        self.audio_loop = False
 
     def process_script(self):
         now = time.time()
@@ -1155,6 +1180,8 @@ class Sakura:
             ##if idle > self.PAUSE_TIMEOUT:
             ##    self.script_mode = self.BROWSE_MODE
             pass
+        elif self.script_mode == self.WAIT_MODE:
+            pass
         elif self.processed_script or self.processed_text:
             self.interpret_script()
         elif self.script_post_proc:
@@ -1570,6 +1597,7 @@ class Sakura:
             self.audio_player.set_state(Gst.State.NULL)
             self.audio_player.set_property(
                 'uri', 'file://' + urllib.parse.quote(path))
+            self.audio_loop = False
             self.audio_player.set_state(Gst.State.PLAYING)
 
     def __yen_8(self, args):
@@ -1586,8 +1614,15 @@ class Sakura:
             self.audio_player.set_state(Gst.State.NULL)
             self.audio_player.set_property(
                 'uri', 'file://' + urllib.parse.quote(path))
+            self.audio_loop = False
             self.audio_player.set_state(Gst.State.PLAYING)
 
+    def __yen__V(self, args):
+        if self.audio_loop:
+            return # nothing to do
+        if self.audio_player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PLAYING:
+            self.script_mode = self.WAIT_MODE
+
     def __yen_exclamation(self, args): ## FIXME
         if not args:
             return
@@ -1705,6 +1740,58 @@ class Sakura:
                     gsettings.set_string('picture-options', opt)
                 else:
                     pass # not implemented yet
+        elif args[0] == 'sound':
+            command = args[1]
+            if self.audio_player is None:
+                return
+            if command == 'stop':
+                self.audio_player.set_state(Gst.State.NULL)
+                self.audio_loop = False
+            elif command == 'play':
+                filename = args[2]
+                filename = get_normalized_path(filename)
+                path = os.path.join(self.get_prefix(),
+                                    b'ghost/master', filename)
+                if os.path.isfile(path):
+                    self.audio_player.set_state(Gst.State.NULL)
+                    self.audio_player.set_property(
+                        'uri', 'file://' + urllib.parse.quote(path))
+                    self.audio_loop = False
+                    self.audio_player.set_state(Gst.State.PLAYING)
+            elif command == 'cdplay':
+                self.audio_player.set_state(Gst.State.NULL)
+                try:
+                    track = int(args[2])
+                except:
+                    return
+                self.audio_player.set_property(
+                    'uri', 'cdda://{}'.format(track))
+                self.audio_loop = False
+                self.audio_player.set_state(Gst.State.PLAYING)
+            elif command == 'loop':
+                filename = args[2]
+                filename = get_normalized_path(filename)
+                path = os.path.join(self.get_prefix(),
+                                    b'ghost/master', filename)
+                if os.path.isfile(path):
+                    self.audio_player.set_state(Gst.State.NULL)
+                    self.audio_player.set_property(
+                        'uri', 'file://' + urllib.parse.quote(path))
+                    self.audio_loop = True
+                    self.audio_player.set_state(Gst.State.PLAYING)
+            elif command == 'wait':
+                if self.audio_loop:
+                    return # nothing to do
+                if self.audio_player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PLAYING:
+                    self.script_mode = self.WAIT_MODE
+            elif command == 'pause':
+                if self.audio_player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PLAYING:
+                    self.audio_player.set_state(Gst.State.PAUSED)
+            elif command == 'resume':
+                if self.audio_player.get_state(timeout=Gst.SECOND)[1] == Gst.State.PAUSED:
+                    self.audio_player.set_state(Gst.State.PLAYING)
+            else:
+                pass ## FIXME
         elif args[0] == '*':
             self.balloon.append_sstp_marker(self.script_side)
         else:
@@ -1774,6 +1861,7 @@ class Sakura:
         r'\_u': __yen__u,
         r'\_v': __yen__v,
         r'\8': __yen_8,
+        r'\_V': __yen__V,
         r'\!': __yen_exclamation,
         r'\__c': __yen___c,
         r'\__t': __yen___t,