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

📄 mixer_oss.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
#define SNDRV_MIXER_OSS_ITEM_PSWITCH	4#define SNDRV_MIXER_OSS_ITEM_PROUTE	5#define SNDRV_MIXER_OSS_ITEM_PVOLUME	6#define SNDRV_MIXER_OSS_ITEM_CSWITCH	7#define SNDRV_MIXER_OSS_ITEM_CROUTE	8#define SNDRV_MIXER_OSS_ITEM_CVOLUME	9#define SNDRV_MIXER_OSS_ITEM_CAPTURE	10#define SNDRV_MIXER_OSS_ITEM_COUNT	11#define SNDRV_MIXER_OSS_PRESENT_GLOBAL	(1<<0)#define SNDRV_MIXER_OSS_PRESENT_GSWITCH	(1<<1)#define SNDRV_MIXER_OSS_PRESENT_GROUTE	(1<<2)#define SNDRV_MIXER_OSS_PRESENT_GVOLUME	(1<<3)#define SNDRV_MIXER_OSS_PRESENT_PSWITCH	(1<<4)#define SNDRV_MIXER_OSS_PRESENT_PROUTE	(1<<5)#define SNDRV_MIXER_OSS_PRESENT_PVOLUME	(1<<6)#define SNDRV_MIXER_OSS_PRESENT_CSWITCH	(1<<7)#define SNDRV_MIXER_OSS_PRESENT_CROUTE	(1<<8)#define SNDRV_MIXER_OSS_PRESENT_CVOLUME	(1<<9)#define SNDRV_MIXER_OSS_PRESENT_CAPTURE	(1<<10)struct slot {	unsigned int signature;	unsigned int present;	unsigned int channels;	unsigned int numid[SNDRV_MIXER_OSS_ITEM_COUNT];	unsigned int capture_item;	struct snd_mixer_oss_assign_table *assigned;	unsigned int allocated: 1;};#define ID_UNKNOWN	((unsigned int)-1)static snd_kcontrol_t *snd_mixer_oss_test_id(snd_mixer_oss_t *mixer, const char *name, int index){	snd_card_t * card = mixer->card;	snd_ctl_elem_id_t id;		memset(&id, 0, sizeof(id));	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;	strcpy(id.name, name);	id.index = index;	return snd_ctl_find_id(card, &id);}static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer,					  snd_mixer_oss_slot_t *pslot,					  unsigned int numid,					  int *left, int *right){	snd_ctl_elem_info_t *uinfo;	snd_ctl_elem_value_t *uctl;	snd_kcontrol_t *kctl;	snd_card_t *card = fmixer->card;	if (numid == ID_UNKNOWN)		return;	down_read(&card->controls_rwsem);	if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {		up_read(&card->controls_rwsem);		return;	}	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);	if (uinfo == NULL || uctl == NULL)		goto __unalloc;	if (kctl->info(kctl, uinfo))		goto __unalloc;	if (kctl->get(kctl, uctl))		goto __unalloc;	if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&	    uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)		goto __unalloc;	*left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);	if (uinfo->count > 1)		*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);      __unalloc:	up_read(&card->controls_rwsem);      	kfree(uctl);      	kfree(uinfo);}static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,					 snd_mixer_oss_slot_t *pslot,					 unsigned int numid,					 int *left, int *right,					 int route){	snd_ctl_elem_info_t *uinfo;	snd_ctl_elem_value_t *uctl;	snd_kcontrol_t *kctl;	snd_card_t *card = fmixer->card;	if (numid == ID_UNKNOWN)		return;	down_read(&card->controls_rwsem);	if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {		up_read(&card->controls_rwsem);		return;	}	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);	if (uinfo == NULL || uctl == NULL)		goto __unalloc;	if (kctl->info(kctl, uinfo))		goto __unalloc;	if (kctl->get(kctl, uctl))		goto __unalloc;	if (!uctl->value.integer.value[0]) {		*left = 0;		if (uinfo->count == 1)			*right = 0;	}	if (uinfo->count > 1 && !uctl->value.integer.value[route ? 3 : 1])		*right = 0;      __unalloc:	up_read(&card->controls_rwsem);      	kfree(uctl);	kfree(uinfo);}static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer,				     snd_mixer_oss_slot_t *pslot,				     int *left, int *right){	struct slot *slot = (struct slot *)pslot->private_data;		*left = *right = 100;	if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {		snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {		snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {		snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GLOBAL], left, right);	}	if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH) {		snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH) {		snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE) {		snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {		snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);	}	return 0;}static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer,					  snd_mixer_oss_slot_t *pslot,					  unsigned int numid,					  int left, int right){	snd_ctl_elem_info_t *uinfo;	snd_ctl_elem_value_t *uctl;	snd_kcontrol_t *kctl;	snd_card_t *card = fmixer->card;	int res;	if (numid == ID_UNKNOWN)		return;	down_read(&card->controls_rwsem);	if ((kctl = snd_ctl_find_numid(card, numid)) == NULL)		return;	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);	if (uinfo == NULL || uctl == NULL)		goto __unalloc;	if (kctl->info(kctl, uinfo))		goto __unalloc;	if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&	    uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)		goto __unalloc;	uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);	if (uinfo->count > 1)		uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);	if ((res = kctl->put(kctl, uctl)) < 0)		goto __unalloc;	if (res > 0)		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);      __unalloc:	up_read(&card->controls_rwsem);      	kfree(uctl);	kfree(uinfo);}static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,					 snd_mixer_oss_slot_t *pslot,					 unsigned int numid,					 int left, int right,					 int route){	snd_ctl_elem_info_t *uinfo;	snd_ctl_elem_value_t *uctl;	snd_kcontrol_t *kctl;	snd_card_t *card = fmixer->card;	int res;	if (numid == ID_UNKNOWN)		return;	down_read(&card->controls_rwsem);	if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {		up_read(&fmixer->card->controls_rwsem);		return;	}	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);	if (uinfo == NULL || uctl == NULL)		goto __unalloc;	if (kctl->info(kctl, uinfo))		goto __unalloc;	if (uinfo->count > 1) {		uctl->value.integer.value[0] = left > 0 ? 1 : 0;		uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;		if (route) {			uctl->value.integer.value[1] =			uctl->value.integer.value[2] = 0;		}	} else {		uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;	}	if ((res = kctl->put(kctl, uctl)) < 0)		goto __unalloc;	if (res > 0)		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);      __unalloc:	up_read(&card->controls_rwsem);      	kfree(uctl);	kfree(uinfo);}static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,				     snd_mixer_oss_slot_t *pslot,				     int left, int right){	struct slot *slot = (struct slot *)pslot->private_data;		if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {		snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);		if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)			snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {		snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {		snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GLOBAL], left, right);	}	if (left || right) {		if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH)			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);		if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH)			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);		if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE)			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);		if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE)			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);	} else {		if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH) {			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);		} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH) {			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);		} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE) {			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);		} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);		}	}	return 0;}static int snd_mixer_oss_get_recsrc1_sw(snd_mixer_oss_file_t *fmixer,					snd_mixer_oss_slot_t *pslot,					int *active){	struct slot *slot = (struct slot *)pslot->private_data;	int left, right;		left = right = 1;	snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], &left, &right, 0);	*active = (left || right) ? 1 : 0;	return 0;}static int snd_mixer_oss_get_recsrc1_route(snd_mixer_oss_file_t *fmixer,					   snd_mixer_oss_slot_t *pslot,					   int *active){	struct slot *slot = (struct slot *)pslot->private_data;	int left, right;		left = right = 1;	snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], &left, &right, 1);	*active = (left || right) ? 1 : 0;	return 0;}static int snd_mixer_oss_put_recsrc1_sw(snd_mixer_oss_file_t *fmixer,					snd_mixer_oss_slot_t *pslot,					int active){	struct slot *slot = (struct slot *)pslot->private_data;		snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0);	return 0;}static int snd_mixer_oss_put_recsrc1_route(snd_mixer_oss_file_t *fmixer,					   snd_mixer_oss_slot_t *pslot,					   int active){	struct slot *slot = (struct slot *)pslot->private_data;		snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);	return 0;}static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned 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;		uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);	if (uinfo == NULL || uctl == NULL) {		err = -ENOMEM;		goto __unlock;	}	down_read(&card->controls_rwsem);	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);	if (! kctl) {		err = -ENOENT;		goto __unlock;	}	if ((err = kctl->info(kctl, uinfo)) < 0)		goto __unlock;	if ((err = kctl->get(kctl, uctl)) < 0)		goto __unlock;	for (idx = 0; idx < 32; idx++) {		if (!(mixer->mask_recsrc & (1 << idx)))			continue;		pslot = &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;		}	}	err = 0;      __unlock:     	up_read(&card->controls_rwsem);      	kfree(uctl);      	kfree(uinfo);      	return err;}static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned 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;	unsigned int idx;	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);	if (uinfo == NULL || uctl == NULL) {		err = -ENOMEM;		goto __unlock;	}	down_read(&card->controls_rwsem);	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);	if (! kctl) {		err = -ENOENT;		goto __unlock;	}	if ((err = kctl->info(kctl, uinfo)) < 0)		goto __unlock;	for (idx = 0; idx < 32; idx++) {		if (!(mixer->mask_recsrc & (1 << idx)))			continue;		pslot = &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;	}	if (! slot)		goto __unlock;	for (idx = 0; idx < uinfo->count; idx++)		uctl->value.enumerated.item[idx] = slot->capture_item;	err = kctl->put(kctl, uctl);	if (err > 0)		snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);	err = 0;      __unlock:	up_read(&card->controls_rwsem);	kfree(uctl);	kfree(uinfo);	return err;}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;	snd_card_t *card = mixer->card;	int err;	down_read(&card->controls_rwsem);	kcontrol = snd_mixer_oss_test_id(mixer, name, index);	if (kcontrol == NULL) {		up_read(&card->controls_rwsem);		return 0;	}	info = kmalloc(sizeof(*info), GFP_KERNEL);	if (! info) {		up_read(&card->controls_rwsem);		return -ENOMEM;	}	if ((err = kcontrol->info(kcontrol, info)) < 0) {		up_read(&card->controls_rwsem);		kfree(info);		return err;	}	slot->numid[item] = kcontrol->id.numid;	up_read(&card->controls_rwsem);	if (info->count > slot->channels)		slot->channels = info->count;	slot->present |= 1 << item;	kfree(info);	return 0;}

⌨️ 快捷键说明

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