>>>
>>
>> I understand the need for 2 threads in "general" case, but here  
>> the requeriments are somewhat restricted. JACK server runs usually  
>> in *duplex* mode, using a card and using input and output devices  
>> of the *same* card. That is we assume both devices runs completely  
>> synchronized (otherwise we are not going to try having a system  
>> meant for completely synchronous execution to work reliably....)
>
> Duplex works fine with multiple threads.  You can have two file  
> descriptors, one used by the reading thread (opened O_RDONLY) and  
> one used by the playback thread (opened O_WRONLY).  You don't have  
> to use only a single file descriptor to make this work.
>
> You should *not* assume that the two sides (read vs. write) are  
> synchronized.  On a single device, they might have different  
> fragmentation boundaries, and might use completely independent  
> clocks!  (This is not as uncommon as you might think.)

Do you mean with an input and output rate that would not stay in  
synch? What is the application supposed to do (for example in a input  
==> some processing  ==> output case) Resample?

>
> I think the root of your troubles here are "assumptions".  Well  
> written code won't have any such assumptions and will work well  
> regardless of the details of the device driver, or even the  
> underlying implementation.
>
>>
>> That said, the system is supposed to consume and produce frames at  
>> the right time! Said in another way, if the execution of the  
>> client graph takes toom much time, then we have an "Xrun (overrun/ 
>> underrun)" which is perfectly normal... What else could we do? We  
>> can possible smooth  "occasionnal" CPU spike a bit by prefilling  
>> the output buffer, but in the general case, the audio cycle :  
>> Read / Process/ Write is not supposed to take more time than  
>> represented but the "buffer size" used in the graph processing.
>
> *That* is a bad assumption.  You're trying to get a promise/ 
> guarantee from the kernel that simply doesn't exist.  And, you  
> don't actually need the promise if your code is written properly.
>
> To prevent overruns or underruns, you need to either restrict your  
> writes or reads to the size that can be performed without blocking  
> (which you can learn with the SNDCTL_DSP_GETOSPACE/ISPACE ioctls),  
> or use non-blocking IO.  If you want to do this for both read and  
> write in a single thread, you'll need to also use poll().
>
> All the other approaches you're thinking of are hacks that *might*  
> work for some of the devices some of the time, but which are  
> technically "incorrect" and will almost certainly fail for *some*  
> devices, at least some of the time.

Do we at least agree on the fact that a duplex processing application  
*cannot* use more than the time slice represented by the buffer-size  
value the application processing part is using, *on average* ?

  (I agree that for a *given* cycle this may be more, if the output  
buffer has some frames in advance to compensate...)

>
>>
>> So to summarize, we prefill output a bit to avoid underruns, then  
>> the Read / Process/ Write is supposed to work at the right speed.  
>> And this one thread model simplify others parts: we don't need to  
>> use additonal "ring-buffers" or "queues" to move data between the  
>> thread that calls the graph "Process" and the one that would call  
>> Read/Write.
>
> Okay, one thread will work for you, but you need to use the poll or  
> ioctl or nonblocking approaches I've already pointed out then.  My  
> sample code should help you out there.
>
> Actually, with your crazy processing considerations, probably what  
> we should do is look into getting you mmap(2) support, where you  
> can just run completely disconnected from the kernel code, and use  
> whatever speed and rate is most comfortable for your server.   
> Unfortunately, the mmap(2) syscall isn't supported by Boomer Phase  
> I (it will be in Phase II), and in any case it isn't portable to  
> all drivers.  (4Front's code only supports it on Linux, and only  
> for some devices ... e.g. USB audio probably doesn't support it  
> because USB devices don't use memory mapped IO.)

Yes I know mmap would be much better (used in JACK ALSA backend  in  
Linux)

Stephane Letz

Reply via email to