We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3705 - [patch] Add capture support to the sndio backend
Summary: [patch] Add capture support to the sndio backend
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: audio (show other bugs)
Version: HG 2.1
Hardware: All OpenBSD
: P2 enhancement
Assignee: Ryan C. Gordon
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-20 01:43 UTC by kdrakehp
Modified: 2017-07-21 00:43 UTC (History)
0 users

See Also:


Attachments
Add capture support to the sndio backend (4.27 KB, patch)
2017-07-20 01:43 UTC, kdrakehp
Details | Diff
Fixes for the sndio backend (142 bytes, patch)
2017-07-20 20:57 UTC, kdrakehp
Details | Diff
Fixes for the sndio backend (3.11 KB, patch)
2017-07-20 21:16 UTC, kdrakehp
Details | Diff
Fix the incorrect check on poll(2) (626 bytes, patch)
2017-07-20 22:46 UTC, kdrakehp
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description kdrakehp 2017-07-20 01:43:22 UTC
Created attachment 2801 [details]
Add capture support to the sndio backend

The attached patch adds capture support to the sndio backend.

The patch also allows the `OpenDevice' function to accept arbitrary device names.
Comment 1 Sam Lantinga 2017-07-20 17:39:59 UTC
Added, thanks!
https://hg.libsdl.org/SDL/rev/9bdb766ec7e5
Comment 2 Ryan C. Gordon 2017-07-20 18:10:27 UTC
Some minor nitpicks on this patch:

+    while (SNDIO_sio_read(this->hidden->dev, buf, sizeof(buf)) != 0) {
+        /* do nothing */;
+    }

Can this return -1 if there's an error? If so, this will loop forever if a USB audio device is unplugged or whatever, so we should loop while sio_read() > 0.

+        SNDIO_sio_open(devname != NULL ? SIO_DEVANY : devname,

That probably was meant to be "devname == NULL", right?

Also, CaptureFromDevice() needs to block enough to return a value > 0, but it doesn't have to return a full buffer; the calling code knows to loop again to get more data, but it considers a zero return value as a fatal error. I don't know if that simplifies the code much to only block until _something_ is available instead of _enough_ is available, but that option is available to you if it makes things cleaner.

--ryan.
Comment 3 kdrakehp 2017-07-20 20:53:54 UTC
> Can this return -1 if there's an error? If so, this will loop forever if a USB audio
> device is unplugged or whatever, so we should loop while sio_read() > 0.

`sio_read' returns an unsigned value with zero indicating an error.

> That probably was meant to be "devname == NULL", right?

Right, sorry.
Comment 4 kdrakehp 2017-07-20 20:57:01 UTC
Created attachment 2803 [details]
Fixes for the sndio backend
Comment 5 Ryan C. Gordon 2017-07-20 21:02:58 UTC
(In reply to kdrakehp from comment #4)
> Created attachment 2803 [details]
> Fixes for the sndio backend

(this wasn't the patch, can't you attach again? Sorry.)

--ryan.
Comment 6 Ryan C. Gordon 2017-07-20 21:03:42 UTC
> `sio_read' returns an unsigned value with zero indicating an error.

Oh, ok, cool.  :)

--ryan.
Comment 7 kdrakehp 2017-07-20 21:16:53 UTC
Created attachment 2804 [details]
Fixes for the sndio backend
Comment 8 kdrakehp 2017-07-20 21:45:26 UTC
(In reply to Ryan C. Gordon from comment #5)
> (In reply to kdrakehp from comment #4)
> > Created attachment 2803 [details]
> > Fixes for the sndio backend
> 
> (this wasn't the patch, can't you attach again? Sorry.)
> 
> --ryan.

That is odd.  I have added the patch again.
Comment 9 Ryan C. Gordon 2017-07-20 22:22:54 UTC
> That is odd.  I have added the patch again.

Thanks!

This patch is now https://hg.libsdl.org/SDL/rev/dfa9358ae3e0 ...

One last question (just to make sure)...in SNDIO_CaptureFromDevice, this doesn't block at all; this happens in a background thread in SDL, but I assume this is burning the CPU core at full speed waiting for more data to arrive; should we put a sleep in there? (and/or can the device's file descriptor just be set to block, so reads don't return until there is data or an error?).

--ryan.
Comment 10 kdrakehp 2017-07-20 22:45:22 UTC
> One last question (just to make sure)...in SNDIO_CaptureFromDevice, this
> doesn't block at all; this happens in a background thread in SDL, but I
> assume this is burning the CPU core at full speed waiting for more data to
> arrive; should we put a sleep in there? (and/or can the device's file
> descriptor just be set to block, so reads don't return until there is data
> or an error?).
> 
> --ryan.

No, poll(2) waits for an event on the file-descriptor list set by
`sio_pollfd'.  The way I used it in the `CaptureFromDevice' function
waits for the `POLLIN' event to signal that there is data available
to read.  It should only ever execute the loop body once, unless an
interrupt is received.

The `FlushCapture' function is what requires the device to be
non-blocking, because sndio itself does not provide a way to flush
the buffer.

Now that I think about it, I forgot something else.  The comparison
for poll should be ``< 0'' not ``<= 0'', an interrupt would cause
the `CaptureFromDevice' function to incorrectly return zero.

Sorry about that.
Comment 11 kdrakehp 2017-07-20 22:46:40 UTC
Created attachment 2806 [details]
Fix the incorrect check on poll(2)
Comment 12 Ryan C. Gordon 2017-07-21 00:43:19 UTC
> No, poll(2) waits for an event on the file-descriptor list set by

Oh, sorry, you're right. I saw "poll" and ignored the INFTIM argument.

Your poll() fix is now https://hg.libsdl.org/SDL/rev/41d93b7fd207, thanks!

I think this resolves everything, so I'm marking this bug resolved again. Thanks again for working through this with me.  :)

--ryan.