[Jack-Devel] Fwd: Possible error codes for jack_midi_event_get()?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Jack-Devel] Fwd: Possible error codes for jack_midi_event_get()?

Matthias Geier
Dear list.

I'm the author of one of the Python bindings for JACK:
https://jackclient-python.readthedocs.io/

I was a bit lazy when implementing a generator function that's
supposed to yield all incoming MIDI events one-by-one.

Here's the code if somebody is interested (it's using CFFI and the
_lib object is a wrapper for the JACK API):


    def incoming_midi_events(self):
        event = self._event
        buf = _lib.jack_port_get_buffer(
            self._ptr, self._client.blocksize)
        for i in range(_lib.jack_midi_get_event_count(buf)):
            err = _lib.jack_midi_event_get(event, buf, i)
            # TODO: proper error handling if this ever happens:
            assert not err, err
            yield event.time, _ffi.buffer(event.buffer, event.size)


As you can see, I didn't check the return value of
jack_midi_event_get(), I just added an "assert" statement hoping that
somebody would report it if the call to jack_midi_event_get() would
ever fail.

I didn't hear anything for a long time, but recently I got a bug
report where the assertion was violated:
https://github.com/spatialaudio/jackclient-python/issues/54

This shows that jack_midi_event_get() can raise an error, even if I
check with jack_midi_get_event_count() beforehand.

My question is now: how should I react to this error?

Shall I ...

* discard the current event and continue reading further events?

* discard the current and all following events in this block?

* raise an error?

* do something else?

Can I guarantee that no incoming MIDI events get lost?

Another related question: what error code is supposed to be returned?
The documentation
(http://www.jackaudio.org/api/group__MIDIAPI.html#ga838c794bd1451bfd47edde1c7cd1ff4f)
mentions ENODATA, but according to my bug report, ENOBUFS (-105) was
returned.

Is this a bug in JACK or an omission in the documentation?

I don't know which JACK version was used, the OS was Ubuntu 18.04 LTS 64 bits.

cheers,
Matthias
_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Possible error codes for jack_midi_event_get()?

Hanspeter Portner-2
On 28.07.2018 16:55, Matthias Geier wrote:

> Dear list.
>
> I'm the author of one of the Python bindings for JACK:
> https://jackclient-python.readthedocs.io/
>
> I was a bit lazy when implementing a generator function that's
> supposed to yield all incoming MIDI events one-by-one.
>
> Here's the code if somebody is interested (it's using CFFI and the
> _lib object is a wrapper for the JACK API):
>
>
>     def incoming_midi_events(self):
>         event = self._event
>         buf = _lib.jack_port_get_buffer(
>             self._ptr, self._client.blocksize)
>         for i in range(_lib.jack_midi_get_event_count(buf)):
>             err = _lib.jack_midi_event_get(event, buf, i)
>             # TODO: proper error handling if this ever happens:
>             assert not err, err
>             yield event.time, _ffi.buffer(event.buffer, event.size)
>
>
> As you can see, I didn't check the return value of
> jack_midi_event_get(), I just added an "assert" statement hoping that
> somebody would report it if the call to jack_midi_event_get() would
> ever fail.
>
> I didn't hear anything for a long time, but recently I got a bug
> report where the assertion was violated:
> https://github.com/spatialaudio/jackclient-python/issues/54
>
> This shows that jack_midi_event_get() can raise an error, even if I
> check with jack_midi_get_event_count() beforehand.
>
> My question is now: how should I react to this error?

For JACK1 error is only returned if midi_event_index >= midi_event_count [1].

For JACK2 the same is true; additionally it can fail if the MIDI port buffer is
invalid (whatever that means...) [2].

[1] https://github.com/jackaudio/jack1/blob/master/libjack/midiport.c#L96
[2] https://github.com/jackaudio/jack2/blob/master/common/JackMidiAPI.cpp#L67

>
> Shall I ...
>
> * discard the current event and continue reading further events?
>
> * discard the current and all following events in this block?
>
> * raise an error?
>
> * do something else?

Well, there is no valid event, so ignore it ?

>
> Can I guarantee that no incoming MIDI events get lost?
>

MIDI events can only get lost while multiplexed down from multiple ports into
one (and the latter can not take them all), iirc.

> Another related question: what error code is supposed to be returned?
> The documentation
> (http://www.jackaudio.org/api/group__MIDIAPI.html#ga838c794bd1451bfd47edde1c7cd1ff4f)
> mentions ENODATA, but according to my bug report, ENOBUFS (-105) was
> returned.
>
> Is this a bug in JACK or an omission in the documentation?

It is in the documentation, that it can fail [3].

[3] http://jackaudio.org/api/group__MIDIAPI.html#ga838c794bd1451bfd47edde1c7cd1ff4f

>
> I don't know which JACK version was used, the OS was Ubuntu 18.04 LTS 64 bits.
>
> cheers,
> Matthias
_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Possible error codes for jack_midi_event_get()?

Matthias Geier
On Sat, Jul 28, 2018 at 8:21 PM, Hanspeter Portner wrote:

> On 28.07.2018 16:55, Matthias Geier wrote:
>> Dear list.
>>
>> I'm the author of one of the Python bindings for JACK:
>> https://jackclient-python.readthedocs.io/
>>
>> I was a bit lazy when implementing a generator function that's
>> supposed to yield all incoming MIDI events one-by-one.
>>
>> Here's the code if somebody is interested (it's using CFFI and the
>> _lib object is a wrapper for the JACK API):
>>
>>
>>     def incoming_midi_events(self):
>>         event = self._event
>>         buf = _lib.jack_port_get_buffer(
>>             self._ptr, self._client.blocksize)
>>         for i in range(_lib.jack_midi_get_event_count(buf)):
>>             err = _lib.jack_midi_event_get(event, buf, i)
>>             # TODO: proper error handling if this ever happens:
>>             assert not err, err
>>             yield event.time, _ffi.buffer(event.buffer, event.size)
>>
>>
>> As you can see, I didn't check the return value of
>> jack_midi_event_get(), I just added an "assert" statement hoping that
>> somebody would report it if the call to jack_midi_event_get() would
>> ever fail.
>>
>> I didn't hear anything for a long time, but recently I got a bug
>> report where the assertion was violated:
>> https://github.com/spatialaudio/jackclient-python/issues/54
>>
>> This shows that jack_midi_event_get() can raise an error, even if I
>> check with jack_midi_get_event_count() beforehand.
>>
>> My question is now: how should I react to this error?
>
> For JACK1 error is only returned if midi_event_index >= midi_event_count [1].
>
> For JACK2 the same is true; additionally it can fail if the MIDI port buffer is
> invalid (whatever that means...) [2].
>
> [1] https://github.com/jackaudio/jack1/blob/master/libjack/midiport.c#L96
> [2] https://github.com/jackaudio/jack2/blob/master/common/JackMidiAPI.cpp#L67

Thanks a lot for those links, that's very helpful!

So jack_midi_get_event_count() really just returns the (private)
"event_count" field of the buffer structure.

My follow-up question now is:

Is the "event_count" field ever changed by JACK while a process
callback is running?

It seems unlikely to me, but it looks this is exactly what is
happening in the case of the bug report I've received.

Is it possible that the buffer is cleared while a process callback is
still running?

Of course it would also be possible (but similarly unlikely) that some
of the user code is writing to the buffer structure.

If I didn't miss anything, jack_midi_event_get() can never write to
the "event_count" field.

>> Shall I ...
>>
>> * discard the current event and continue reading further events?
>>
>> * discard the current and all following events in this block?
>>
>> * raise an error?
>>
>> * do something else?
>
> Well, there is no valid event, so ignore it ?

OK.

>> Can I guarantee that no incoming MIDI events get lost?
>
> MIDI events can only get lost while multiplexed down from multiple ports into
> one (and the latter can not take them all), iirc.

OK, good to know.

>> Another related question: what error code is supposed to be returned?
>> The documentation
>> (http://www.jackaudio.org/api/group__MIDIAPI.html#ga838c794bd1451bfd47edde1c7cd1ff4f)
>> mentions ENODATA, but according to my bug report, ENOBUFS (-105) was
>> returned.
>>
>> Is this a bug in JACK or an omission in the documentation?
>
> It is in the documentation, that it can fail [3].
>
> [3] http://jackaudio.org/api/group__MIDIAPI.html#ga838c794bd1451bfd47edde1c7cd1ff4f

Yes, I've used that same link a few lines above.
It tells us about the return value:

    0 on success, ENODATA if buffer is empty.

Having looked at the implementations in the meantime, I now know that
JACK1 returns ENODATA and JACK2 returns -ENOBUFS.

So this is clearly a mismatch between the documentation and the JACK2
implementation.

This also shows that the user who filed the bug report was using
JACK2, since they got a return value of -105 (which is -ENOBUFS).

cheers,
Matthias

>> I don't know which JACK version was used, the OS was Ubuntu 18.04 LTS 64 bits.
>>
>> cheers,
>> Matthias
_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org