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

📄 pcm.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Digital Audio (PCM) abstract layer *  Copyright (c) by Jaroslav Kysela <perex@suse.cz> * * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * */#include <sound/driver.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/time.h>#include <sound/core.h>#include <sound/minors.h>#include <sound/pcm.h>#include <sound/control.h>#include <sound/info.h>MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>");MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");MODULE_LICENSE("GPL");snd_pcm_t *snd_pcm_devices[SNDRV_CARDS * SNDRV_PCM_DEVICES];static LIST_HEAD(snd_pcm_notify_list);static DECLARE_MUTEX(register_mutex);static int snd_pcm_free(snd_pcm_t *pcm);static int snd_pcm_dev_free(snd_device_t *device);static int snd_pcm_dev_register(snd_device_t *device);static int snd_pcm_dev_disconnect(snd_device_t *device);static int snd_pcm_dev_unregister(snd_device_t *device);static int snd_pcm_control_ioctl(snd_card_t * card,				 snd_ctl_file_t * control,				 unsigned int cmd, unsigned long arg){	unsigned int tmp;	tmp = card->number * SNDRV_PCM_DEVICES;	switch (cmd) {	case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:		{			int device;			if (get_user(device, (int __user *)arg))				return -EFAULT;			device = device < 0 ? 0 : device + 1;			while (device < SNDRV_PCM_DEVICES) {				if (snd_pcm_devices[tmp + device])					break;				device++;			}			if (device == SNDRV_PCM_DEVICES)				device = -1;			if (put_user(device, (int __user *)arg))				return -EFAULT;			return 0;		}	case SNDRV_CTL_IOCTL_PCM_INFO:		{			snd_pcm_info_t __user *info;			unsigned int device, subdevice;			snd_pcm_stream_t stream;			snd_pcm_t *pcm;			snd_pcm_str_t *pstr;			snd_pcm_substream_t *substream;			info = (snd_pcm_info_t __user *)arg;			if (get_user(device, &info->device))				return -EFAULT;			if (device >= SNDRV_PCM_DEVICES)				return -ENXIO;			pcm = snd_pcm_devices[tmp + device];			if (pcm == NULL)				return -ENXIO;			if (get_user(stream, &info->stream))				return -EFAULT;			if (stream < 0 || stream > 1)				return -EINVAL;			pstr = &pcm->streams[stream];			if (pstr->substream_count == 0)				return -ENOENT;			if (get_user(subdevice, &info->subdevice))				return -EFAULT;			if (subdevice >= pstr->substream_count)				return -ENXIO;			for (substream = pstr->substream; substream; substream = substream->next)				if (substream->number == (int)subdevice)					break;			if (substream == NULL)				return -ENXIO;			return snd_pcm_info_user(substream, info);		}	case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:		{			int val;						if (get_user(val, (int __user *)arg))				return -EFAULT;			control->prefer_pcm_subdevice = val;			return 0;		}	}	return -ENOIOCTLCMD;}#define STATE(v) [SNDRV_PCM_STATE_##v] = #v#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v#define READY(v) [SNDRV_PCM_READY_##v] = #v#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v#define START(v) [SNDRV_PCM_START_##v] = #v#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v char *snd_pcm_stream_names[] = {	STREAM(PLAYBACK),	STREAM(CAPTURE),};char *snd_pcm_state_names[] = {	STATE(OPEN),	STATE(SETUP),	STATE(PREPARED),	STATE(RUNNING),	STATE(XRUN),	STATE(DRAINING),	STATE(PAUSED),	STATE(SUSPENDED),};char *snd_pcm_access_names[] = {	ACCESS(MMAP_INTERLEAVED), 	ACCESS(MMAP_NONINTERLEAVED),	ACCESS(MMAP_COMPLEX),	ACCESS(RW_INTERLEAVED),	ACCESS(RW_NONINTERLEAVED),};char *snd_pcm_format_names[] = {	FORMAT(S8),	FORMAT(U8),	FORMAT(S16_LE),	FORMAT(S16_BE),	FORMAT(U16_LE),	FORMAT(U16_BE),	FORMAT(S24_LE),	FORMAT(S24_BE),	FORMAT(U24_LE),	FORMAT(U24_BE),	FORMAT(S32_LE),	FORMAT(S32_BE),	FORMAT(U32_LE),	FORMAT(U32_BE),	FORMAT(FLOAT_LE),	FORMAT(FLOAT_BE),	FORMAT(FLOAT64_LE),	FORMAT(FLOAT64_BE),	FORMAT(IEC958_SUBFRAME_LE),	FORMAT(IEC958_SUBFRAME_BE),	FORMAT(MU_LAW),	FORMAT(A_LAW),	FORMAT(IMA_ADPCM),	FORMAT(MPEG),	FORMAT(GSM),	FORMAT(SPECIAL),	FORMAT(S24_3LE),	FORMAT(S24_3BE),	FORMAT(U24_3LE),	FORMAT(U24_3BE),	FORMAT(S20_3LE),	FORMAT(S20_3BE),	FORMAT(U20_3LE),	FORMAT(U20_3BE),	FORMAT(S18_3LE),	FORMAT(S18_3BE),	FORMAT(U18_3LE),	FORMAT(U18_3BE),};char *snd_pcm_subformat_names[] = {	SUBFORMAT(STD), };char *snd_pcm_tstamp_mode_names[] = {	TSTAMP(NONE),	TSTAMP(MMAP),};const char *snd_pcm_stream_name(snd_pcm_stream_t stream){	snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL);	return snd_pcm_stream_names[stream];}const char *snd_pcm_access_name(snd_pcm_access_t access){	snd_assert(access <= SNDRV_PCM_ACCESS_LAST, return NULL);	return snd_pcm_access_names[access];}const char *snd_pcm_format_name(snd_pcm_format_t format){	snd_assert(format <= SNDRV_PCM_FORMAT_LAST, return NULL);	return snd_pcm_format_names[format];}const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat){	snd_assert(subformat <= SNDRV_PCM_SUBFORMAT_LAST, return NULL);	return snd_pcm_subformat_names[subformat];}const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode){	snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL);	return snd_pcm_tstamp_mode_names[mode];}const char *snd_pcm_state_name(snd_pcm_state_t state){	snd_assert(state <= SNDRV_PCM_STATE_LAST, return NULL);	return snd_pcm_state_names[state];}#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)#include <linux/soundcard.h>const char *snd_pcm_oss_format_name(int format){	switch (format) {	case AFMT_MU_LAW:		return "MU_LAW";	case AFMT_A_LAW:		return "A_LAW";	case AFMT_IMA_ADPCM:		return "IMA_ADPCM";	case AFMT_U8:		return "U8";	case AFMT_S16_LE:		return "S16_LE";	case AFMT_S16_BE:		return "S16_BE";	case AFMT_S8:		return "S8";	case AFMT_U16_LE:		return "U16_LE";	case AFMT_U16_BE:		return "U16_BE";	case AFMT_MPEG:		return "MPEG";	default:		return "unknown";	}}#endifstatic void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buffer_t *buffer){	snd_pcm_info_t info;	int err;	snd_runtime_check(substream, return);	err = snd_pcm_info(substream, &info);	if (err < 0) {		snd_iprintf(buffer, "error %d\n", err);		return;	}	snd_iprintf(buffer, "card: %d\n", info.card);	snd_iprintf(buffer, "device: %d\n", info.device);	snd_iprintf(buffer, "subdevice: %d\n", info.subdevice);	snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info.stream));	snd_iprintf(buffer, "id: %s\n", info.id);	snd_iprintf(buffer, "name: %s\n", info.name);	snd_iprintf(buffer, "subname: %s\n", info.subname);	snd_iprintf(buffer, "class: %d\n", info.dev_class);	snd_iprintf(buffer, "subclass: %d\n", info.dev_subclass);	snd_iprintf(buffer, "subdevices_count: %d\n", info.subdevices_count);	snd_iprintf(buffer, "subdevices_avail: %d\n", info.subdevices_avail);}static void snd_pcm_stream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	snd_pcm_proc_info_read(((snd_pcm_str_t *)entry->private_data)->substream, buffer);}static void snd_pcm_substream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	snd_pcm_proc_info_read((snd_pcm_substream_t *)entry->private_data, buffer);}static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;	snd_pcm_runtime_t *runtime = substream->runtime;	if (!runtime) {		snd_iprintf(buffer, "closed\n");		return;	}	snd_pcm_stream_lock_irq(substream);	if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {		snd_iprintf(buffer, "no setup\n");		snd_pcm_stream_unlock_irq(substream);		return;	}	snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));	snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));	snd_iprintf(buffer, "subformat: %s\n", snd_pcm_subformat_name(runtime->subformat));	snd_iprintf(buffer, "channels: %u\n", runtime->channels);		snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den);		snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);		snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);		snd_iprintf(buffer, "tick_time: %u\n", runtime->tick_time);#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)	if (substream->oss.oss) {		snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));		snd_iprintf(buffer, "OSS channels: %u\n", runtime->oss.channels);			snd_iprintf(buffer, "OSS rate: %u\n", runtime->oss.rate);		snd_iprintf(buffer, "OSS period bytes: %lu\n", (unsigned long)runtime->oss.period_bytes);		snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);		snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);	}#endif	snd_pcm_stream_unlock_irq(substream);}static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;	snd_pcm_runtime_t *runtime = substream->runtime;	if (!runtime) {		snd_iprintf(buffer, "closed\n");		return;	}	snd_pcm_stream_lock_irq(substream);	if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {		snd_iprintf(buffer, "no setup\n");		snd_pcm_stream_unlock_irq(substream);		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);

⌨️ 快捷键说明

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