Re: [Jack-Devel] major change in jack1 MIDI handling

PrevNext  Index
DateWed, 16 Oct 2013 01:25:58 -0700
From Devin Anderson <[hidden] at gmail dot com>
ToStéphane Letz <[hidden] at grame dot fr>
CcJACK <[hidden] at lists dot jackaudio dot org>
In-Reply-ToStéphane Letz Re: [Jack-Devel] major change in jack1 MIDI handling
Follow-UpStéphane Letz Re: [Jack-Devel] major change in jack1 MIDI handling
Follow-UpStéphane Letz Re: [Jack-Devel] major change in jack1 MIDI handling
Follow-UpStéphane Letz Re: [Jack-Devel] major change in jack1 MIDI handling
Follow-UpChristian Schoenebeck Re: [Jack-Devel] major change in jack1 MIDI handling
Hi Stéphane,

On Wed, Oct 16, 2013 at 12:16 AM, Stéphane Letz <[hidden]> wrote:

>> The reason I chose to add code to JACK 2 is because C++ afforded me
>> the path of least resistance.
>
> Which is by itself quite a real argument… ((-;

Sure.

> At that time, my feeling was that your C++ MIDI backend architecture
> was quite elegant and could be inserted quite easily in the global
> backend model.

I appreciate the compliment.  Thank you.

>> I prefer the architecture and code structure of JACK 1.
>
> You preferred JACK1 code structure, but you coded in C++. So why
> in the first place?

JACK 1 has a simpler codebase.  In my experience, when I've wanted to
understand how any particular thing works in JACK 1 vs. how it works
in JACK 2, I've had a much easier time figuring out how things work in
JACK 1.  However, my own designs are generally object-oriented, so if
I want to add a significant amount of code to a project, I'm less
inclined to do so if the project itself isn't object-oriented.

This isn't to say that JACK 1 doesn't have anything resembling
object-oriented architecture.  It's driver system, for example, is
basically object-oriented, even though the bindings are modular
because C is in use.  Speaking of the driver design ...

> Anyway this discussion is again coming to an end: the result of all
> this years is that people generally criticize, but *never* provide any
> real significant re-structure/improvement ideas, new code design…
> etc…

A few years ago, I would have had more to say (and did, at times,
IIRC).  I'm not as familiar with the JACK 2 codebase as I used to be.

And you're right - it's not fair for me to express my dislike of the
JACK 2 architecture, design, etc. and not give some specifics.

One problem I remember trying to wrap my head around was the Open
functions in the JACK 2 driver system.  Let's take a brief look at
those now.

1.) The JackDriverInterface class has three pure virtual Open()
functions.  IIRC, there isn't one driver I've seen that implements all
three of these functions.  That's confusing.

2.) Then there's the JackDriver class that extends the
JackDriverInterface class.  The class is meant to be a base class, but
it implements all three of the virtual functions.  These
implementations are meant to be called by subclasses that override the
JackDriver virtual functions, which is an ugly anti-pattern.  If
JackDriver's Open functions are called without the overriding wrapper
function, then hilarity may ensue when the underlying JackDriver part
of the class thinks the driver has been successfully opened.

3.) There's also JackThreadDriver, which also extends the
JackDriverInterface class (not JackDriver!).  It also provides
implementations for the three Open functions, one of which just fails
by returning -1.  If the JackThreadDriver class doesn't need some of
the API from the JackDriverInterface class, then either
JackDriverInterface should be changed, or JackThreadDriver shouldn't
extend JackDriverInterface.

4.) Speaking of returning -1 for non-realtime errors, I'm of the
opinion that throwing exceptions is a fantastic way to handle errors.
It's okay to write data to stderr and to indicate that some sort of
error happened, but it's even better to throw an exception containing
a reason for the error occurring so that it can be handled at an
appropriate place for handling errors.  Also, not checking return
values for error codes again and again is a good thing.  Note that
JACK 1 also has this problem; however, given that it's written in C,
I'm a little more forgiving.

5.) I said before that there isn't one driver I've seen that
implements all three of the Open() functions.  Looking through the
Linux-specific drivers, I see that JACKAlsaDriver and
JackALSARawMidiDriver (I wrote that one) implement only one Open()
function each.  Here's a bit of a curve ball - JackFreebobDriver and
JackFFADODriver each define an Open function with a completely
different signature!  So, why does JackDriverInterface have a public
definition for Open() functions that may never be used, and aren't
meant to be used at all at times?

So, there's an example.  It's likely too little, too late, but
hopefully you can generalize some of what I'm talking about to the
rest of the code, because the problems above can be found in more
places than just the Open() functions of Jack drivers.

Thanks,

-- 
Devin Anderson
surfacepatterns (at) gmail (dot) com

blog - http://surfacepatterns.blogspot.com/
midisnoop - http://midisnoop.googlecode.com/
psinsights - http://psinsights.googlecode.com/
synthclone - http://synthclone.googlecode.com/
PrevNext  Index

1381911964.17373_0.ltw:2, <CAG7zqTp8CO_kioYn2M=Pm7_fOmBQghgt7aGHTFMzyOCg9wmomQ at mail dot gmail dot com>