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

📄 pcm_oss.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}static int snd_pcm_oss_get_rate(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *substream;	int err;		if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)		return err;	return substream->runtime->oss.rate;}static int snd_pcm_oss_set_channels(snd_pcm_oss_file_t *pcm_oss_file, int channels){	int idx;	if (channels < 1)		channels = 1;	if (channels > 128)		return -EINVAL;	for (idx = 1; idx >= 0; --idx) {		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];		snd_pcm_runtime_t *runtime;		if (substream == NULL)			continue;		runtime = substream->runtime;		if (runtime->oss.channels != channels) {			runtime->oss.params = 1;			runtime->oss.channels = channels;		}	}	return snd_pcm_oss_get_channels(pcm_oss_file);}static int snd_pcm_oss_get_channels(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *substream;	int err;		if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)		return err;	return substream->runtime->oss.channels;}static int snd_pcm_oss_get_block_size(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *substream;	int err;		if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)		return err;	return substream->runtime->oss.period_bytes;}static int snd_pcm_oss_get_formats(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *substream;	int err;	int direct;	snd_pcm_hw_params_t params;	unsigned int formats = 0;	unsigned int format_mask;	int fmt;	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)		return err;	if (atomic_read(&substream->runtime->mmap_count)) {		direct = 1;	} else {		snd_pcm_oss_setup_t *setup = substream->oss.setup;		direct = (setup != NULL && setup->direct);	}	if (!direct)		return AFMT_MU_LAW | AFMT_U8 |		       AFMT_S16_LE | AFMT_S16_BE |		       AFMT_S8 | AFMT_U16_LE |		       AFMT_U16_BE;	_snd_pcm_hw_params_any(&params);	err = snd_pcm_hw_refine(substream, &params);	snd_assert(err >= 0, return err);	format_mask = *hw_param_mask(&params, SNDRV_PCM_HW_PARAM_FORMAT); 	for (fmt = 0; fmt < 32; ++fmt) {		if (format_mask & (1 << fmt)) {			int f = snd_pcm_oss_format_to(fmt);			if (f >= 0)				formats |= f;		}	}	return formats;}static int snd_pcm_oss_set_format(snd_pcm_oss_file_t *pcm_oss_file, int format){	int formats, idx;		if (format != AFMT_QUERY) {		formats = snd_pcm_oss_get_formats(pcm_oss_file);		if (!(formats & format))			format = AFMT_U8;		for (idx = 1; idx >= 0; --idx) {			snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];			snd_pcm_runtime_t *runtime;			if (substream == NULL)				continue;			runtime = substream->runtime;			if (runtime->oss.format != format) {				runtime->oss.params = 1;				runtime->oss.format = format;			}		}	}	return snd_pcm_oss_get_format(pcm_oss_file);}static int snd_pcm_oss_get_format(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *substream;	int err;		if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)		return err;	return substream->runtime->oss.format;}static int snd_pcm_oss_set_subdivide1(snd_pcm_substream_t *substream, int subdivide){	snd_pcm_runtime_t *runtime;	if (substream == NULL)		return 0;	runtime = substream->runtime;	if (subdivide == 0) {		subdivide = runtime->oss.subdivision;		if (subdivide == 0)			subdivide = 1;		return subdivide;	}	if (runtime->oss.subdivision || runtime->oss.fragshift)		return -EINVAL;	if (subdivide != 1 && subdivide != 2 && subdivide != 4 &&	    subdivide != 8 && subdivide != 16)		return -EINVAL;	runtime->oss.subdivision = subdivide;	runtime->oss.params = 1;	return subdivide;}static int snd_pcm_oss_set_subdivide(snd_pcm_oss_file_t *pcm_oss_file, int subdivide){	int err = -EINVAL, idx;	for (idx = 1; idx >= 0; --idx) {		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];		if (substream == NULL)			continue;		if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0)			return err;	}	return err;}static int snd_pcm_oss_set_fragment1(snd_pcm_substream_t *substream, unsigned int val){	snd_pcm_runtime_t *runtime;	if (substream == NULL)		return 0;	runtime = substream->runtime;	if (runtime->oss.subdivision || runtime->oss.fragshift)		return -EINVAL;	runtime->oss.fragshift = val & 0xffff;	runtime->oss.maxfrags = (val >> 16) & 0xffff;	if (runtime->oss.fragshift < 4)		/* < 16 */		runtime->oss.fragshift = 4;	if (runtime->oss.maxfrags < 2)		runtime->oss.maxfrags = 2;	runtime->oss.params = 1;	return 0;}static int snd_pcm_oss_set_fragment(snd_pcm_oss_file_t *pcm_oss_file, unsigned int val){	int err = -EINVAL, idx;	for (idx = 1; idx >= 0; --idx) {		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];		if (substream == NULL)			continue;		if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)			return err;	}	return err;}static int snd_pcm_oss_nonblock(struct file * file){	file->f_flags |= O_NONBLOCK;	return 0;}static int snd_pcm_oss_get_caps1(snd_pcm_substream_t *substream, int res){	if (substream == NULL) {		res &= ~DSP_CAP_DUPLEX;		return res;	}#ifdef DSP_CAP_MULTI	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)		if (substream->pstr->substream_count > 1)			res |= DSP_CAP_MULTI;#endif	/* DSP_CAP_REALTIME is set all times: */	/* all ALSA drivers can return actual pointer in ring buffer */#if defined(DSP_CAP_REALTIME) && 0	{		snd_pcm_runtime_t *runtime = substream->runtime;		if (runtime->info & (SNDRV_PCM_INFO_BLOCK_TRANSFER|SNDRV_PCM_INFO_BATCH))			res &= ~DSP_CAP_REALTIME;	}#endif	return res;}static int snd_pcm_oss_get_caps(snd_pcm_oss_file_t *pcm_oss_file){	int result, idx;		result = DSP_CAP_TRIGGER | DSP_CAP_MMAP	| DSP_CAP_DUPLEX | DSP_CAP_REALTIME;	for (idx = 0; idx < 2; idx++) {		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];		result = snd_pcm_oss_get_caps1(substream, result);	}	result |= 0x0001;	/* revision - same as SB AWE 64 */	return result;}static void snd_pcm_oss_simulate_fill(snd_pcm_substream_t *substream){	snd_pcm_runtime_t *runtime = substream->runtime;	snd_pcm_uframes_t appl_ptr;	appl_ptr = runtime->hw_ptr_interrupt + runtime->buffer_size;	appl_ptr %= runtime->boundary;	runtime->control->appl_ptr = appl_ptr;}static int snd_pcm_oss_set_trigger(snd_pcm_oss_file_t *pcm_oss_file, int trigger){	snd_pcm_runtime_t *runtime;	snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;	int err, cmd;		psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];	csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];	if (psubstream) {		if ((err = snd_pcm_oss_make_ready(psubstream)) < 0)			return err;		if (atomic_read(&psubstream->runtime->mmap_count))			snd_pcm_oss_simulate_fill(psubstream);	}	if (csubstream) {		if ((err = snd_pcm_oss_make_ready(csubstream)) < 0)			return err;	}      	if (psubstream) {      		runtime = psubstream->runtime;		if (trigger & PCM_ENABLE_OUTPUT) {			if (runtime->oss.trigger)				goto _skip1;			runtime->oss.trigger = 1;			runtime->start_threshold = 1;			cmd = SNDRV_PCM_IOCTL_START;		} else {			if (!runtime->oss.trigger)				goto _skip1;			runtime->oss.trigger = 0;			runtime->start_threshold = runtime->boundary;			cmd = SNDRV_PCM_IOCTL_DROP;			runtime->oss.prepare = 1;		}		err = snd_pcm_kernel_playback_ioctl(psubstream, cmd, 0);		if (err < 0)			return err;	} _skip1:	if (csubstream) {      		runtime = csubstream->runtime;		if (trigger & PCM_ENABLE_INPUT) {			if (runtime->oss.trigger)				goto _skip2;			runtime->oss.trigger = 1;			runtime->start_threshold = 1;			cmd = SNDRV_PCM_IOCTL_START;		} else {			if (!runtime->oss.trigger)				goto _skip2;			runtime->oss.trigger = 0;			runtime->start_threshold = runtime->boundary;			cmd = SNDRV_PCM_IOCTL_DROP;			runtime->oss.prepare = 1;		}		err = snd_pcm_kernel_capture_ioctl(csubstream, cmd, 0);		if (err < 0)			return err;	} _skip2:	return 0;}static int snd_pcm_oss_get_trigger(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;	int result = 0;	psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];	csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];	if (psubstream && psubstream->runtime && psubstream->runtime->oss.trigger)		result |= PCM_ENABLE_OUTPUT;	if (csubstream && csubstream->runtime && csubstream->runtime->oss.trigger)		result |= PCM_ENABLE_INPUT;	return result;}static int snd_pcm_oss_get_odelay(snd_pcm_oss_file_t *pcm_oss_file){	snd_pcm_substream_t *substream;	snd_pcm_runtime_t *runtime;	snd_pcm_sframes_t delay;	int err;	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];	if (substream == NULL)		return -EINVAL;	if ((err = snd_pcm_oss_make_ready(substream)) < 0)		return err;	runtime = substream->runtime;	if (runtime->oss.params || runtime->oss.prepare)		return 0;	err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);	if (err == -EPIPE)		delay = 0;	/* hack for broken OSS applications */	else if (err < 0)		return err;	return snd_pcm_oss_bytes(substream, delay);}static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info * _info){		snd_pcm_substream_t *substream;	snd_pcm_runtime_t *runtime;	snd_pcm_status_t status;	struct count_info info;	int err;	if (_info == NULL)		return -EFAULT;	substream = pcm_oss_file->streams[stream];	if (substream == NULL)		return -EINVAL;	if ((err = snd_pcm_oss_make_ready(substream)) < 0)		return err;	runtime = substream->runtime;	if (runtime->oss.params || runtime->oss.prepare) {		memset(&info, 0, sizeof(info));		if (copy_to_user(_info, &info, sizeof(info)))			return -EFAULT;		return 0;	}	memset(&status, 0, sizeof(status));	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_STATUS, &status);	if (err < 0)		return err;	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {		info.bytes = runtime->oss.bytes - snd_pcm_oss_bytes(substream, runtime->buffer_size - status.avail);	} else {		info.bytes = runtime->oss.bytes + snd_pcm_oss_bytes(substream, status.avail);	}	info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);	if (atomic_read(&runtime->mmap_count)) {		snd_pcm_sframes_t n;		n = runtime->hw_ptr_interrupt - runtime->oss.prev_hw_ptr_interrupt;		if (n < 0)			n += runtime->boundary;		info.blocks = n / runtime->period_size;		runtime->oss.prev_hw_ptr_interrupt = runtime->hw_ptr_interrupt;		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)			snd_pcm_oss_simulate_fill(substream);	} else {		if (stream == SNDRV_PCM_STREAM_PLAYBACK)			info.blocks = (runtime->buffer_size - status.avail) / runtime->period_size;		else			info.blocks = status.avail / runtime->period_size;	}	if (copy_to_user(_info, &info, sizeof(info)))		return -EFAULT;	return 0;}static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info *_info){	snd_pcm_substream_t *substream;	snd_pcm_runtime_t *runtime;	snd_pcm_status_t status;	struct audio_buf_info info;	int err;	if (_info == NULL)		return -EFAULT;	substream = pcm_oss_file->streams[stream];	if (substream == NULL)		return -EINVAL;	runtime = substream->runtime;	if (runtime->oss.params &&	    (err = snd_pcm_oss_change_params(substream)) < 0)		return err;	info.fragsize = runtime->oss.period_bytes;	info.fragstotal = runtime->periods;	memset(&status, 0, sizeof(status));	if (runtime->oss.prepare) {		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {			info.bytes = runtime->oss.period_bytes * runtime->periods;			info.fragments = runtime->periods;		} else {			info.bytes = 0;			info.fragments = 0;		}	} else {		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_STATUS, &status);		if (err < 0)			return err;		info.bytes = snd_pcm_oss_bytes(substream, status.avail);		info.fragments = status.avail / runtime->period_size;	}#if 0	/* very experimental stuff to get Quake2 working */	runtime->oss.period = (info.periods - 1) << 16;	for (tmp = info.fragsize; tmp > 1; tmp >>= 1)		runtime->oss.period++;

⌨️ 快捷键说明

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