version 1.1, 2008/05/23 07:15:46 |
version 1.2, 2008/05/28 07:36:23 |
|
|
int fd; |
int fd; |
int fullduplex; |
int fullduplex; |
struct audio_info aui; |
struct audio_info aui; |
|
struct audio_bufinfo aubi; |
|
|
if (!ipar && !opar) |
if (!ipar && !opar) |
errx(1, "%s: must at least play or record", path); |
errx(1, "%s: must at least play or record", path); |
|
|
*/ |
*/ |
AUDIO_INITINFO(&aui); |
AUDIO_INITINFO(&aui); |
aui.mode = 0; |
aui.mode = 0; |
aui.lowat = UINT_MAX / 2; /* will set lowat = hiwat - 1 */ |
|
if (opar) { |
if (opar) { |
sun_partoinfo(&aui.play, opar); |
sun_partoinfo(&aui.play, opar); |
aui.play.pause = 1; |
aui.play.pause = 1; |
|
|
return -1; |
return -1; |
} |
} |
if (opar) { |
if (opar) { |
/* |
if (!sun_infotopar(&aui.play, opar)) { |
* We _must_ ensure that write() will accept at most |
|
* one block when it unblocks. Here is our definition |
|
* of the block size: the minimum amount of data |
|
* write() accepts immediately when it unblocks. If |
|
* write() accepts more that 1 block, then this means |
|
* that we failed to provide the first block early |
|
* enough thus underrun happened. |
|
* |
|
* If we fail to ensure that lowat = hiwat - 1, then |
|
* we will trigger the underrun detection mechanism. |
|
* Recording doesn't use the water mark non-sense. |
|
*/ |
|
if (aui.lowat != aui.hiwat - 1) { |
|
warnx("%s: failed to disable lowat: hiwat = %u, " |
|
"lowat = %u", path, aui.hiwat, aui.lowat); |
|
close(fd); |
close(fd); |
return -1; |
return -1; |
} |
} |
if (!sun_infotopar(&aui.play, opar)) { |
if (ioctl(fd, AUDIO_GETPRINFO, &aubi) < 0) { |
|
warn("%s: AUDIO_GETPRINFO", path); |
close(fd); |
close(fd); |
return -1; |
return -1; |
} |
} |
*onfr = aui.play.block_size / |
*onfr = aubi.blksize * aubi.hiwat / |
(aui.play.channels * aui.play.precision / 8); |
(aui.play.channels * aui.play.precision / 8); |
} |
} |
if (ipar) { |
if (ipar) { |
|
|
close(fd); |
close(fd); |
return -1; |
return -1; |
} |
} |
*infr = aui.record.block_size / |
if (ioctl(fd, AUDIO_GETRRINFO, &aubi) < 0) { |
|
warn("%s: AUDIO_GETRRINFO", path); |
|
close(fd); |
|
return -1; |
|
} |
|
*infr = aubi.blksize * aubi.hiwat / |
(aui.record.channels * aui.record.precision / 8); |
(aui.record.channels * aui.record.precision / 8); |
} |
} |
return fd; |
return fd; |