[Asterisk-cvs] asterisk/channels chan_iax2.c, 1.340, 1.341 chan_zap.c, 1.501, 1.502

kpfleming kpfleming
Tue Sep 6 21:29:35 CDT 2005


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv24621/channels

Modified Files:
	chan_iax2.c chan_zap.c 
Log Message:
add new channel option (via ast_channel_setoption()) to let channel drivers adjust txgain/rxgain if they are able (only Zap channels at this time)
modify app_chanspy to use new gain option
reformat app_chanspy to match coding guidelines
add user-controlled volume adjustment to app_meetme (issue #4170, heavily modified to actually work on Zap channels)


Index: chan_iax2.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v
retrieving revision 1.340
retrieving revision 1.341
diff -u -d -r1.340 -r1.341
--- chan_iax2.c	2 Sep 2005 19:17:19 -0000	1.340
+++ chan_iax2.c	7 Sep 2005 01:30:00 -0000	1.341
@@ -2992,18 +2992,29 @@
 {
 	struct ast_option_header *h;
 	int res;
-	h = malloc(datalen + sizeof(struct ast_option_header));
-	if (h) {
-		h->flag = AST_OPTION_FLAG_REQUEST;
-		h->option = htons(option);
-		memcpy(h->data, data, datalen);
-		res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
-			AST_CONTROL_OPTION, 0, (unsigned char *)h, datalen + sizeof(struct ast_option_header), -1);
-		free(h);
-		return res;
-	} else 
-		ast_log(LOG_WARNING, "Out of memory\n");
-	return -1;
+
+	switch (option) {
+	case AST_OPTION_TXGAIN:
+	case AST_OPTION_RXGAIN:
+		/* these two cannot be sent, because they require a result */
+		errno = ENOSYS;
+		return -1;
+	default:
+		h = malloc(datalen + sizeof(*h));
+		if (h) {
+			h->flag = AST_OPTION_FLAG_REQUEST;
+			h->option = htons(option);
+			memcpy(h->data, data, datalen);
+			res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
+						  AST_CONTROL_OPTION, 0, (unsigned char *) h,
+						  datalen + sizeof(*h), -1);
+			free(h);
+			return res;
+		} else {
+			ast_log(LOG_WARNING, "Out of memory\n");
+			return -1;
+		}
+	}
 }
 
 static struct ast_frame *iax2_read(struct ast_channel *c) 

Index: chan_zap.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_zap.c,v
retrieving revision 1.501
retrieving revision 1.502
diff -u -d -r1.501 -r1.502
--- chan_zap.c	6 Sep 2005 17:50:55 -0000	1.501
+++ chan_zap.c	7 Sep 2005 01:30:00 -0000	1.502
@@ -1409,50 +1409,105 @@
 	p->echocanon = 0;
 }
 
-int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
+static void fill_txgain(struct zt_gains *g, float gain, int law)
 {
-	struct	zt_gains g;
-	float ltxgain;
-	float lrxgain;
-	int j,k;
-	g.chan = chan;
-	if ((rxgain != 0.0)  || (txgain != 0.0)) {
-		/* caluculate linear value of tx gain */
-		ltxgain = pow(10.0,txgain / 20.0);
-		/* caluculate linear value of rx gain */
-		lrxgain = pow(10.0,rxgain / 20.0);
-		if (law == ZT_LAW_ALAW) {
-			for (j=0;j<256;j++) {
-				k = (int)(((float)AST_ALAW(j)) * lrxgain);
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
-				g.rxgain[j] = AST_LIN2A(k);
-				k = (int)(((float)AST_ALAW(j)) * ltxgain);
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
-				g.txgain[j] = AST_LIN2A(k);
+	int j;
+	short k;
+	float linear_gain = pow(10.0, gain / 20.0);
+
+	switch (law) {
+	case ZT_LAW_ALAW:
+		for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
+			if (gain) {
+				k = (short) (((float) AST_ALAW(j)) * linear_gain);
+				g->txgain[j] = AST_LIN2A(k);
+			} else {
+				g->txgain[j] = j;
 			}
-		} else {
-			for (j=0;j<256;j++) {
-				k = (int)(((float)AST_MULAW(j)) * lrxgain);
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
-				g.rxgain[j] = AST_LIN2MU(k);
-				k = (int)(((float)AST_MULAW(j)) * ltxgain);
-				if (k > 32767) k = 32767;
-				if (k < -32767) k = -32767;
-				g.txgain[j] = AST_LIN2MU(k);
+		}
+		break;
+	case ZT_LAW_MULAW:
+		for (j = 0; j < (sizeof(g->txgain) / sizeof(g->txgain[0])); j++) {
+			if (gain) {
+				k = (short) (((float) AST_MULAW(j)) * linear_gain);
+				g->txgain[j] = AST_LIN2MU(k);
+			} else {
+				g->txgain[j] = j;
 			}
 		}
-	} else {
-		for (j=0;j<256;j++) {
-			g.rxgain[j] = j;
-			g.txgain[j] = j;
+		break;
+	}
+}
+
+static void fill_rxgain(struct zt_gains *g, float gain, int law)
+{
+	int j;
+	short k;
+	float linear_gain = pow(10.0, gain / 20.0);
+
+	switch (law) {
+	case ZT_LAW_ALAW:
+		for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
+			if (gain) {
+				k = (short) (((float) AST_ALAW(j)) * linear_gain);
+				g->rxgain[j] = AST_LIN2A(k);
+			} else {
+				g->rxgain[j] = j;
+			}
 		}
+		break;
+	case ZT_LAW_MULAW:
+		for (j = 0; j < (sizeof(g->rxgain) / sizeof(g->rxgain[0])); j++) {
+			if (gain) {
+				k = (short) (((float) AST_MULAW(j)) * linear_gain);
+				g->rxgain[j] = AST_LIN2MU(k);
+			} else {
+				g->rxgain[j] = j;
+			}
+		}
+		break;
 	}
-		
-	  /* set 'em */
-	return(ioctl(fd,ZT_SETGAINS,&g));
+}
+
+int set_actual_txgain(int fd, int chan, float gain, int law)
+{
+	struct zt_gains g;
+	int res;
+
+	memset(&g, 0, sizeof(g));
+	g.chan = chan;
+	res = ioctl(fd, ZT_GETGAINS, &g);
+	if (res) {
+		ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
+		return res;
+	}
+
+	fill_txgain(&g, gain, law);
+
+	return ioctl(fd, ZT_SETGAINS, &g);
+}
+
+int set_actual_rxgain(int fd, int chan, float gain, int law)
+{
+	struct zt_gains g;
+	int res;
+
+	memset(&g, 0, sizeof(g));
+	g.chan = chan;
+	res = ioctl(fd, ZT_GETGAINS, &g);
+	if (res) {
+		ast_log(LOG_DEBUG, "Failed to read gains: %s\n", strerror(errno));
+		return res;
+	}
+
+	fill_rxgain(&g, gain, law);
+
+	return ioctl(fd, ZT_SETGAINS, &g);
+}
+
+int set_actual_gain(int fd, int chan, float rxgain, float txgain, int law)
+{
+	return set_actual_txgain(fd, chan, txgain, law) | set_actual_rxgain(fd, chan, rxgain, law);
 }
 
 static inline int zt_set_hook(int fd, int hs)
@@ -2570,65 +2625,78 @@
 
 static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen)
 {
-char	*cp;
-int	x;
-
+	char *cp;
+	signed char *scp;
+	int x;
+	int index;
 	struct zt_pvt *p = chan->tech_pvt;
 
-	
-	if ((option != AST_OPTION_TONE_VERIFY) && (option != AST_OPTION_AUDIO_MODE) &&
-		(option != AST_OPTION_TDD) && (option != AST_OPTION_RELAXDTMF))
-	   {
-		errno = ENOSYS;
-		return -1;
-	   }
-	cp = (char *)data;
-	if ((!cp) || (datalen < 1))
-	   {
+	/* all supported options require data */
+	if (!data || (datalen < 1)) {
 		errno = EINVAL;
 		return -1;
-	   }
+	}
+
 	switch(option) {
-	    case AST_OPTION_TONE_VERIFY:
+	case AST_OPTION_TXGAIN:
+		scp = (signed char *) data;
+		index = zt_get_index(chan, p, 0);
+		if (index < 0) {
+			ast_log(LOG_WARNING, "No index in TXGAIN?\n");
+			return -1;
+		}
+		ast_log(LOG_DEBUG, "Setting actual tx gain on %s to %f\n", chan->name, p->txgain + (float) *scp);
+		return set_actual_txgain(p->subs[index].zfd, 0, p->txgain + (float) *scp, p->law);
+	case AST_OPTION_RXGAIN:
+		scp = (signed char *) data;
+		index = zt_get_index(chan, p, 0);
+		if (index < 0) {
+			ast_log(LOG_WARNING, "No index in RXGAIN?\n");
+			return -1;
+		}
+		ast_log(LOG_DEBUG, "Setting actual rx gain on %s to %f\n", chan->name, p->rxgain + (float) *scp);
+		return set_actual_rxgain(p->subs[index].zfd, 0, p->rxgain + (float) *scp, p->law);
+	case AST_OPTION_TONE_VERIFY:
 		if (!p->dsp)
 			break;
-		switch(*cp) {
-		    case 1:
-				ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
-				ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
+		cp = (char *) data;
+		switch (*cp) {
+		case 1:
+			ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF(1) on %s\n",chan->name);
+			ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | p->dtmfrelax);  /* set mute mode if desired */
 			break;
-		    case 2:
-				ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
-				ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
+		case 2:
+			ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: MUTECONF/MAX(2) on %s\n",chan->name);
+			ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX | p->dtmfrelax);  /* set mute mode if desired */
 			break;
-		    default:
-				ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
-				ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
+		default:
+			ast_log(LOG_DEBUG, "Set option TONE VERIFY, mode: OFF(0) on %s\n",chan->name);
+			ast_dsp_digitmode(p->dsp,DSP_DIGITMODE_DTMF | p->dtmfrelax);  /* set mute mode if desired */
 			break;
 		}
 		break;
-	    case AST_OPTION_TDD:  /* turn on or off TDD */
+	case AST_OPTION_TDD:
+		/* turn on or off TDD */
+		cp = (char *) data;
+		p->mate = 0;
 		if (!*cp) { /* turn it off */
 			ast_log(LOG_DEBUG, "Set option TDD MODE, value: OFF(0) on %s\n",chan->name);
 			if (p->tdd) tdd_free(p->tdd);
 			p->tdd = 0;
-			p->mate = 0;
 			break;
 		}
-		if (*cp == 2)
-			ast_log(LOG_DEBUG, "Set option TDD MODE, value: MATE(2) on %s\n",chan->name);
-		else ast_log(LOG_DEBUG, "Set option TDD MODE, value: ON(1) on %s\n",chan->name);
-		p->mate = 0;
+		ast_log(LOG_DEBUG, "Set option TDD MODE, value: %s(%d) on %s\n",
+			(*cp == 2) ? "MATE" : "ON", (int) *cp, chan->name);
 		zt_disable_ec(p);
 		/* otherwise, turn it on */
 		if (!p->didtdd) { /* if havent done it yet */
 			unsigned char mybuf[41000],*buf;
 			int size,res,fd,len;
-			int index;
 			struct pollfd fds[1];
+
 			buf = mybuf;
-			memset(buf,0x7f,sizeof(mybuf)); /* set to silence */
-			ast_tdd_gen_ecdisa(buf + 16000,16000);  /* put in tone */
+			memset(buf, 0x7f, sizeof(mybuf)); /* set to silence */
+			ast_tdd_gen_ecdisa(buf + 16000, 16000);  /* put in tone */
 			len = 40000;
 			index = zt_get_index(chan, p, 0);
 			if (index < 0) {
@@ -2649,7 +2717,7 @@
 					ast_log(LOG_DEBUG, "poll (for write) ret. 0 on channel %d\n", p->channel);
 					continue;
 				}
-				  /* if got exception */
+				/* if got exception */
 				if (fds[0].revents & POLLPRI) return -1;
 				if (!(fds[0].revents & POLLOUT)) {
 					ast_log(LOG_DEBUG, "write fd not ready on channel %d\n", p->channel);
@@ -2671,36 +2739,27 @@
 			p->tdd = 0;
 			p->mate = 1;
 			break;
-			}		
+		}		
 		if (!p->tdd) { /* if we dont have one yet */
 			p->tdd = tdd_new(); /* allocate one */
 		}		
 		break;
-	    case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
+	case AST_OPTION_RELAXDTMF:  /* Relax DTMF decoding (or not) */
 		if (!p->dsp)
 			break;
-		if (!*cp)
-		{		
-			ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: OFF(0) on %s\n",chan->name);
-			x = 0;
-		}
-		else
-		{		
-			ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: ON(1) on %s\n",chan->name);
-			x = 1;
-		}
-		ast_dsp_digitmode(p->dsp,x ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF | p->dtmfrelax);
+		cp = (char *) data;
+		ast_log(LOG_DEBUG, "Set option RELAX DTMF, value: %s(%d) on %s\n",
+			*cp ? "ON" : "OFF", (int) *cp, chan->name);
+		ast_dsp_digitmode(p->dsp, ((*cp) ? DSP_DIGITMODE_RELAXDTMF : DSP_DIGITMODE_DTMF) | p->dtmfrelax);
 		break;
-	    case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
-		if (!*cp)
-		{		
-			ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n",chan->name);
+	case AST_OPTION_AUDIO_MODE:  /* Set AUDIO mode (or not) */
+		cp = (char *) data;
+		if (!*cp) {		
+			ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: OFF(0) on %s\n", chan->name);
 			x = 0;
 			zt_disable_ec(p);
-		}
-		else
-		{		
-			ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n",chan->name);
+		} else {		
+			ast_log(LOG_DEBUG, "Set option AUDIO MODE, value: ON(1) on %s\n", chan->name);
 			x = 1;
 		}
 		if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
@@ -2708,6 +2767,7 @@
 		break;
 	}
 	errno = 0;
+
 	return 0;
 }
 




More information about the svn-commits mailing list