On January 22, 2014 10:37:55 PM Tim E. Real wrote:
> 
> Relax, you are right.
> 
> It has taken me a long time but I realize now that the way MusE handles
>  processing is wrong. 
>
> To make a long story (which follows) short, we'll do it the right way,
>  something like this:
> 
> https://github.com/jackaudio/jack2/blob/master/example-clients/capture_clien
> t.c
> 
> Rough blueprint:
> ==============
> 
> The Jack process callback should do one job only:
> Move data into and out of the Jack ports.
> 
> You know all that crap we do in our process callback?
> That's gotta be moved outta there into OUR audio thread.

No!

Man, I hate to flip-flop... but I'm /reversing/ my position regarding
 our Jack process callback. We CAN'T use another thread to 
 transfer data to the callback.

It is *right* the way it is. Really :

The example capture_client.c given is naive and too simple:
It is half-duplex. So it can gingerly pump as many ring buffer items
 as it wants and it doesn't care about how long it takes to process them.
Also, this example is a disk writer - it NEEDS another thread to do that
 as doing such things in the RT thread is bad. 

MusE however is a full-duplex. Waaay different ballgame.

It NEEDS to be synchronous: Read some input data from Jack if available, 
 process it, add any playback material for this period, and write this data to 
 Jack outputs - ALL /during/ a single process callback, not /after/ it's done. 
Problem: If you use your OWN thread to transfer data to the
 Jack process callback, your thread must wait until the process
 callback is done before it can have access to the Jack buffers.
That introduces one EXTRA period of latency.

Yes you /can/ do it, but there's no reason except in special cases.

Today I dug deep for answers:

There are two Jack APIs for processing:
The one we use which is the 'callback' API, and the non-callback API.
http://jackaudio.org/files/docs/html/index.html

The non-callback API looked intriguing because it gives you full
 access to the special RT thread which the Jack backend creates.
Exactly what I was thinking. See the simple example which uses it:

https://github.com/jackaudio/jack2/blob/master/example-clients/tw.c

Ardour has been using non-callback API for years.

But... in the end the two APIs do exactly the /same/ thing and one
 is really no better off using one over the other. See this:

http://permalink.gmane.org/gmane.comp.audio.jackit/23984
                Stéphane Letz 21 Apr 07:40 2011:
"... But anyway I don't really see the point of your "clean" version.  
The " set process calllback" mode was the"historical" mode (classic, 
 easy to understand...), now we also have the "give you thread and 
 use jack_cycle_wait/jack_cycle_signal pair" that give all flexibility 
 needed... "

 which was in response to a question about the API:
http://comments.gmane.org/gmane.comp.audio.jackit/23953

So either API, it still needs to be a real-time ballgame.

What do I mean?
I found *this* absolute *gem* of a response from Paul in response to a 
 question from somebody trying to do the exact SAME thing I suggested,
 using your OWN thread as a data pump worker:

http://jack-audio.10948.n7.nabble.com/Jack-Devel-Using-the-callback-free-API-with-self-created-RT-threads-td17046.html

                Paul Davis Sep 11, 2013:
"JACK provides a thread primarily in the interest of a uniform cross-platform 
 model. if you try this on OS X or windows, you will find that the APIs there 
 also provide a thread in which your callback will run.

what you're doing is adding another layer of buffering between your own RT 
thread(s) and JACK - this is contrary to the entire purpose and intent of a 
pull-mode audio API. it adds to your latency and increases the complexity of 
your code design.

realtime audio is always implemented, ultimately, around a pull model (the 
hardware defines when transfer takes place). if you want to ignore that and 
somehow imagine that you can do your own scheduling, then you just need to add 
a ringbuffer between your other threads and the one that runs the callback. the 
only cases i know where this is important is when running FFT's or other 
similar algorithms which have significant internal latency due to their window-
based model of accumulating a certain amount of data before being able to 
process. you can always wrap a pull model as a push model simply by adding 
buffering, but the normal case for doing this is where the audio generation 
code is running in a non-RT context and needs to be "isolated" from the 
demands of RT processing. it doesn't appear that your program fits into this 
category. "

See how Paul both *mirrored* and *confirmed* everything I said ?

Welcome to real time.
You either have enough process time or not.
If not, you increase the Jack period size OR buy a faster computer.

As I said before, I agree there are some things we can do to speed it up.
Another is maybe splitting the work up between different process calls.
We can use certain Jack functions to determine how much time is left
 in the process call before we gotta get outta there. 

Another is using mutex or trylocks as you say. 
I noticed even Ardour and some of the Jack examples use it WITHIN the process. 
I'm not sure. Wouldn't we need to lock our data OUTSIDE of the process?
I mentioned this great discussion about locks and real-time:
http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing
Kinda scared me off mutexes and such.

Don't worry too much, we'll find ways to help it. 
But no getting away from that darn process cycle...

Cheers. 
Tim.

------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today. 
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Lmuse-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmuse-developer

Reply via email to