Hi and thanks for the great library, been using it for years!
What's the best way to detect if the last process callback lead to an xrun? Here's my use case: I'm sending MIDI, which works 99% of the time. But when an xrun occurs, the MIDI events aren't sent to connected inputs and on the next process callback I clear the buffer and they're lost forever. Here's how I'm currently doing it:
jack_midi_event_write=jack._lib.jack_midi_event_writejack_port_get_buffer=jack._lib.jack_port_get_bufferclassProcess:
__slots__= ('_before', '_buffer', '_client', '_port', '_xrun')
def__init__(self, client: jack.Client, port: jack.OwnMidiPort) ->None:
self._before=0;
self._buffer=jack.RingBuffer(2**8)
self._xrun=threading.Event()
self._client=clientself._port=portdefprocess(self, frames: int) ->None:
xrun=self._xrunxrun_set=xrun.is_set()
port=self._portclient=port._clientlast_frame_time=client.last_frame_timeblocksize=client.blocksizeifnotxrun_setandlast_frame_time-blocksize==self._before:
port.clear_buffer()
ifxrun_set:
xrun.clear()
self._before=last_frame_timesrc_buffer=self._bufferspace=src_buffer.read_spaceifspace!=0:
data=src_buffer.read(space)
dst_buffer=jack_port_get_buffer(port._ptr, blocksize)
i=0whilei!=space:
jack_midi_event_write(dst_buffer, 0, data[i : i+3], 3)
i+=3defhandle_xrun(self, delay_usec: float) ->None:
self._xrun.set()
def_append(self, event: Tuple[int, int, int]) ->None:
self._buffer.write(bytes(event))
defnote_on(self, note: int) ->None:
self._append((0x99, note, 100))
defnote_off(self, note: int) ->None:
self._append((0x89, note, 0))I'm doing two things:
I'm comparing last_frame_time - blocksize to the last_frame_time on the previous process callback.
Using the set_xrun_callback to set a threading.Event()
I'm not sure if I'm doing any of this correctly, just experimenting to see what works. I know you're not meant to use Python for realtime, but it's working too well to justify moving to C++.
Thanks.
Hi and thanks for the great library, been using it for years!
What's the best way to detect if the last process callback lead to an xrun? Here's my use case: I'm sending MIDI, which works 99% of the time. But when an xrun occurs, the MIDI events aren't sent to connected inputs and on the next process callback I clear the buffer and they're lost forever. Here's how I'm currently doing it:
I'm doing two things:
I'm comparing
last_frame_time - blocksizeto thelast_frame_timeon the previous process callback.Using the
set_xrun_callbackto set athreading.Event()I'm not sure if I'm doing any of this correctly, just experimenting to see what works. I know you're not meant to use Python for realtime, but it's working too well to justify moving to C++.
Thanks.