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

📄 mixer.c

📁 Minix比较全的源码
💻 C
字号:
#include "sb16.h"#include "mixer.h" FORWARD _PROTOTYPE( int get_set_volume, (struct volume_level *level, int flag));FORWARD _PROTOTYPE( int get_set_input, (struct inout_ctrl *input, int flag, int channel));FORWARD _PROTOTYPE( int get_set_output, (struct inout_ctrl *output, int flag));/*=========================================================================* *				mixer_ioctl				   	 *=========================================================================*/PUBLIC int mixer_ioctl(int request, void *val, int *len) {	int status;	switch(request) {		case MIXIOGETVOLUME:      status = get_set_volume(val, 0); break;		case MIXIOSETVOLUME:      status = get_set_volume(val, 1); break;		case MIXIOGETINPUTLEFT:   status = get_set_input(val, 0, 0); break;		case MIXIOGETINPUTRIGHT:  status = get_set_input(val, 0, 1); break;		case MIXIOGETOUTPUT:      status = get_set_output(val, 0); break;		case MIXIOSETINPUTLEFT:   status = get_set_input(val, 1, 0); break;		case MIXIOSETINPUTRIGHT:  status = get_set_input(val, 1, 1); break;		case MIXIOSETOUTPUT:      status = get_set_output(val, 1); break;		default:                  status = ENOTTY;	}	return status;}/*=========================================================================* *				mixer_init				    *=========================================================================*/PUBLIC int mixer_init() {	/* Try to detect the mixer by writing to MIXER_DAC_LEVEL if the	* value written can be read back the mixer is there	*/	mixer_set(MIXER_DAC_LEVEL, 0x10);       /* write something to it */	if(mixer_get(MIXER_DAC_LEVEL) != 0x10) {		dprint("sb16: Mixer not detected\n");		return EIO;	}	/* Enable Automatic Gain Control */	mixer_set(MIXER_AGC, 0x01);	dprint("Mixer detected\n");	return OK;}/*=========================================================================* *				get_set_volume				   * *=========================================================================*/PRIVATE int get_set_volume(struct volume_level *level, int flag) {	int cmd_left, cmd_right, shift, max_level;	shift = 3;	max_level = 0x1F;	switch(level->device) {		case Master:			cmd_left = MIXER_MASTER_LEFT;			cmd_right = MIXER_MASTER_RIGHT;			break;		case Dac:			cmd_left = MIXER_DAC_LEFT;			cmd_right = MIXER_DAC_RIGHT;			break;		case Fm:			cmd_left = MIXER_FM_LEFT;			cmd_right = MIXER_FM_RIGHT;			break;		case Cd:			cmd_left = MIXER_CD_LEFT;			cmd_right = MIXER_CD_RIGHT;			break;		case Line:			cmd_left = MIXER_LINE_LEFT;			cmd_right = MIXER_LINE_RIGHT;			break;		case Mic:			cmd_left = cmd_right = MIXER_MIC_LEVEL;			break;		case Speaker:			cmd_left = cmd_right = MIXER_PC_LEVEL;			shift = 6;			max_level = 0x03;			break;		case Treble:			cmd_left = MIXER_TREBLE_LEFT;			cmd_right = MIXER_TREBLE_RIGHT;			shift = 4;			max_level = 0x0F;			break;		case Bass:  			cmd_left = MIXER_BASS_LEFT;			cmd_right = MIXER_BASS_RIGHT;			shift = 4;			max_level = 0x0F;			break;		default:     			return EINVAL;	}	if(flag) { /* Set volume level */		if(level->right < 0) level->right = 0;		else if(level->right > max_level) level->right = max_level;		if(level->left < 0) level->left = 0;		else if(level->left > max_level) level->left = max_level;		mixer_set(cmd_right, (level->right << shift));		mixer_set(cmd_left, (level->left << shift));	} else { /* Get volume level */		level->left = mixer_get(cmd_left);		level->right = mixer_get(cmd_right);		level->left >>= shift;		level->right >>= shift;	}	return OK;}/*=========================================================================* *				get_set_input				   * *=========================================================================*/PRIVATE int get_set_input(struct inout_ctrl *input, int flag, int channel) {	int input_cmd, input_mask, mask, del_mask, shift;	input_cmd = (channel == 0 ? MIXER_IN_LEFT : MIXER_IN_RIGHT);	mask = mixer_get(input_cmd); 	switch (input->device) {		case Fm:			shift = 5;			del_mask = 0x1F; 			break;		case Cd: 			shift = 1;			del_mask = 0x79;			break;		case Line:			shift = 3;			del_mask = 0x67;			break;		case Mic: 			shift = 0;			del_mask = 0x7E;			break;		default:   			return EINVAL;	}	if (flag) {  /* Set input */		input_mask = ((input->left == ON ? 1 : 0) << 1) | (input->right == ON ? 1 : 0);		if (shift > 0) input_mask <<= shift;		else input_mask >>= 1;		mask &= del_mask;   		mask |= input_mask;		mixer_set(input_cmd, mask);	} else {	/* Get input */		if (shift > 0) {			input->left = ((mask >> (shift+1)) & 1 == 1 ? ON : OFF);			input->right = ((mask >> shift) & 1 == 1 ? ON : OFF);		} else {			input->left = ((mask & 1) == 1 ? ON : OFF);		}	}	return OK;}/*=========================================================================* *				get_set_output				   * *=========================================================================*/PRIVATE int get_set_output(struct inout_ctrl *output, int flag) {	int output_mask, mask, del_mask, shift;	mask = mixer_get(MIXER_OUTPUT_CTRL); 	switch (output->device) {		case Cd:			shift = 1;			del_mask = 0x79;			break;		case Line:			shift = 3;			del_mask = 0x67;			break;		case Mic:			shift = 0;			del_mask = 0x7E;			break;		default:   			return EINVAL;	}	if (flag) {  /* Set input */		output_mask = ((output->left == ON ? 1 : 0) << 1) | (output->right == ON ? 1 : 0);		if (shift > 0) output_mask <<= shift;		else output_mask >>= 1;		mask &= del_mask;   		mask |= output_mask;		mixer_set(MIXER_OUTPUT_CTRL, mask);	} else {    /* Get input */		if (shift > 0) {			output->left = ((mask >> (shift+1)) & 1 == 1 ? ON : OFF);			output->right = ((mask >> shift) & 1 == 1 ? ON : OFF);		} else {			output->left = ((mask & 1) == 1 ? ON : OFF);		}	}	return OK;}PUBLIC int mixer_set(int reg, int data) {	int i;	sb16_outb(MIXER_REG, reg);	for(i = 0; i < 100; i++);	sb16_outb(MIXER_DATA, data);	return OK;}PUBLIC int mixer_get(int reg) {	int i;	sb16_outb(MIXER_REG, reg);	for(i = 0; i < 100; i++);	return sb16_inb(MIXER_DATA) & 0xff;}  

⌨️ 快捷键说明

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