snd_pcm_uframes_t buffer_size, period_size;
snd_output_t *log;
unsigned buffer_time;
- int err;
+ int ret;
+ const char *msg;
PARA_INFO_LOG("opening %s\n", conf->device_arg);
- err = snd_pcm_open(&pad->handle, conf->device_arg,
+ msg = "unable to open pcm";
+ ret = snd_pcm_open(&pad->handle, conf->device_arg,
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
- if (err < 0)
- return -E_PCM_OPEN;
-
+ if (ret < 0)
+ goto fail;
snd_pcm_hw_params_alloca(&hwparams);
- snd_pcm_sw_params_alloca(&swparams);
- if (snd_pcm_hw_params_any(pad->handle, hwparams) < 0)
- return -E_BROKEN_CONF;
- if (snd_pcm_hw_params_set_access(pad->handle, hwparams,
- SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
- return -E_ACCESS_TYPE;
- if (snd_pcm_hw_params_set_format(pad->handle, hwparams,
- pad->sample_format) < 0)
- return -E_SAMPLE_FORMAT;
- if (snd_pcm_hw_params_set_channels(pad->handle, hwparams,
- pad->channels) < 0)
- return -E_CHANNEL_COUNT;
- if (snd_pcm_hw_params_set_rate_near(pad->handle, hwparams,
- &pad->sample_rate, NULL) < 0)
- return -E_SET_RATE;
- err = snd_pcm_hw_params_get_buffer_time_max(hwparams,
+ msg = "Broken alsa configuration";
+ ret = snd_pcm_hw_params_any(pad->handle, hwparams);
+ if (ret < 0)
+ goto fail;
+ msg = "access type not available";
+ ret = snd_pcm_hw_params_set_access(pad->handle, hwparams,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+ if (ret < 0)
+ goto fail;
+ msg = "sample format not available";
+ ret = snd_pcm_hw_params_set_format(pad->handle, hwparams,
+ pad->sample_format);
+ if (ret < 0)
+ goto fail;
+ msg = "channels count not available";
+ ret = snd_pcm_hw_params_set_channels(pad->handle, hwparams,
+ pad->channels);
+ if (ret < 0)
+ goto fail;
+ msg = "could not set sample rate";
+ ret = snd_pcm_hw_params_set_rate_near(pad->handle, hwparams,
+ &pad->sample_rate, NULL);
+ if (ret < 0)
+ goto fail;
+ msg = "unable to get buffer time";
+ ret = snd_pcm_hw_params_get_buffer_time_max(hwparams, &buffer_time,
+ NULL);
+ if (ret < 0 || buffer_time == 0)
+ goto fail;
+ msg = "could not set buffer time";
+ ret = snd_pcm_hw_params_set_buffer_time_near(pad->handle, hwparams,
&buffer_time, NULL);
- if (err < 0 || buffer_time == 0)
- return -E_GET_BUFFER_TIME;
- if (snd_pcm_hw_params_set_buffer_time_near(pad->handle, hwparams,
- &buffer_time, NULL) < 0)
- return -E_SET_BUFFER_TIME;
- if (snd_pcm_hw_params(pad->handle, hwparams) < 0)
- return -E_HW_PARAMS;
+ if (ret < 0)
+ goto fail;
+ msg = "unable to install hw params";
+ ret = snd_pcm_hw_params(pad->handle, hwparams);
+ if (ret < 0)
+ goto fail;
snd_pcm_hw_params_get_period_size(hwparams, &period_size, NULL);
snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
+ msg = "period size equals buffer size";
if (period_size == buffer_size)
- return -E_BAD_PERIOD;
+ goto fail;
+
/* software parameter setup */
+ snd_pcm_sw_params_alloca(&swparams);
snd_pcm_sw_params_current(pad->handle, swparams);
snd_pcm_sw_params_set_avail_min(pad->handle, swparams, period_size);
if (buffer_size < 1)
else
start_threshold = PARA_MIN(buffer_size,
(snd_pcm_uframes_t)pad->sample_rate);
- if (snd_pcm_sw_params_set_start_threshold(pad->handle, swparams,
- start_threshold) < 0)
- return -E_START_THRESHOLD;
+ msg = "could not set start threshold";
+ ret = snd_pcm_sw_params_set_start_threshold(pad->handle, swparams,
+ start_threshold);
+ if (ret < 0)
+ goto fail;
stop_threshold = buffer_size;
- if (snd_pcm_sw_params_set_stop_threshold(pad->handle, swparams,
- stop_threshold) < 0)
- return -E_STOP_THRESHOLD;
- if (snd_pcm_sw_params(pad->handle, swparams) < 0)
- PARA_WARNING_LOG("unable to install sw params\n");
- pad->bytes_per_frame = snd_pcm_format_physical_width(pad->sample_format)
- * pad->channels / 8;
- if (pad->bytes_per_frame <= 0)
- return -E_PHYSICAL_WIDTH;
- if (snd_pcm_nonblock(pad->handle, 1))
- PARA_ERROR_LOG("failed to set nonblock mode\n");
- err = snd_output_buffer_open(&log);
- if (err == 0) {
+ msg = "could not set stop threshold";
+ ret = snd_pcm_sw_params_set_stop_threshold(pad->handle, swparams,
+ stop_threshold);
+ if (ret < 0)
+ goto fail;
+ msg = "unable to install sw params";
+ ret = snd_pcm_sw_params(pad->handle, swparams);
+ if (ret < 0)
+ goto fail;
+ msg = "unable to determine bytes per frame";
+ ret = snd_pcm_format_physical_width(pad->sample_format);
+ if (ret <= 0)
+ goto fail;
+ pad->bytes_per_frame = ret * pad->channels / 8;
+ msg = "failed to set alsa handle to nonblock mode";
+ ret = snd_pcm_nonblock(pad->handle, 1);
+ if (ret < 0)
+ goto fail;
+ ret = snd_output_buffer_open(&log);
+ if (ret == 0) {
char *buf;
PARA_INFO_LOG("dumping alsa configuration\n");
snd_pcm_dump(pad->handle, log);
snd_output_close(log);
}
return 1;
+fail:
+ if (ret < 0)
+ PARA_ERROR_LOG("%s: %s\n", msg, snd_strerror(-ret));
+ else
+ PARA_ERROR_LOG("%s\n", msg);
+ return -E_ALSA;
}
static void alsa_write_pre_select(struct sched *s, struct task *t)
}
ret = snd_pcm_poll_descriptors(pad->handle, &pfd, 1);
if (ret < 0) {
- PARA_ERROR_LOG("%s\n", snd_strerror(-ret));
- t->error = -E_ALSA_POLL_FDS;
+ PARA_ERROR_LOG("could not get alsa poll fd: %s\n",
+ snd_strerror(-ret));
+ t->error = -E_ALSA;
return;
}
pad->poll_fd = pfd.fd;
snd_pcm_prepare(pad->handle);
return;
}
- PARA_WARNING_LOG("%s\n", snd_strerror(-frames));
- ret = -E_ALSA_WRITE;
+ PARA_ERROR_LOG("alsa write error: %s\n", snd_strerror(-frames));
+ ret = -E_ALSA;
err:
assert(ret < 0);
btr_remove_node(btrn);
#define ALSA_WRITE_ERRORS \
- PARA_ERROR(BROKEN_CONF, "Broken alsa configuration"), \
- PARA_ERROR(ACCESS_TYPE, "alsa access type not available"), \
- PARA_ERROR(SAMPLE_FORMAT, "sample format not available"), \
- PARA_ERROR(CHANNEL_COUNT, "channels count not available"), \
- PARA_ERROR(HW_PARAMS, "unable to install hw params"), \
- PARA_ERROR(BAD_PERIOD, "can not use period equal to buffer size"), \
- PARA_ERROR(ALSA_WRITE, "alsa write error"), \
- PARA_ERROR(PCM_OPEN, "unable to open pcm"), \
- PARA_ERROR(PHYSICAL_WIDTH, "unable to determine bytes per frame"), \
- PARA_ERROR(GET_BUFFER_TIME, "snd_pcm_hw_params_get_buffer_time_max() failed"), \
- PARA_ERROR(SET_BUFFER_TIME, "snd_pcm_hw_params_set_buffer_time_near() failed"), \
- PARA_ERROR(SET_RATE, "snd_pcm_hw_params_set_rate_near failed"), \
- PARA_ERROR(START_THRESHOLD, "snd_pcm_sw_params_set_start_threshold() failed"), \
- PARA_ERROR(STOP_THRESHOLD, "snd_pcm_sw_params_set_stop_threshold() failed"), \
- PARA_ERROR(ALSA_POLL_FDS, "could not get alsa poll fd"), \
+ PARA_ERROR(ALSA, "alsa error"), \
#define WRITE_COMMON_ERRORS \