参照元

説明

引数

返り値

参考

実装

/**
 * \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;
}

コメント


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS