Browse Source

questo funziona meglio

encrypt 4 years ago
parent
commit
39c2590630
1 changed files with 44 additions and 19 deletions
  1. 44 19
      mumble-bot/bot.py

+ 44 - 19
mumble-bot/bot.py

@@ -1,11 +1,10 @@
 import pymumble_py3 as pymumble
-from pymumble_py3.callbacks import PYMUMBLE_CLBK_SOUNDRECEIVED as PCS
 import subprocess as sp
-from time import sleep
+import time
 import sys
 import os
 import fcntl
-import pyaudio
+import audioop
 
 pwd = ""  # password
 server = "mumble.esiliati.org"  # server address
@@ -13,29 +12,55 @@ nick = "TubiaBot"
 channel = "radiospore"
 port = 64738  # port number
 
-# pyaudio set up
-CHUNK = 1024
-FORMAT = pyaudio.paInt16  # pymumble soundchunk.pcm is 16 bits
-CHANNELS = 1
-RATE = 48000  # pymumble soundchunk.pcm is 48000Hz
-
-# mumble client set up
-def sound_received_handler(user, soundchunk):
-    """ play sound received from mumble server upon its arrival """
-    sys.stdout.buffer.write(soundchunk.pcm)
-
-
 # Spin up a client and connect to mumble server
 mumble = pymumble.Mumble(server, nick, password=pwd, port=port)
 # set up callback called when PCS event occurs
-mumble.callbacks.set_callback(PCS, sound_received_handler)
 mumble.set_receive_sound(1)  # Enable receiving sound from mumble server
 mumble.start()
 mumble.is_ready()  # Wait for client is ready
 mumble.channels.find_by_name(channel).move_in()
 mumble.users.myself.mute()
 
-# constant capturing sound and sending it to mumble server
+BUFFER = 0.1
+BITRATE = 48000
+RESOLUTION = 10 # in ms
+FLOAT_RESOLUTION = float(RESOLUTION) / 1000
+MONO_CHUNK_SIZE = BITRATE * 2 * RESOLUTION / 1000
+STEREO_CHUNK_SIZE = MONO_CHUNK_SIZE * 2 
+silent = b"\x00" * int(STEREO_CHUNK_SIZE)
+cursor_time = None
+cursor_time = time.time() - BUFFER
+
+while mumble.is_alive():
+
+    if cursor_time < time.time() - BUFFER:  # it's time to check audio
+        base_sound = None
 
-while True:
-    sleep(0.1)
+        try:
+            for user in mumble.users.values():  # check the audio queue of each user
+                while ( user.sound.is_sound() and
+                        user.sound.first_sound().time < cursor_time):
+                    user.sound.get_sound(FLOAT_RESOLUTION)  # forget about too old sounds
+                
+                if user.sound.is_sound():
+                    if ( user.sound.first_sound().time >= cursor_time and
+                         user.sound.first_sound().time < cursor_time + FLOAT_RESOLUTION ):
+                        # available sound is to be treated now and not later
+                        sound = user.sound.get_sound(FLOAT_RESOLUTION)
+                        stereo_pcm = audioop.tostereo(sound.pcm, 2, 1, 1)
+                        if base_sound == None:
+                            base_sound = stereo_pcm
+                        else:
+                            base_sound = audioop.add(base_sound, stereo_pcm, 2)
+        except RuntimeError:
+            eprint("ignored exception in stderr...")
+            
+        if base_sound:
+            sys.stdout.buffer.write(base_sound)
+        else:
+            sys.stdout.buffer.write(silent)
+            
+        cursor_time += FLOAT_RESOLUTION
+    else:
+        time.sleep(FLOAT_RESOLUTION)
+