参照元†
- snd_pcm_t **pcmp
- const char *name
- snd_config_t *root ATTRIBUTE_UNUSED
- snd_config_t *conf
- snd_pcm_stream_t stream
- int mode
返り値†
/**
* \brief Creates a new hw PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with hw PCM description
* \param stream PCM Stream
* \param mode PCM Mode
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
long card = -1, device = 0, subdevice = -1;
const char *str;
int err, sync_ptr_ioctl = 0;
int rate = 0, channels = 0;
snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN;
snd_config_t *n;
int nonblock = 1; /* non-block per default */
snd_pcm_chmap_query_t **chmap = NULL;
snd_pcm_hw_t *hw;
/* look for defaults.pcm.nonblock definition */
if (snd_config_search(root, "defaults.pcm.nonblock", &n) >= 0) {
err = snd_config_get_bool(n);
if (err >= 0)
nonblock = err;
}
snd_config_for_each(i, next, conf) {
const char *id;
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
if (snd_pcm_conf_generic_id(id))
continue;
if (strcmp(id, "card") == 0) {
err = snd_config_get_integer(n, &card);
if (err < 0) {
err = snd_config_get_string(n, &str);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
card = snd_card_get_index(str);
if (card < 0) {
SNDERR("Invalid value for %s", id);
return card;
}
}
continue;
}
if (strcmp(id, "device") == 0) {
err = snd_config_get_integer(n, &device);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return err;
}
continue;
}
if (strcmp(id, "subdevice") == 0) {
err = snd_config_get_integer(n, &subdevice);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return err;
}
continue;
}
if (strcmp(id, "sync_ptr_ioctl") == 0) {
err = snd_config_get_bool(n);
if (err < 0)
continue;
sync_ptr_ioctl = err;
continue;
}
if (strcmp(id, "nonblock") == 0) {
err = snd_config_get_bool(n);
if (err < 0)
continue;
nonblock = err;
continue;
}
if (strcmp(id, "rate") == 0) {
long val;
err = snd_config_get_integer(n, &val);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return err;
}
rate = val;
continue;
}
if (strcmp(id, "format") == 0) {
err = snd_config_get_string(n, &str);
if (err < 0) {
SNDERR("invalid type for %s", id);
return err;
}
format = snd_pcm_format_value(str);
continue;
}
if (strcmp(id, "channels") == 0) {
long val;
err = snd_config_get_integer(n, &val);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return err;
}
channels = val;
continue;
}
if (strcmp(id, "chmap") == 0) {
snd_pcm_free_chmaps(chmap);
chmap = _snd_pcm_parse_config_chmaps(n);
if (!chmap) {
SNDERR("Invalid channel map for %s", id);
return -EINVAL;
}
continue;
}
SNDERR("Unknown field %s", id);
snd_pcm_free_chmaps(chmap);
return -EINVAL;
}
if (card < 0) {
SNDERR("card is not defined");
snd_pcm_free_chmaps(chmap);
return -EINVAL;
}
err = snd_pcm_hw_open(pcmp, name, card, device, subdevice, stream,
mode | (nonblock ? SND_PCM_NONBLOCK : 0),
0, sync_ptr_ioctl);
if (err < 0) {
snd_pcm_free_chmaps(chmap);
return err;
}
if (nonblock && ! (mode & SND_PCM_NONBLOCK)) {
/* revert to blocking mode for read/write access */
snd_pcm_hw_nonblock(*pcmp, 0);
(*pcmp)->mode = mode;
} else
/* make sure the SND_PCM_NO_xxx flags don't get lost on the
* way */
(*pcmp)->mode |= mode & (SND_PCM_NO_AUTO_RESAMPLE|
SND_PCM_NO_AUTO_CHANNELS|
SND_PCM_NO_AUTO_FORMAT|
SND_PCM_NO_SOFTVOL);
hw = (*pcmp)->private_data;
if (format != SND_PCM_FORMAT_UNKNOWN)
hw->format = format;
if (channels > 0)
hw->channels = channels;
if (rate > 0)
hw->rate = rate;
if (chmap)
hw->chmap_override = chmap;
return 0;
}
コメント†