⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	struct snd_pcm_substream *substream = entry->private_data;	struct snd_pcm_runtime *runtime = substream->runtime;	if (!runtime) {		snd_iprintf(buffer, "closed\n");		return;	}	if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {		snd_iprintf(buffer, "no setup\n");		return;	}	snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));	snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);	snd_iprintf(buffer, "sleep_min: %u\n", runtime->sleep_min);	snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);	snd_iprintf(buffer, "xfer_align: %lu\n", runtime->xfer_align);	snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);	snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);	snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);	snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);	snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);}static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,					       struct snd_info_buffer *buffer){	struct snd_pcm_substream *substream = entry->private_data;	struct snd_pcm_runtime *runtime = substream->runtime;	struct snd_pcm_status status;	int err;	if (!runtime) {		snd_iprintf(buffer, "closed\n");		return;	}	memset(&status, 0, sizeof(status));	err = snd_pcm_status(substream, &status);	if (err < 0) {		snd_iprintf(buffer, "error %d\n", err);		return;	}	snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));	snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",		status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);	snd_iprintf(buffer, "tstamp      : %ld.%09ld\n",		status.tstamp.tv_sec, status.tstamp.tv_nsec);	snd_iprintf(buffer, "delay       : %ld\n", status.delay);	snd_iprintf(buffer, "avail       : %ld\n", status.avail);	snd_iprintf(buffer, "avail_max   : %ld\n", status.avail_max);	snd_iprintf(buffer, "-----\n");	snd_iprintf(buffer, "hw_ptr      : %ld\n", runtime->status->hw_ptr);	snd_iprintf(buffer, "appl_ptr    : %ld\n", runtime->control->appl_ptr);}#ifdef CONFIG_SND_PCM_XRUN_DEBUGstatic void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,				    struct snd_info_buffer *buffer){	struct snd_pcm_str *pstr = entry->private_data;	snd_iprintf(buffer, "%d\n", pstr->xrun_debug);}static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,				     struct snd_info_buffer *buffer){	struct snd_pcm_str *pstr = entry->private_data;	char line[64];	if (!snd_info_get_line(buffer, line, sizeof(line)))		pstr->xrun_debug = simple_strtoul(line, NULL, 10);}#endifstatic int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr){	struct snd_pcm *pcm = pstr->pcm;	struct snd_info_entry *entry;	char name[16];	sprintf(name, "pcm%i%c", pcm->device, 		pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');	if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL)		return -ENOMEM;	entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;	if (snd_info_register(entry) < 0) {		snd_info_free_entry(entry);		return -ENOMEM;	}	pstr->proc_root = entry;	if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {		snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	pstr->proc_info_entry = entry;#ifdef CONFIG_SND_PCM_XRUN_DEBUG	if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",						pstr->proc_root)) != NULL) {		entry->c.text.read = snd_pcm_xrun_debug_read;		entry->c.text.write = snd_pcm_xrun_debug_write;		entry->mode |= S_IWUSR;		entry->private_data = pstr;		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	pstr->proc_xrun_debug_entry = entry;#endif	return 0;}static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr){#ifdef CONFIG_SND_PCM_XRUN_DEBUG	snd_info_free_entry(pstr->proc_xrun_debug_entry);	pstr->proc_xrun_debug_entry = NULL;#endif	snd_info_free_entry(pstr->proc_info_entry);	pstr->proc_info_entry = NULL;	snd_info_free_entry(pstr->proc_root);	pstr->proc_root = NULL;	return 0;}static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream){	struct snd_info_entry *entry;	struct snd_card *card;	char name[16];	card = substream->pcm->card;	sprintf(name, "sub%i", substream->number);	if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL)		return -ENOMEM;	entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;	if (snd_info_register(entry) < 0) {		snd_info_free_entry(entry);		return -ENOMEM;	}	substream->proc_root = entry;	if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {		snd_info_set_text_ops(entry, substream,				      snd_pcm_substream_proc_info_read);		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	substream->proc_info_entry = entry;	if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {		snd_info_set_text_ops(entry, substream,				      snd_pcm_substream_proc_hw_params_read);		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	substream->proc_hw_params_entry = entry;	if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {		snd_info_set_text_ops(entry, substream,				      snd_pcm_substream_proc_sw_params_read);		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	substream->proc_sw_params_entry = entry;	if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {		snd_info_set_text_ops(entry, substream,				      snd_pcm_substream_proc_status_read);		if (snd_info_register(entry) < 0) {			snd_info_free_entry(entry);			entry = NULL;		}	}	substream->proc_status_entry = entry;	return 0;}static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream){	snd_info_free_entry(substream->proc_info_entry);	substream->proc_info_entry = NULL;	snd_info_free_entry(substream->proc_hw_params_entry);	substream->proc_hw_params_entry = NULL;	snd_info_free_entry(substream->proc_sw_params_entry);	substream->proc_sw_params_entry = NULL;	snd_info_free_entry(substream->proc_status_entry);	substream->proc_status_entry = NULL;	snd_info_free_entry(substream->proc_root);	substream->proc_root = NULL;	return 0;}#else /* !CONFIG_SND_VERBOSE_PROCFS */static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }#endif /* CONFIG_SND_VERBOSE_PROCFS *//** * snd_pcm_new_stream - create a new PCM stream * @pcm: the pcm instance * @stream: the stream direction, SNDRV_PCM_STREAM_XXX * @substream_count: the number of substreams * * Creates a new stream for the pcm. * The corresponding stream on the pcm must have been empty before * calling this, i.e. zero must be given to the argument of * snd_pcm_new(). * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count){	int idx, err;	struct snd_pcm_str *pstr = &pcm->streams[stream];	struct snd_pcm_substream *substream, *prev;#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)	mutex_init(&pstr->oss.setup_mutex);#endif	pstr->stream = stream;	pstr->pcm = pcm;	pstr->substream_count = substream_count;	if (substream_count > 0) {		err = snd_pcm_stream_proc_init(pstr);		if (err < 0) {			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");			return err;		}	}	prev = NULL;	for (idx = 0, prev = NULL; idx < substream_count; idx++) {		substream = kzalloc(sizeof(*substream), GFP_KERNEL);		if (substream == NULL) {			snd_printk(KERN_ERR "Cannot allocate PCM substream\n");			return -ENOMEM;		}		substream->pcm = pcm;		substream->pstr = pstr;		substream->number = idx;		substream->stream = stream;		sprintf(substream->name, "subdevice #%i", idx);		snprintf(substream->latency_id, sizeof(substream->latency_id),			 "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,			 (stream ? 'c' : 'p'), idx);		substream->buffer_bytes_max = UINT_MAX;		if (prev == NULL)			pstr->substream = substream;		else			prev->next = substream;		err = snd_pcm_substream_proc_init(substream);		if (err < 0) {			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");			if (prev == NULL)				pstr->substream = NULL;			else				prev->next = NULL;			kfree(substream);			return err;		}		substream->group = &substream->self_group;		spin_lock_init(&substream->self_group.lock);		INIT_LIST_HEAD(&substream->self_group.substreams);		list_add_tail(&substream->link_list, &substream->self_group.substreams);		spin_lock_init(&substream->timer_lock);		atomic_set(&substream->mmap_count, 0);		prev = substream;	}	return 0;}				EXPORT_SYMBOL(snd_pcm_new_stream);/** * snd_pcm_new - create a new PCM instance * @card: the card instance * @id: the id string * @device: the device index (zero based) * @playback_count: the number of substreams for playback * @capture_count: the number of substreams for capture * @rpcm: the pointer to store the new pcm instance * * Creates a new PCM instance. * * The pcm operators have to be set afterwards to the new instance * via snd_pcm_set_ops(). * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_new(struct snd_card *card, char *id, int device,		int playback_count, int capture_count,	        struct snd_pcm ** rpcm){	struct snd_pcm *pcm;	int err;	static struct snd_device_ops ops = {		.dev_free = snd_pcm_dev_free,		.dev_register =	snd_pcm_dev_register,		.dev_disconnect = snd_pcm_dev_disconnect,	};	snd_assert(rpcm != NULL, return -EINVAL);	*rpcm = NULL;	snd_assert(card != NULL, return -ENXIO);	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);	if (pcm == NULL) {		snd_printk(KERN_ERR "Cannot allocate PCM\n");		return -ENOMEM;	}	pcm->card = card;	pcm->device = device;	if (id)		strlcpy(pcm->id, id, sizeof(pcm->id));	if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {		snd_pcm_free(pcm);		return err;	}	if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) {		snd_pcm_free(pcm);		return err;	}	mutex_init(&pcm->open_mutex);	init_waitqueue_head(&pcm->open_wait);	if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {		snd_pcm_free(pcm);		return err;	}	*rpcm = pcm;	return 0;}EXPORT_SYMBOL(snd_pcm_new);static void snd_pcm_free_stream(struct snd_pcm_str * pstr){	struct snd_pcm_substream *substream, *substream_next;#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)	struct snd_pcm_oss_setup *setup, *setupn;#endif	substream = pstr->substream;	while (substream) {		substream_next = substream->next;		snd_pcm_timer_done(substream);		snd_pcm_substream_proc_done(substream);		kfree(substream);		substream = substream_next;	}	snd_pcm_stream_proc_done(pstr);#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)	for (setup = pstr->oss.setup_list; setup; setup = setupn) {		setupn = setup->next;		kfree(setup->task_name);		kfree(setup);	}#endif}static int snd_pcm_free(struct snd_pcm *pcm){	struct snd_pcm_notify *notify;	snd_assert(pcm != NULL, return -ENXIO);	list_for_each_entry(notify, &snd_pcm_notify_list, list) {		notify->n_unregister(pcm);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -