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

📄 emupcm.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:		snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,						   &emu->efx_pcm_mixer[0]);		for (i = 1; i < NUM_EFX_PLAYBACK; i++)			snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0,							   &emu->efx_pcm_mixer[i]);		snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);		snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);		for (i = 1; i < NUM_EFX_PLAYBACK; i++)			snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);		epcm->running = 1;		break;	case SNDRV_PCM_TRIGGER_STOP:	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:		epcm->running = 0;		for (i = 0; i < NUM_EFX_PLAYBACK; i++) {				snd_emu10k1_playback_stop_voice(emu, epcm->voices[i]);		}		snd_emu10k1_playback_stop_voice(emu, epcm->extra);		break;	default:		result = -EINVAL;		break;	}	spin_unlock(&emu->reg_lock);	return result;}static snd_pcm_uframes_t snd_emu10k1_capture_pointer(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	emu10k1_pcm_t *epcm = runtime->private_data;	unsigned int ptr;	if (!epcm->running)		return 0;	if (epcm->first_ptr) {		udelay(50);	// hack, it takes awhile until capture is started		epcm->first_ptr = 0;	}	ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff;	return bytes_to_frames(runtime, ptr);}/* *  Playback support device description */static snd_pcm_hardware_t snd_emu10k1_playback ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000,	.rate_min =		4000,	.rate_max =		96000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};/* *  Capture support device description */static snd_pcm_hardware_t snd_emu10k1_capture ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID),	.formats =		SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_8000_48000,	.rate_min =		8000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(64*1024),	.period_bytes_min =	384,	.period_bytes_max =	(64*1024),	.periods_min =		2,	.periods_max =		2,	.fifo_size =		0,};/* * */static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl, int idx, int activate){	snd_ctl_elem_id_t id;	if (! kctl)		return;	if (activate)		kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;	else		kctl->vd[idx].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;	snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |		       SNDRV_CTL_EVENT_MASK_INFO,		       snd_ctl_build_ioff(&id, kctl, idx));}static void snd_emu10k1_pcm_mixer_notify(emu10k1_t *emu, int idx, int activate){	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_routing, idx, activate);	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_volume, idx, activate);	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_attn, idx, activate);}static void snd_emu10k1_pcm_efx_mixer_notify(emu10k1_t *emu, int idx, int activate){	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_routing, idx, activate);	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_volume, idx, activate);	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_attn, idx, activate);}static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime){	kfree(runtime->private_data);}static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu10k1_pcm_mixer_t *mix;	int i;	for (i=0; i < NUM_EFX_PLAYBACK; i++) {		mix = &emu->efx_pcm_mixer[i];		mix->epcm = NULL;		snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0);	}	return 0;}static int snd_emu10k1_efx_playback_open(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu10k1_pcm_t *epcm;	emu10k1_pcm_mixer_t *mix;	snd_pcm_runtime_t *runtime = substream->runtime;	int i;	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);	if (epcm == NULL)		return -ENOMEM;	epcm->emu = emu;	epcm->type = PLAYBACK_EFX;	epcm->substream = substream;		emu->pcm_playback_efx_substream = substream;	runtime->private_data = epcm;	runtime->private_free = snd_emu10k1_pcm_free_substream;	runtime->hw = snd_emu10k1_efx_playback;		for (i=0; i < NUM_EFX_PLAYBACK; i++) {		mix = &emu->efx_pcm_mixer[i];		mix->send_routing[0][0] = i;		memset(&mix->send_volume, 0, sizeof(mix->send_volume));		mix->send_volume[0][0] = 255;		mix->attn[0] = 0xffff;		mix->epcm = epcm;		snd_emu10k1_pcm_efx_mixer_notify(emu, i, 1);	}	return 0;}static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu10k1_pcm_t *epcm;	emu10k1_pcm_mixer_t *mix;	snd_pcm_runtime_t *runtime = substream->runtime;	int i, err;	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);	if (epcm == NULL)		return -ENOMEM;	epcm->emu = emu;	epcm->type = PLAYBACK_EMUVOICE;	epcm->substream = substream;	runtime->private_data = epcm;	runtime->private_free = snd_emu10k1_pcm_free_substream;	runtime->hw = snd_emu10k1_playback;	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {		kfree(epcm);		return err;	}	if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) {		kfree(epcm);		return err;	}	mix = &emu->pcm_mixer[substream->number];	for (i = 0; i < 4; i++)		mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i;	memset(&mix->send_volume, 0, sizeof(mix->send_volume));	mix->send_volume[0][0] = mix->send_volume[0][1] =	mix->send_volume[1][0] = mix->send_volume[2][1] = 255;	mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;	mix->epcm = epcm;	snd_emu10k1_pcm_mixer_notify(emu, substream->number, 1);	return 0;}static int snd_emu10k1_playback_close(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number];	mix->epcm = NULL;	snd_emu10k1_pcm_mixer_notify(emu, substream->number, 0);	return 0;}static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	emu10k1_pcm_t *epcm;	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);	if (epcm == NULL)		return -ENOMEM;	epcm->emu = emu;	epcm->type = CAPTURE_AC97ADC;	epcm->substream = substream;	epcm->capture_ipr = IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL;	epcm->capture_inte = INTE_ADCBUFENABLE;	epcm->capture_ba_reg = ADCBA;	epcm->capture_bs_reg = ADCBS;	epcm->capture_idx_reg = emu->audigy ? A_ADCIDX : ADCIDX;	runtime->private_data = epcm;	runtime->private_free = snd_emu10k1_pcm_free_substream;	runtime->hw = snd_emu10k1_capture;	emu->capture_interrupt = snd_emu10k1_pcm_ac97adc_interrupt;	emu->pcm_capture_substream = substream;	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_capture_rates);	return 0;}static int snd_emu10k1_capture_close(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu->capture_interrupt = NULL;	emu->pcm_capture_substream = NULL;	return 0;}static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu10k1_pcm_t *epcm;	snd_pcm_runtime_t *runtime = substream->runtime;	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);	if (epcm == NULL)		return -ENOMEM;	epcm->emu = emu;	epcm->type = CAPTURE_AC97MIC;	epcm->substream = substream;	epcm->capture_ipr = IPR_MICBUFFULL|IPR_MICBUFHALFFULL;	epcm->capture_inte = INTE_MICBUFENABLE;	epcm->capture_ba_reg = MICBA;	epcm->capture_bs_reg = MICBS;	epcm->capture_idx_reg = emu->audigy ? A_MICIDX : MICIDX;	substream->runtime->private_data = epcm;	substream->runtime->private_free = snd_emu10k1_pcm_free_substream;	runtime->hw = snd_emu10k1_capture;	runtime->hw.rates = SNDRV_PCM_RATE_8000;	runtime->hw.rate_min = runtime->hw.rate_max = 8000;	runtime->hw.channels_min = 1;	emu->capture_mic_interrupt = snd_emu10k1_pcm_ac97mic_interrupt;	emu->pcm_capture_mic_substream = substream;	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);	return 0;}static int snd_emu10k1_capture_mic_close(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu->capture_interrupt = NULL;	emu->pcm_capture_mic_substream = NULL;	return 0;}static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu10k1_pcm_t *epcm;	snd_pcm_runtime_t *runtime = substream->runtime;	int nefx = emu->audigy ? 64 : 32;	int idx;	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);	if (epcm == NULL)		return -ENOMEM;	epcm->emu = emu;	epcm->type = CAPTURE_EFX;	epcm->substream = substream;	epcm->capture_ipr = IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL;	epcm->capture_inte = INTE_EFXBUFENABLE;	epcm->capture_ba_reg = FXBA;	epcm->capture_bs_reg = FXBS;	epcm->capture_idx_reg = FXIDX;	substream->runtime->private_data = epcm;	substream->runtime->private_free = snd_emu10k1_pcm_free_substream;	runtime->hw = snd_emu10k1_capture;	runtime->hw.rates = SNDRV_PCM_RATE_48000;	runtime->hw.rate_min = runtime->hw.rate_max = 48000;	spin_lock_irq(&emu->reg_lock);	runtime->hw.channels_min = runtime->hw.channels_max = 0;	for (idx = 0; idx < nefx; idx++) {		if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {			runtime->hw.channels_min++;			runtime->hw.channels_max++;		}	}	epcm->capture_cr_val = emu->efx_voices_mask[0];	epcm->capture_cr_val2 = emu->efx_voices_mask[1];	spin_unlock_irq(&emu->reg_lock);	emu->capture_efx_interrupt = snd_emu10k1_pcm_efx_interrupt;	emu->pcm_capture_efx_substream = substream;	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);	return 0;}static int snd_emu10k1_capture_efx_close(snd_pcm_substream_t * substream){	emu10k1_t *emu = snd_pcm_substream_chip(substream);	emu->capture_interrupt = NULL;	emu->pcm_capture_efx_substream = NULL;	return 0;}static snd_pcm_ops_t snd_emu10k1_playback_ops = {	.open =			snd_emu10k1_playback_open,	.close =		snd_emu10k1_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_emu10k1_playback_hw_params,	.hw_free =		snd_emu10k1_playback_hw_free,	.prepare =		snd_emu10k1_playback_prepare,	.trigger =		snd_emu10k1_playback_trigger,	.pointer =		snd_emu10k1_playback_pointer,	.page =			snd_pcm_sgbuf_ops_page,};static snd_pcm_ops_t snd_emu10k1_capture_ops = {	.open =			snd_emu10k1_capture_open,	.close =		snd_emu10k1_capture_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_emu10k1_capture_hw_params,	.hw_free =		snd_emu10k1_capture_hw_free,	.prepare =		snd_emu10k1_capture_prepare,	.trigger =		snd_emu10k1_capture_trigger,	.pointer =		snd_emu10k1_capture_pointer,};/* EFX playback */static snd_pcm_ops_t snd_emu10k1_efx_playback_ops = {	.open =			snd_emu10k1_efx_playback_open,	.close =		snd_emu10k1_efx_playback_close,	.ioctl =		snd_pcm_lib_ioctl,	.hw_params =		snd_emu10k1_playback_hw_params,	.hw_free =		snd_emu10k1_efx_playback_hw_free,	.prepare =		snd_emu10k1_efx_playback_prepare,	.trigger =		snd_emu10k1_efx_playback_trigger,	.pointer =		snd_emu10k1_efx_playback_pointer,	.page =			snd_pcm_sgbuf_ops_page,};static void snd_emu10k1_pcm_free(snd_pcm_t *pcm){	emu10k1_t *emu = pcm->private_data;	emu->pcm = NULL;	snd_pcm_lib_preallocate_free_for_all(pcm);}int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm){	snd_pcm_t *pcm;	snd_pcm_substream_t *substream;	int err;	if (rpcm)		*rpcm = NULL;	if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0)		return err;	pcm->private_data = emu;	pcm->private_free = snd_emu10k1_pcm_free;	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_playback_ops);	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_ops);	pcm->info_flags = 0;	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;	strcpy(pcm->name, "ADC Capture/Standard PCM Playback");	emu->pcm = pcm;	for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)		if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)			return err;	for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)		snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);	if (rpcm)		*rpcm = pcm;	return 0;}int __devinit snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm){	snd_pcm_t *pcm;	snd_pcm_substream_t *substream;	int err;

⌨️ 快捷键说明

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