I'm trying to figure how to keep the client running but it just shows up for a little
# coding=utf-8
import io
import logging
import sys
import jack
import soundfile as sf
import queue
import threading
BUFFERSIZE = 1024
class AudioLib:
def __init__(self):
self.log = logging.getLogger(__name__)
self.log.info("INIT AUDIO LIB")
self.buffersize = BUFFERSIZE
self.queue = queue.Queue(maxsize=self.buffersize)
self.event = threading.Event()
self.jack_client = jack.Client('TEST', session_id='Test')
self.blocksize = self.jack_client.blocksize
self.samplerate = self.jack_client.samplerate
self.jack_client.set_xrun_callback(self.xrun)
self.jack_client.set_shutdown_callback(self.shutdown)
self.jack_client.set_process_callback(self.process)
self.voice_output_0 = self.jack_client.outports.register('voice_0')
print("ACTIVATE")
self.jack_client.activate()
# self.jack_client.connect(self.voice_output_0, 'system:playback_1')
def play(self, format, audio, fin):
audio_samplerate, bits, channels = format
with sf.SoundFile(io.BytesIO(audio),
channels=channels,
samplerate=audio_samplerate,
format='RAW',
subtype='FLOAT') as audio_stream:
block_generator = audio_stream.blocks(blocksize=self.blocksize,
always_2d=True, fill_value=0)
for _, data in zip(range(self.buffersize), block_generator):
self.queue.put_nowait(data) # Pre-fill queue
timeout = self.blocksize * self.buffersize / self.samplerate
for data in block_generator:
self.queue.put(data, timeout=timeout)
self.queue.put(None, timeout=timeout) # Signal end of file
self.event.wait() # Wait until playback is
def print_error(self, *args):
print(*args, file=sys.stderr)
def xrun(self, delay):
self.print_error("An xrun occured, increase JACK's period size?")
def shutdown(self, status, reason):
self.print_error('JACK shutdown!')
self.print_error('status:', status)
self.print_error('reason:', reason)
self.event.set()
def stop_callback(self, msg=''):
if msg:
self.print_error(msg)
for port in self.jack_client.outports:
port.get_array().fill(0)
self.event.set()
raise jack.CallbackExit
def process(self, frames):
assert frames == self.jack_client.blocksize
try:
data = self.queue.get_nowait()
for channel, port in zip(data.T, self.jack_client.outports):
port.get_array()[:] = channel
except queue.Empty:
self.stop_callback('Buffer is empty: increase buffersize?')
if data is None:
self.stop_callback() # Playback is finished
else:
for channel, port in zip(data.T, self.jack_client.outports):
port.get_array()[:] = channel