Garrett D'Amore wrote:
> St?phane Letz wrote:
>>>>
>>>> But SNDCTL_DSP_GETISPACE./SNDCTL_DSP_GETOSPACE are called "This 
>>>> ioctl call is out of fashion."...
>>>
>>> The reason its out of fashion is that it is really only intended for 
>>> mmap (which 4Front has said is "out of fashion" as well). You really 
>>> shouldn't depend on this at *all*, and should instead avoid any 
>>> assumptions about block size. The only reason to use the above calls 
>>> is if you absolutely can't block, and are unwilling to use select & 
>>> non-blocking read/write calls. Put another way, this ioctl is a 
>>> crutch you shouldn't need. However if you need the crutch, this is 
>>> the one you should use, rather than making assumptions about the 
>>> fragment size.
>>>
>>>>
>>>> I just commited a seperated version of driver now called 
>>>> JackBoomerDriver. Indeed we cannot afford to break the working OSS 
>>>> version (that is "working" at least on the RME MADI 64 in/out 
>>>> channel card we were supposed to develop on...).
>>>
>>> Code written to support OSS should support Boomer just fine. But you 
>>> have to avoid doing things that the OSS documentation tells you not to.
>>>
>>>>
>>>> I now prefer to wait until SUN developers propose a "non completely 
>>>> trivial" example code (like full-duplex blocking one allowing to 
>>>> work with power-of-two buffer size for instance...), that shows 
>>>> *what has to be done the correct way* (and not only describing what 
>>>> should not be done...) with the Boomer "quite different" vision of 
>>>> OSS stuff. Until then I'll not spend more time on that.
>>>
>>> I sent you code. If the code sample was trivial, its because the 
>>> problem itself is trivial. I don't understand what exactly it is you 
>>> want to see. Do you want to see a select/poll driven loop?
>>
>> Not at all ((-:
>>
>>> Do you want to see two threads that work together? I don't know what 
>>> it is you want, but the short answer is: almost the most simple code 
>>> you could develop for this is the *right* code. The complications 
>>> you seem to want to add is where the problems are getting introduced.
>>>
>>> If I have time later, I'll try to make the changes to your OSS code 
>>> to make it do the right thing for *both* stock OSS as well as 
>>> Boomer. If you need separate versions, then either your code is 
>>> incorrect, or the Boomer project has failed.
>>>
>>> -- Garrett
>>
>> Well maybe I should try to explain the "requirement" more clearly: 
>> JACK assume the entire audio process (that is activating the graph of 
>> audio clients) is done on a *fixed* size block on each cycle. We also 
>> need to run at power-of-two block size. We also usually assume (that 
>> is on all other OS JACK is running on) that the *user* choose the 
>> buffer size value given to the driver as the way to select the 
>> overall latency he wants. (this is not completely true since on 
>> LINUX/ALSA, we may choose the fragment (= buffer size) *and* the 
>> number of fragments, but this is quite correct on OSX where the 
>> in/out latency is then : chosen buffer size * 2 + some constant).
>>
>> The server is usually started in duplex mode and the audio cycle does 
>> : (blocking) Read / Process / Write. We may start in input mode only 
>> (so : (blocking) Read / Process) or output mode only (so : Process 
>> (blocking) Write.
>
> So, the only "tricky" part of any thing you've described above, is the 
> disconnect between the natural processing size of JACK (which will be 
> that power-of-two thing, and can be user selectable), and the fixed 
> fragment size of Boomer or OSS.
>
> Note that if you want to use blocking IO *and* support both read and 
> write from the same thread then you'll need to use the aforementioned 
> ioctl. It would be a lot simpler if you could either:
>
> a) run the read and write routines on separate threads, or
> b) use non-blocking IO
>
> Here's a sample processing loop that assumes all IO is blocking, using 
> poll() combined with the ioctls. Error handling is omitted.
>
> int audiofile = open("/dev/dsp", O_RDWR);
>
> for (;;) {
> char readbuf[1024]; // pick whatever size you want here
> char writebuf[1024]; // again, pick whatever size you want
> char *rptr, *wptr;
> int rcnt, wcnt;
> sttruct pollfd pollfd;
>
> pollfd.fd = audiofile;
> pollfd.events = 0;
> pollfd.revents = 0;
>
> if (capturing && rcnt == 1024) {
> // this empties the read buffer by sending capture data to a file or 
> whatever...
> empty_readbuf(readbuf, 1024);
> rcnt = 0;
> rbuf = readbuf;
> }
>
> if (playing && wcnt == 0) {
> // this is your write size, fills writebuf with mixed audio data, etc.
> fill_writebuf(writebuf, 1024);
> wcnt = 1024;
> wbuf = writebuf;
> }
>
> if (capturing) {
> pollfd.events |= POLLIN;
> }
>
> if (playing) {
> pollfd.events |= POLLOUT;
> }
>
> if (pollfd.events == 0) {
> /* no data to read *or* to write, why are we here! */
> abort();
> }
>
> if (poll(&pollfd, 1, 0) < 0) {
> // error handling here
> }
>
> if (pollfd.revents & POLLIN) {
> // data ready for reading
>
> // if the file descriptor was setup for non-blocking reads
> // then we could just call read() instead of using the ioctl
> // error handling omitted
> ioctl(audiofd, SNDCTL_DSP_GETISPACE, &info);
> n = read(audiofd, rbuf, min(info.bytes, 1024 - rcnt));
> rcnt += n;
> rbuf += n;
> }
>
> if (pollfd.revents & POLLOUT) {
> // data ready for writing... similiar to reading case
> ioctl(audiofd, SNDCTL_DSP_GETOSPACE, &info);
> n = write(audiofd, rbuf, min(info.bytes, wcnt));
> wcnt -= n;
> wbuf += n;
> }
>
> }

After I carefully indented everything, my mailer (Thunderbird) removed 
all my tabs.  :-(  If you want me to reindent and send you a clean copy, 
let me know.  I apologize.

    -- Garrett
>
> If the above loop looks pretty simple, well it is. But that's all you 
> need to do. And it will work on *all* OSS versions, not just Boomer or 
> 4Front's code, but also FreeBSD, etc. If you want to avoid the ioctls, 
> you need to either use separate threads for read and write processing, 
> *or* you need to use nonblocking read() and write() calls. (The poll() 
> call will still block for you though.)
>
> -- Garrett
>> Nothing more complex!
>>
>> Thanks
>>
>> Stephane Letz
>>
>>
>
> _______________________________________________
> opensound-discuss mailing list
> opensound-discuss at opensolaris.org
> http://mail.opensolaris.org/mailman/listinfo/opensound-discuss


Reply via email to