[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebob-devel
Subject:    Re: [Freebob-devel] libfreebob-2.0: replacement JACK driver issue
From:       Jonathan Woithe <jwoithe () physics ! adelaide ! edu ! au>
Date:       2006-09-05 23:58:53
Message-ID: 200609052346.k85NkrMJ015530 () auster ! physics ! adelaide ! edu ! au
[Download RAW message or body]

> > Regarding the MOTU I am now starting to work with JACK to see if I can
> > get something sensible happening through that interface.  When trying the
> > replacement JACK driver in libfreebob-2.0's support/ area over the weekend
> > though I struck an interesting problem.
> >
> > freebob_driver_attach() has responsibility for setting up the streams ready
> > for use and to this end calls
> > freebob_streaming_set_{playback,capture}_buffer_type() in order to configure
> > the buffer type.  However, it does not call
> > freebob_streaming_set_{playback,capture}_stream_buffer() - that is left to
> > freebob_driver_read() because the appropriate JACK buffer to use can only be
> > determined during streaming operation (via jack_port_get_buffer()).
> >
> > The problem is that because the freebob_streaming_set_*_stream_buffer()
> > function is not called before freebob_streaming_prepare() freebob assumes
> > that the buffers are internal and allocates them accordingly.  When
> > freebob_driver_read() eventually calls
> > freebob_streaming_set_*_stream_buffer() we get an assertion failure in
> > Port::setExternalBufferAddress() because at this point the buffer type is
> > internal and setting the buffer pointer on a stream which uses an internal
> > buffer is not allowed.
> >
> > I tried fixing this by inserting a call to
> > freebob_streaming_set_*_stream_buffer() in freebob_driver_attach() after
> > freebob_streaming_set_*_buffer_type(), passing NULL as the pointer.  The
> > reasoning was that this would at least inform freebob that an external
> > buffer was to be used; freebob_driver_read() and freebob_driver_write()
> > would continue to call freebob_streaming_set_*_stream_buffer() with an
> > appropriate buffer address when required so there was going to be no problem
> > with the NULL pointer.  The trouble with this approach was that
> > freebob_streaming_set_*_stream_buffer() calls useExternalBuffer() before
> > setting the pointer, and following initialisation useExternalBuffer() throws
> > an error message to stdout.  These messages obviously cause a huge delay in
> > the streaming thread and things go pear-shaped fairly rapidly as a result of
> > the induced latency.
> >
> > Given all this, what would be the most appropriate way of dealing with this
> > little issue?  Should we just remove the offending failure mode from
> > Port::useExternalBuffer() and allow the setting of the buffer for an
> > initialised port or pursue a more obviously "safe" solution?  The only
> > "safe" alternative I can see is to utilise a bounce-buffer in
> > freebob_driver_read() and freebob_driver_write(), but this is undesireable
> > because it adds extra processing overheads.
> >   
> The C API is a mess, so don't consider it as 'golden' ;).
> It has been a while since I've touched the freebob code, and I don't 
> have time now to review it. But I think the idea is that the jackd 
> backend should have a way to indicate that it want's to use external 
> buffers before calling prepare(). Maybe we need another API call.

Hmm, ok.  The current issue isn't really the communication of the need to
use an external buffer - that works perfectly well with the current code
by calling freebob_streaming_set_*_stream_buffer() with a NULL buffer pointer.
Of course this might be regarded as a bit of a hack and perhaps the C API
does need a wrapper function around Port::useExternalBuffer(), but at
the moment that's not an insurmountable issue.

The real problem is that currently freebob_streaming_set_*_stream_buffer()
unconditionally calls useExternalBuffer() before setting the pointer, and
doing so following initialisation causes an output to stderr (which in turn
creates latency that the system can't cope with).  Since it seems that
setting the buffers following initialisation is OK, what I would propose is
that instead of calling useExternalBuffer() unconditionally,
freebob_streaming_set_*_stream_buffer() only calls it prior to
initialisation.  We wouldn't loose any error trapping by doing this because
Port::setExternalBufferAddress() confirms the buffer is external before
setting the pointer.

I'll give this some thought over the next few days and see what I come
up with.

Regards
  jonathan

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Freebob-devel mailing list
Freebob-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freebob-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic