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

📄 ixj.c

📁 mgcp协议源代码。支持多种编码:g711
💻 C
📖 第 1 页 / 共 5 页
字号:
		ixj_PostWrite(j, 0L);		break;	default:		write_retval = pre_retval;	}	return write_retval;}static void ixj_read_frame(int board){	int cnt, dly;	IXJ *j = &ixj[board];	if (j->read_buffer) {		for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {			if (!(cnt % 16) && !IsRxReady(board)) {				dly = 0;				while (!IsRxReady(board)) {					if (dly++ > 5) {						dly = 0;						break;					}					udelay(10);				}			}			// Throw away word 0 of the 8021 compressed format to get standard G.729.			if (j->rec_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {				inb_p(j->DSPbase + 0x0E);				inb_p(j->DSPbase + 0x0F);			}			*(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);			*(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);		}#ifdef PERFMON_STATS		++j->framesread;#endif		if (j->intercom != -1) {			if (IsTxReady(j->intercom)) {				for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {					if (!(cnt % 16) && !IsTxReady(board)) {						dly = 0;						while (!IsTxReady(board)) {							if (dly++ > 5) {								dly = 0;								break;							}							udelay(10);						}					}					outb_p(*(j->read_buffer + cnt), ixj[j->intercom].DSPbase + 0x0C);					outb_p(*(j->read_buffer + cnt + 1), ixj[j->intercom].DSPbase + 0x0D);				}#ifdef PERFMON_STATS				++ixj[j->intercom].frameswritten;#endif			}		} else {			j->read_buffer_ready = 1;			wake_up_interruptible(&j->read_q);	// Wake any blocked readers			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects			if (j->async_queue)				kill_fasync(j->async_queue, SIGIO);	// Send apps notice of frame		}	}}static void ixj_write_frame(int board){	int cnt, frame_count, dly;	BYTES blankword;	IXJ *j = &ixj[board];	frame_count = 0;	if (j->write_buffer && j->write_buffers_empty < 2) {		if (j->write_buffer_wp > j->write_buffer_rp) {			frame_count =			    (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);		}		if (j->write_buffer_rp > j->write_buffer_wp) {			frame_count =			    (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) +			    (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2);		}		if (frame_count >= 1) {			if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) {				switch (j->play_mode) {				case PLAYBACK_MODE_ULAW:				case PLAYBACK_MODE_ALAW:					blankword.low = blankword.high = 0xFF;					break;				case PLAYBACK_MODE_8LINEAR:				case PLAYBACK_MODE_16LINEAR:					blankword.low = blankword.high = 0x00;					break;				case PLAYBACK_MODE_8LINEAR_WSS:					blankword.low = blankword.high = 0x80;					break;				}				for (cnt = 0; cnt < 16; cnt++) {					if (!(cnt % 16) && !IsTxReady(board)) {						dly = 0;						while (!IsTxReady(board)) {							if (dly++ > 5) {								dly = 0;								break;							}							udelay(10);						}					}					outb_p((blankword.low), j->DSPbase + 0x0C);					outb_p((blankword.high), j->DSPbase + 0x0D);				}				j->flags.play_first_frame = 0;			}			for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {				if (!(cnt % 16) && !IsTxReady(board)) {					dly = 0;					while (!IsTxReady(board)) {						if (dly++ > 5) {							dly = 0;							break;						}						udelay(10);					}				}// Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG 				// so all frames are type 1.				if (j->play_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {					outb_p(0x01, j->DSPbase + 0x0C);					outb_p(0x00, j->DSPbase + 0x0D);				}				outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);				outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);				*(j->write_buffer_rp + cnt) = 0;				*(j->write_buffer_rp + cnt + 1) = 0;			}			j->write_buffer_rp += j->play_frame_size * 2;			if (j->write_buffer_rp >= j->write_buffer_end) {				j->write_buffer_rp = j->write_buffer;			}			j->write_buffers_empty++;			wake_up_interruptible(&j->write_q);	// Wake any blocked writers			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects			if (j->async_queue)				kill_fasync(j->async_queue, SIGIO);	// Send apps notice of empty buffer#ifdef PERFMON_STATS			++j->frameswritten;#endif		}	} else {		j->drybuffer++;	}}static int idle(int board){	IXJ *j = &ixj[board];	if (ixj_WriteDSPCommand(0x0000, board))		// DSP Idle		return 0;	if (j->ssr.high || j->ssr.low)		return 0;	else		return 1;}static int set_base_frame(int board, int size){	unsigned short cmd;	int cnt;	IXJ *j = &ixj[board];	aec_stop(board);	for (cnt = 0; cnt < 10; cnt++) {		if (idle(board))			break;	}	if (j->ssr.high || j->ssr.low)		return -1;	if (j->dsp.low != 0x20) {		switch (size) {		case 30:			cmd = 0x07F0;			/* Set Base Frame Size to 240 pg9-10 8021 */			break;		case 20:			cmd = 0x07A0;			/* Set Base Frame Size to 160 pg9-10 8021 */			break;		case 10:			cmd = 0x0750;			/* Set Base Frame Size to 80 pg9-10 8021 */			break;		default:			return -1;		}	} else {		if (size == 30)			return size;		else			return -1;	}	if (ixj_WriteDSPCommand(cmd, board)) {		j->baseframe.high = j->baseframe.low = 0xFF;		return -1;	} else {		j->baseframe.high = j->ssr.high;		j->baseframe.low = j->ssr.low;	}	return size;}static int set_rec_codec(int board, int rate){	int retval = 0;	IXJ *j = &ixj[board];	j->rec_codec = rate;	switch (rate) {	case G723_63:		if (j->ver.low != 0x12 || ixj_convert_loaded) {			j->rec_frame_size = 12;			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case G723_53:		if (j->ver.low != 0x12 || ixj_convert_loaded) {			j->rec_frame_size = 10;			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case TS85:		if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {			j->rec_frame_size = 16;			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case TS48:		if (j->ver.low != 0x12 || ixj_convert_loaded) {			j->rec_frame_size = 9;			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case TS41:		if (j->ver.low != 0x12 || ixj_convert_loaded) {			j->rec_frame_size = 8;			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case G728:		if (j->dsp.low != 0x20) {			j->rec_frame_size = 48;			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case G729:		if (j->dsp.low != 0x20) {			if (!j->flags.g729_loaded) {				retval = 1;				break;			}			switch (j->baseframe.low) {			case 0xA0:				j->rec_frame_size = 10;				break;			case 0x50:				j->rec_frame_size = 5;				break;			default:				j->rec_frame_size = 15;				break;			}			j->rec_mode = 0;		} else {			retval = 1;		}		break;	case ULAW:		switch (j->baseframe.low) {		case 0xA0:			j->rec_frame_size = 80;			break;		case 0x50:			j->rec_frame_size = 40;			break;		default:			j->rec_frame_size = 120;			break;		}		j->rec_mode = 4;		break;	case ALAW:		switch (j->baseframe.low) {		case 0xA0:			j->rec_frame_size = 80;			break;		case 0x50:			j->rec_frame_size = 40;			break;		default:			j->rec_frame_size = 120;			break;		}		j->rec_mode = 4;		break;	case LINEAR16:		switch (j->baseframe.low) {		case 0xA0:			j->rec_frame_size = 160;			break;		case 0x50:			j->rec_frame_size = 80;			break;		default:			j->rec_frame_size = 240;			break;		}		j->rec_mode = 5;		break;	case LINEAR8:		switch (j->baseframe.low) {		case 0xA0:			j->rec_frame_size = 80;			break;		case 0x50:			j->rec_frame_size = 40;			break;		default:			j->rec_frame_size = 120;			break;		}		j->rec_mode = 6;		break;	case WSS:		switch (j->baseframe.low) {		case 0xA0:			j->rec_frame_size = 80;			break;		case 0x50:			j->rec_frame_size = 40;			break;		default:			j->rec_frame_size = 120;			break;		}		j->rec_mode = 7;		break;	default:		j->rec_frame_size = 0;		j->rec_mode = -1;		if (j->read_buffer) {			kfree(j->read_buffer);			j->read_buffer = NULL;			j->read_buffer_size = 0;		}		retval = 1;		break;	}	return retval;}static int ixj_record_start(int board){	unsigned short cmd = 0x0000;	IXJ *j = &ixj[board];	if (j->read_buffer) {		ixj_record_stop(board);	}	if (!j->rec_mode) {		switch (j->rec_codec) {		case G723_63:			cmd = 0x5131;			break;		case G723_53:			cmd = 0x5132;			break;		case TS85:			cmd = 0x5130;	// TrueSpeech 8.5			break;		case TS48:			cmd = 0x5133;	// TrueSpeech 4.8			break;		case TS41:			cmd = 0x5134;	// TrueSpeech 4.1			break;		case G728:			cmd = 0x5135;			break;		case G729:			cmd = 0x5136;			break;		default:			return 1;		}		if (ixj_WriteDSPCommand(cmd, board))			return -1;	}	if (!j->read_buffer) {		if (!j->read_buffer)			j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);		if (!j->read_buffer) {			printk("Read buffer allocation for ixj board %d failed!\n", board);			return -ENOMEM;		}	}	j->read_buffer_size = j->rec_frame_size * 2;	if (ixj_WriteDSPCommand(0x5102, board))		// Set Poll sync mode		return -1;	switch (j->rec_mode) {	case 0:		cmd = 0x1C03;	// Record C1		break;	case 4:		if (j->ver.low == 0x12) {			cmd = 0x1E03;	// Record C1		} else {			cmd = 0x1E01;	// Record C1		}		break;	case 5:		if (j->ver.low == 0x12) {			cmd = 0x1E83;	// Record C1		} else {			cmd = 0x1E81;	// Record C1		}		break;	case 6:		if (j->ver.low == 0x12) {			cmd = 0x1F03;	// Record C1		} else {			cmd = 0x1F01;	// Record C1		}		break;	case 7:		if (j->ver.low == 0x12) {			cmd = 0x1F83;	// Record C1		} else {			cmd = 0x1F81;	// Record C1		}		break;	}	if (ixj_WriteDSPCommand(cmd, board))		return -1;	return 0;}static void ixj_record_stop(int board){	IXJ *j = &ixj[board];	if (j->read_buffer) {		kfree(j->read_buffer);		j->read_buffer = NULL;		j->read_buffer_size = 0;	}	if (j->rec_mode > -1) {		ixj_WriteDSPCommand(0x5120, board);		j->rec_mode = -1;	}}static void ixj_vad(int board, int arg){	if (arg)		ixj_WriteDSPCommand(0x513F, board);	else		ixj_WriteDSPCommand(0x513E, board);}static void set_rec_depth(int board, int depth){	if (depth > 60)		depth = 60;	if (depth < 0)		depth = 0;	ixj_WriteDSPCommand(0x5180 + depth, board);}static void set_rec_volume(int board, int volume){	ixj_WriteDSPCommand(0xCF03, board);	ixj_WriteDSPCommand(volume, board);}static int get_rec_level(int board){	IXJ *j = &ixj[board];	ixj_WriteDSPCommand(0xCF88, board);	return j->ssr.high << 8 | j->ssr.low;}static void ixj_aec_start(int board, int level){	IXJ *j = &ixj[board];	j->aec_level = level;	if (!level) {		ixj_WriteDSPCommand(0xB002, board);	} else {		if (j->rec_codec == G729 || j->play_codec == G729) {			ixj_WriteDSPCommand(0xE022, board);	// Move AEC filter buffer			ixj_WriteDSPCommand(0x0300, board);		}		ixj_WriteDSPCommand(0xB001, board);	// AEC On		ixj_WriteDSPCommand(0xE013, board);	// Advanced AEC C1		switch (level) {		case AEC_LOW:			ixj_WriteDSPCommand(0x0000, board);	// Advanced AEC C2 = off			ixj_WriteDSPCommand(0xE011, board);			ixj_WriteDSPCommand(0xFFFF, board);			break;		case AEC_MED:			ixj_WriteDSPCommand(0x0600, board);	// Advanced AEC C2 = on medium			ixj_WriteDSPCommand(0xE011, board);			ixj_WriteDSPCommand(0x0080, board);			break;		case AEC_HIGH:			ixj_WriteDSPCommand(0x0C00, board);	// Advanced AEC C2 = on high			ixj_WriteDSPCommand(0xE011, board);			ixj_WriteDSPCommand(0x0080, board);			break;		case AEC_AUTO:			ixj_WriteDSPCommand(0x0002, board);	// Attenuation scaling factor of 2

⌨️ 快捷键说明

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