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

📄 mixer_oss.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 3 页
字号:
					   int active){	snd_card_t *card = fmixer->card;	struct slot *slot = (struct slot *)pslot->private_data;		read_lock(&card->control_rwlock);	snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);	read_unlock(&card->control_rwlock);	return 0;}static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_index){	snd_card_t *card = fmixer->card;	snd_mixer_oss_t *mixer = fmixer->mixer;	snd_kcontrol_t *kctl;	snd_mixer_oss_slot_t *pslot;	struct slot *slot;	snd_ctl_elem_info_t uinfo;	snd_ctl_elem_value_t uctl;	int err, idx;		read_lock(&card->control_rwlock);	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);	snd_runtime_check(kctl != NULL, return -ENOENT);	memset(&uinfo, 0, sizeof(uinfo));	memset(&uctl, 0, sizeof(uctl));	snd_runtime_check(!(err = kctl->info(kctl, &uinfo)), read_unlock(&card->control_rwlock); return err);	snd_runtime_check(!(err = kctl->get(kctl, &uctl)), read_unlock(&card->control_rwlock); return err);	read_unlock(&card->control_rwlock);	for (idx = 0; idx < 32; idx++) {		if (!(mixer->mask_recsrc & (1 << idx)))			continue;		pslot = &fmixer->mixer->slots[idx];		slot = (struct slot *)pslot->private_data;		if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)			continue;		if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))			continue;		if (slot->capture_item == uctl.value.enumerated.item[0]) {			*active_index = idx;			break;		}	}	return 0;}static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_index){	snd_card_t *card = fmixer->card;	snd_mixer_oss_t *mixer = fmixer->mixer;	snd_kcontrol_t *kctl;	snd_mixer_oss_slot_t *pslot;	struct slot *slot = NULL;	snd_ctl_elem_info_t uinfo;	snd_ctl_elem_value_t uctl;	int err, idx;	read_lock(&card->control_rwlock);	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);	snd_runtime_check(kctl != NULL, read_unlock(&card->control_rwlock); return -ENOENT);	memset(&uinfo, 0, sizeof(uinfo));	memset(&uctl, 0, sizeof(uctl));	snd_runtime_check(!(err = kctl->info(kctl, &uinfo)), read_unlock(&card->control_rwlock); return err);	for (idx = 0; idx < 32; idx++) {		if (!(mixer->mask_recsrc & (1 << idx)))			continue;		pslot = &fmixer->mixer->slots[idx];		slot = (struct slot *)pslot->private_data;		if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)			continue;		if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))			continue;		if (idx == active_index)			break;		slot = NULL;	}	snd_runtime_check(slot != NULL, goto __unlock);	for (idx = 0; idx < uinfo.count; idx++)		uctl.value.enumerated.item[idx] = slot->capture_item;	snd_runtime_check((err = kctl->put(kctl, &uctl)) >= 0, );	if (err > 0)		snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);      __unlock:	read_unlock(&card->control_rwlock);	return 0;}struct snd_mixer_oss_assign_table {	int oss_id;	const char *name;	int index;};static int snd_mixer_oss_build_test(snd_mixer_oss_t *mixer, struct slot *slot, const char *name, int index, int item){	snd_ctl_elem_info_t info;	snd_kcontrol_t *kcontrol;	int err;	kcontrol = snd_mixer_oss_test_id(mixer, name, index);	if (kcontrol == NULL)		return 0;	snd_runtime_check((err = kcontrol->info(kcontrol, &info)) >= 0, return err);	slot->kcontrol[item] = kcontrol;	if (info.count > slot->channels)		slot->channels = info.count;	slot->present |= 1 << item;	return 0;}static void snd_mixer_oss_slot_free(snd_mixer_oss_slot_t *chn){	kfree(chn->private_data);}static void snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_oss_assign_table *ptr){	struct slot slot;	struct slot *pslot;	snd_kcontrol_t *kctl;	snd_mixer_oss_slot_t *rslot;	char str[64];			memset(&slot, 0, sizeof(slot));	if (snd_mixer_oss_build_test(mixer, &slot, ptr->name, ptr->index,				     SNDRV_MIXER_OSS_ITEM_GLOBAL))		return;	sprintf(str, "%s Switch", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_GSWITCH))		return;	sprintf(str, "%s Route", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_GROUTE))		return;	sprintf(str, "%s Volume", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_GVOLUME))		return;	sprintf(str, "%s Playback Switch", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_PSWITCH))		return;	sprintf(str, "%s Playback Route", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_PROUTE))		return;	sprintf(str, "%s Playback Volume", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_PVOLUME))		return;	sprintf(str, "%s Capture Switch", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_CSWITCH))		return;	sprintf(str, "%s Capture Route", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_CROUTE))		return;	sprintf(str, "%s Capture Volume", ptr->name);	if (snd_mixer_oss_build_test(mixer, &slot, str, ptr->index,				     SNDRV_MIXER_OSS_ITEM_CVOLUME))		return;	if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) {		snd_ctl_elem_info_t uinfo;		memset(&uinfo, 0, sizeof(uinfo));		if (kctl->info(kctl, &uinfo))			return;		strcpy(str, ptr->name);		if (!strcmp(str, "Master"))			strcpy(str, "Mix");		if (!strcmp(str, "Master Mono"))			strcpy(str, "Mix Mono");		slot.capture_item = 0;		if (!strcmp(uinfo.value.enumerated.name, str)) {			slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;		} else {			for (slot.capture_item = 1; slot.capture_item < uinfo.value.enumerated.items; slot.capture_item++) {				uinfo.value.enumerated.item = slot.capture_item;				if (kctl->info(kctl, &uinfo))					return;				if (!strcmp(uinfo.value.enumerated.name, str)) {					slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;					break;				}			}		}	}	if (slot.present != 0) {		pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);		snd_runtime_check(pslot != NULL, return);		*pslot = slot;		pslot->signature = SNDRV_MIXER_OSS_SIGNATURE;		rslot = &mixer->slots[ptr->oss_id];		rslot->stereo = slot.channels > 1 ? 1 : 0;		rslot->get_volume = snd_mixer_oss_get_volume1;		rslot->put_volume = snd_mixer_oss_put_volume1;		/* note: ES18xx have both Capture Source and XX Capture Volume !!! */		if (slot.present & SNDRV_MIXER_OSS_PRESENT_CSWITCH) {			rslot->get_recsrc = snd_mixer_oss_get_recsrc1_sw;			rslot->put_recsrc = snd_mixer_oss_put_recsrc1_sw;		} else if (slot.present & SNDRV_MIXER_OSS_PRESENT_CROUTE) {			rslot->get_recsrc = snd_mixer_oss_get_recsrc1_route;			rslot->put_recsrc = snd_mixer_oss_put_recsrc1_route;		} else if (slot.present & SNDRV_MIXER_OSS_PRESENT_CAPTURE) {			mixer->mask_recsrc |= 1 << ptr->oss_id;		}		rslot->private_data = pslot;		rslot->private_free = snd_mixer_oss_slot_free;	}}static void snd_mixer_oss_build(snd_mixer_oss_t *mixer){	static struct snd_mixer_oss_assign_table table[] = {		{ SOUND_MIXER_VOLUME, 	"Master",		0 },		{ SOUND_MIXER_BASS,	"Tone Control - Bass",	0 },		{ SOUND_MIXER_TREBLE,	"Tone Control - Treble", 0 },		{ SOUND_MIXER_SYNTH,	"Synth",		0 },		{ SOUND_MIXER_PCM,	"PCM",			0 },		{ SOUND_MIXER_SPEAKER,	"PC Speaker", 		0 },		{ SOUND_MIXER_LINE,	"Line", 		0 },		{ SOUND_MIXER_MIC,	"Mic", 			0 },		{ SOUND_MIXER_CD,	"CD", 			0 },		{ SOUND_MIXER_IMIX,	"Monitor Mix", 		0 },		{ SOUND_MIXER_ALTPCM,	"PCM",			1 },		{ SOUND_MIXER_RECLEV,	"-- nothing --",	0 },		{ SOUND_MIXER_IGAIN,	"Capture",		0 },		{ SOUND_MIXER_OGAIN,	"Playback",		0 },		{ SOUND_MIXER_LINE1,	"Aux",			0 },		{ SOUND_MIXER_LINE2,	"Aux",			1 },		{ SOUND_MIXER_LINE3,	"Aux",			2 },		{ SOUND_MIXER_DIGITAL1,	"Digital",		0 },		{ SOUND_MIXER_DIGITAL2,	"Digital",		1 },		{ SOUND_MIXER_DIGITAL3,	"Digital",		2 },		{ SOUND_MIXER_PHONEIN,	"Phone",		0 },		{ SOUND_MIXER_PHONEOUT,	"Phone",		1 },		{ SOUND_MIXER_VIDEO,	"Video",		0 },		{ SOUND_MIXER_RADIO,	"Radio",		0 },		{ SOUND_MIXER_MONITOR,	"Monitor",		0 }	};	static struct snd_mixer_oss_assign_table fm_table = {		SOUND_MIXER_SYNTH,	"FM",			0	};	int idx;		for (idx = 0; idx < sizeof(table) / sizeof(struct snd_mixer_oss_assign_table); idx++)		snd_mixer_oss_build_input(mixer, &table[idx]);	if (mixer->slots[SOUND_MIXER_SYNTH].get_volume == NULL)		snd_mixer_oss_build_input(mixer, &fm_table);	if (mixer->mask_recsrc) {		mixer->get_recsrc = snd_mixer_oss_get_recsrc2;		mixer->put_recsrc = snd_mixer_oss_put_recsrc2;	}}/* * */static int snd_mixer_oss_free1(void *private){	snd_mixer_oss_t *mixer = snd_magic_cast(snd_mixer_oss_t, private, return -ENXIO);	snd_card_t * card;	int idx; 	snd_assert(mixer != NULL, return -ENXIO);	card = mixer->card;	snd_assert(mixer == card->mixer_oss, return -ENXIO);	card->mixer_oss = NULL;	for (idx = 0; idx < 31; idx++) {		snd_mixer_oss_slot_t *chn = &mixer->slots[idx];		if (chn->private_free)			chn->private_free(chn);	}	snd_magic_kfree(mixer);	return 0;}static int snd_mixer_oss_notify_handler(snd_card_t * card, int free_flag){	if (!free_flag) {		snd_mixer_oss_t *mixer;		char name[128];		int idx, err;		mixer = snd_magic_kcalloc(snd_mixer_oss_t, sizeof(snd_mixer_oss_t), GFP_KERNEL);		if (mixer == NULL)			return -ENOMEM;		sprintf(name, "mixer%i%i", card->number, 0);		if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,						   card, 0,						   &snd_mixer_oss_reg,						   name)) < 0) {			snd_printk("unable to register OSS mixer device %i:%i\n", card->number, 0);			snd_magic_kfree(mixer);			return err;		}		mixer->card = card;		strcpy(mixer->name, name);		snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIXERS,				      card->number,				      name);		for (idx = 0; idx < 31; idx++)			mixer->slots[idx].number = idx;		card->mixer_oss = mixer;		snd_mixer_oss_build(mixer);	} else {		snd_mixer_oss_t *mixer = card->mixer_oss;		if (mixer == NULL)			return 0;		snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIXERS, mixer->card->number);		snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, mixer->card, 0);		return snd_mixer_oss_free1(mixer);	}	return 0;}static int __init alsa_mixer_oss_init(void){	int idx;		snd_mixer_oss_notify_callback = snd_mixer_oss_notify_handler;	for (idx = 0; idx < SNDRV_CARDS; idx++) {		if (snd_cards[idx])			snd_mixer_oss_notify_handler(snd_cards[idx], 0);	}	return 0;}static void __exit alsa_mixer_oss_exit(void){	int idx;	snd_mixer_oss_notify_callback = NULL;	for (idx = 0; idx < SNDRV_CARDS; idx++) {		if (snd_cards[idx])			snd_mixer_oss_notify_handler(snd_cards[idx], 1);	}}module_init(alsa_mixer_oss_init)module_exit(alsa_mixer_oss_exit)EXPORT_SYMBOL(snd_mixer_oss_ioctl_card);

⌨️ 快捷键说明

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