This example combines mmap and kqueue, but for some reason sound is bad sometimes, which suggests race condition. If kqueue+mmap combination has some fundamental problem, we should at least document why this approach is a bad idea.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
This is an initial quick review, as I haven't had a chance to properly test it yet.
Both configs in main() open /dev/dsp, so there is no need two have two configs and duplicate the logic twice. You can have one config but with mode = O_RDWR | O_EXCL | O_NONBLOCK, and call mmap() with PROT_READ | PROT_WRITE on the same FD. Or am I missing something?
| share/examples/sound/mmap.c | ||
|---|---|---|
| 41 | ||
| 43 | ||
| 48–50 | ||
| 54 | ||
| 55–57 | ||
The Makefile needs to be updated to install mmap.c.
I also did some tests and there is a lot of distortion.
| share/examples/sound/mmap.c | ||
|---|---|---|
| 5–9 | ||
That's the strange thing. If I run it 20-30 times, I would get roughly half of the times distorted sound, half of the times normal sound. Also, I tried having one config and two events for read and write, but I couldn't produce any sound like that. Anyway, let me fix this example to conform to the comments and lets go from there.
I think this is probably a timing issue. I haven't looked into it yet but my guess it that we are not reading/writing exactly when we should.
| share/examples/sound/mmap.c | ||
|---|---|---|
| 70 | Since we have a mmap field in struct config, wouldn't it make sense to do that in oss_init()? | |
Let me try to compensate the drift by reading SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR and experiment with that for a bit.
Map or allocate buffer in oss_init. For some reason with this patch probability of producing proper sound is way higher. I still have to add GETIPTR/GETOPTR checks and usleep based on the position.