ref: 2908e46d3f2505e8d13845aecddde2d78833068f
parent: af261dcc91071cafd7d83054afb1eb4b2d0083ef
author: cbagwell <cbagwell>
date: Sun May 20 20:24:43 EDT 2001
Updates from Jimen Ching for ALSA driver.
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -39,7 +39,10 @@
snd_pcm_capture_params_t c_params;
memset(&c_info, 0, sizeof(c_info));
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CAPTURE_INFO, &c_info);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CAPTURE_INFO, &c_info) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
ft->file.count = 0;
ft->file.pos = 0;
ft->file.eof = 0;
@@ -59,7 +62,10 @@
format.format = fmt;
format.rate = ft->info.rate;
format.channels = ft->info.channels;
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CAPTURE_FORMAT, &format);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CAPTURE_FORMAT, &format) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
size = ft->file.size;
bps = format.rate * format.channels;
@@ -70,7 +76,10 @@
memset(&c_params, 0, sizeof(c_params));
c_params.fragment_size = size;
c_params.fragments_min = 1;
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CAPTURE_PARAMS, &c_params);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CAPTURE_PARAMS, &c_params) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
/* Change to non-buffered I/O */
setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * ft->file.size);
@@ -89,7 +98,10 @@
snd_pcm_playback_params_t p_params;
memset(&p_info, 0, sizeof(p_info));
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_PLAYBACK_INFO, &p_info);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_PLAYBACK_INFO, &p_info) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
ft->file.pos = 0;
ft->file.eof = 0;
ft->file.size = p_info.buffer_size;
@@ -108,7 +120,10 @@
format.format = fmt;
format.rate = ft->info.rate;
format.channels = ft->info.channels;
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_PLAYBACK_FORMAT, &format);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_PLAYBACK_FORMAT, &format) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
size = ft->file.size;
bps = format.rate * format.channels;
@@ -120,7 +135,10 @@
p_params.fragment_size = size;
p_params.fragments_max = -1;
p_params.fragments_room = 1;
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_PLAYBACK_PARAMS, &p_params);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_PLAYBACK_PARAMS, &p_params) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
/* Change to non-buffered I/O */
setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * ft->file.size);
@@ -138,7 +156,10 @@
snd_pcm_channel_params_t c_params;
memset(&c_info, 0, sizeof(c_info));
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_INFO, &c_info);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_INFO, &c_info) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
ft->file.count = 0;
ft->file.pos = 0;
ft->file.eof = 0;
@@ -158,6 +179,9 @@
c_params.format.format = fmt;
c_params.format.rate = ft->info.rate;
c_params.format.voices = ft->info.channels;
+ c_params.format.interleave = 1;
+ c_params.channel = SND_PCM_CHANNEL_CAPTURE;
+ c_params.mode = SND_PCM_MODE_BLOCK;
c_params.start_mode = SND_PCM_START_DATA;
c_params.stop_mode = SND_PCM_STOP_STOP;
bps = c_params.format.rate * c_params.format.voices;
@@ -166,12 +190,19 @@
size = 1;
while ((size << 1) < bps) size <<= 1;
if (size > ft->file.size) size = ft->file.size;
- c_params.mode = SND_PCM_MODE_BLOCK;
+ if (size < c_info.min_fragment_size) size = c_info.min_fragment_size;
+ if (size > c_info.max_fragment_size) size = c_info.max_fragment_size;
c_params.buf.block.frag_size = size;
- c_params.buf.block.frags_min = 32;
+ c_params.buf.block.frags_max = 32;
c_params.buf.block.frags_min = 1;
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PARAMS, &c_params);
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PREPARE);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PARAMS, &c_params) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PREPARE) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
/* Change to non-buffered I/O */
setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * ft->file.size);
@@ -189,7 +220,10 @@
snd_pcm_channel_params_t p_params;
memset(&p_info, 0, sizeof(p_info));
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_INFO, &p_info);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_INFO, &p_info) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
ft->file.pos = 0;
ft->file.eof = 0;
ft->file.size = p_info.buffer_size;
@@ -208,7 +242,10 @@
p_params.format.format = fmt;
p_params.format.rate = ft->info.rate;
p_params.format.voices = ft->info.channels;
- p_params.start_mode = SND_PCM_START_FULL;
+ p_params.format.interleave = 1;
+ p_params.channel = SND_PCM_CHANNEL_PLAYBACK;
+ p_params.mode = SND_PCM_MODE_BLOCK;
+ p_params.start_mode = SND_PCM_START_DATA;
p_params.stop_mode = SND_PCM_STOP_STOP;
bps = p_params.format.rate * p_params.format.voices;
if (ft->info.size == ST_SIZE_WORD) bps <<= 1;
@@ -216,12 +253,19 @@
size = 1;
while ((size << 1) < bps) size <<= 1;
if (size > ft->file.size) size = ft->file.size;
- p_params.mode = SND_PCM_MODE_BLOCK;
+ if (size < p_info.min_fragment_size) size = p_info.min_fragment_size;
+ if (size > p_info.max_fragment_size) size = p_info.max_fragment_size;
p_params.buf.block.frag_size = size;
- p_params.buf.block.frags_max = -1; /* Little trick (playback only) */
+ p_params.buf.block.frags_max = 32;
p_params.buf.block.frags_min = 1;
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PARAMS, &p_params);
- ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PREPARE);
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PARAMS, &p_params) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
+ if (ioctl(fileno(ft->fp), SND_PCM_IOCTL_CHANNEL_PREPARE) < 0) {
+ st_fail_errno(ft,ST_EPERM,"ioctl operation failed %d",errno);
+ return(ST_EOF);
+ }
/* Change to non-buffered I/O */
setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * ft->file.size);