[Asterisk-Dev] [PATCH] Speex ultra wide band

Alfred E. Heggestad alfredh at owera.com
Mon Jun 6 09:57:34 MST 2005


Hi

attached is a preliminary patch enabling UWB (Ultra wide band 32kHz)
part of the Speex codec. warning! it is not complete and the sampling
rate is currently hardcoded to 32 kHz. the patch works fine with
the app_mp3.c backend streaming mp3/http to speex/32000.

before doing more work on this I have some questions:

o Is anyone doing any similar work?

o What is the best way to negotiate sampling rate with SDP/SIP
  in asterisk? I have added a rate parameter to the arrays
  mimeTypes[] and static_RTP_PT[] in rtp.c but I am not sure
  if that is a good solution. Are there any other non-8000 Hz
  codecs I could look at ?

o Would it be better to add AST_FORMAT_SPEEX_WB = 1<<11 and
  AST_FORMAT_SPEEX_UWB = 1<<12 ? my only worry is that Speex
  can also support other sample rates.

o How to copy the "sample rate" info from chan_sip.c to codec_speex.c ?
  the info must be re-entrant.


thanks!


/alfred


Index: frame.c
===================================================================
RCS file: /usr/cvsroot/asterisk/frame.c,v
retrieving revision 1.56
diff -u -3 -r1.56 frame.c
--- frame.c	19 May 2005 01:57:19 -0000	1.56
+++ frame.c	5 Jun 2005 23:52:00 -0000
@@ -190,8 +190,8 @@
 		memmove(s->data, s->data + len, s->len);
 		if (s->delivery.tv_sec || s->delivery.tv_usec) {
 			/* If we have delivery time, increment it, otherwise, leave it at 0 */
-			s->delivery.tv_sec += (len * s->samplesperbyte) / 8000.0;
-			s->delivery.tv_usec += (((int)(len * s->samplesperbyte)) % 8000) * 125;
+			s->delivery.tv_sec += (len * s->samplesperbyte) / 32000.0;
+			s->delivery.tv_usec += (((int)(len * s->samplesperbyte)) % 32000) * (1000/32);
 			if (s->delivery.tv_usec > 1000000) {
 				s->delivery.tv_usec -= 1000000;
 				s->delivery.tv_sec += 1;
Index: rtp.c
===================================================================
RCS file: /usr/cvsroot/asterisk/rtp.c,v
retrieving revision 1.132
diff -u -3 -r1.132 rtp.c
--- rtp.c	2 Jun 2005 00:50:38 -0000	1.132
+++ rtp.c	5 Jun 2005 23:52:01 -0000
@@ -57,6 +57,7 @@
 struct rtpPayloadType {
 	int isAstFormat; 	/* whether the following code is an AST_FORMAT */
 	int code;
+	int rate;
 };
 
 #define MAX_RTP_PT 256
@@ -575,62 +576,66 @@
 
 /* The following array defines the MIME Media type (and subtype) for each
    of our codecs, or RTP-specific data type. */
-static struct {
+static const struct {
   struct rtpPayloadType payloadType;
   char* type;
   char* subtype;
 } mimeTypes[] = {
-  {{1, AST_FORMAT_G723_1}, "audio", "G723"},
-  {{1, AST_FORMAT_GSM}, "audio", "GSM"},
-  {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
-  {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
-  {{1, AST_FORMAT_G726}, "audio", "G726-32"},
-  {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
-  {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
-  {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
-  {{1, AST_FORMAT_G729A}, "audio", "G729"},
-  {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
-  {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
-  {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
-  {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
-  {{0, AST_RTP_CN}, "audio", "CN"},
-  {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
-  {{1, AST_FORMAT_PNG}, "video", "PNG"},
-  {{1, AST_FORMAT_H261}, "video", "H261"},
-  {{1, AST_FORMAT_H263}, "video", "H263"},
-  {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"},
+  {{1, AST_FORMAT_G723_1,  8000}, "audio", "G723"},
+  {{1, AST_FORMAT_GSM,     8000}, "audio", "GSM"},
+  {{1, AST_FORMAT_ULAW,    8000}, "audio", "PCMU"},
+  {{1, AST_FORMAT_ALAW,    8000}, "audio", "PCMA"},
+  {{1, AST_FORMAT_G726,    8000}, "audio", "G726-32"},
+  {{1, AST_FORMAT_ADPCM,   8000}, "audio", "DVI4"},
+  {{1, AST_FORMAT_SLINEAR, 8000}, "audio", "L16"},
+  {{1, AST_FORMAT_LPC10,   8000}, "audio", "LPC"},
+  {{1, AST_FORMAT_G729A,   8000}, "audio", "G729"},
+  {{1, AST_FORMAT_SPEEX,  32000}, "audio", "speex"},
+  {{1, AST_FORMAT_SPEEX,  16000}, "audio", "speex"},
+  {{1, AST_FORMAT_SPEEX,   8000}, "audio", "speex"},
+  {{1, AST_FORMAT_ILBC,    8000}, "audio", "iLBC"},
+  {{0, AST_RTP_DTMF,       8000}, "audio", "telephone-event"},
+  {{0, AST_RTP_CISCO_DTMF, 8000}, "audio", "cisco-telephone-event"},
+  {{0, AST_RTP_CN,         8000}, "audio", "CN"},
+  {{1, AST_FORMAT_JPEG,   90000}, "video", "JPEG"},
+  {{1, AST_FORMAT_PNG,    90000}, "video", "PNG"},
+  {{1, AST_FORMAT_H261,   90000}, "video", "H261"},
+  {{1, AST_FORMAT_H263,   90000}, "video", "H263"},
+  {{1, AST_FORMAT_H263_PLUS, 90000}, "video", "h263-1998"},
 };
 
 /* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
    also, our own choices for dynamic payload types.  This is our master
    table for transmission */
-static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
-  [0] = {1, AST_FORMAT_ULAW},
+static const struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
+  [0] = {1, AST_FORMAT_ULAW, 8000},
 #ifdef USE_DEPRECATED_G726
-  [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
+  [2] = {1, AST_FORMAT_G726, 8000}, /* Technically this is G.721, but if Cisco can do it, so can we... */
 #endif
-  [3] = {1, AST_FORMAT_GSM},
-  [4] = {1, AST_FORMAT_G723_1},
-  [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
-  [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
-  [7] = {1, AST_FORMAT_LPC10},
-  [8] = {1, AST_FORMAT_ALAW},
-  [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
-  [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
-  [13] = {0, AST_RTP_CN},
-  [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
-  [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
-  [18] = {1, AST_FORMAT_G729A},
-  [19] = {0, AST_RTP_CN},		/* Also used for CN */
-  [26] = {1, AST_FORMAT_JPEG},
-  [31] = {1, AST_FORMAT_H261},
-  [34] = {1, AST_FORMAT_H263},
-  [103] = {1, AST_FORMAT_H263_PLUS},
-  [97] = {1, AST_FORMAT_ILBC},
-  [101] = {0, AST_RTP_DTMF},
-  [110] = {1, AST_FORMAT_SPEEX},
-  [111] = {1, AST_FORMAT_G726},
-  [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
+  [3] = {1, AST_FORMAT_GSM, 8000},
+  [4] = {1, AST_FORMAT_G723_1, 8000},
+  [5] = {1, AST_FORMAT_ADPCM, 8000}, /* 8 kHz */
+  [6] = {1, AST_FORMAT_ADPCM, 16000}, /* 16 kHz */
+  [7] = {1, AST_FORMAT_LPC10, 8000},
+  [8] = {1, AST_FORMAT_ALAW, 8000},
+  [10] = {1, AST_FORMAT_SLINEAR, 8000}, /* 2 channels */
+  [11] = {1, AST_FORMAT_SLINEAR, 8000}, /* 1 channel */
+  [13] = {0, AST_RTP_CN, 8000},
+  [16] = {1, AST_FORMAT_ADPCM, 11025}, /* 11.025 kHz */
+  [17] = {1, AST_FORMAT_ADPCM, 22050}, /* 22.050 kHz */
+  [18] = {1, AST_FORMAT_G729A, 8000},
+  [19] = {0, AST_RTP_CN, 8000},		/* Also used for CN */
+  [26] = {1, AST_FORMAT_JPEG, 90000},
+  [31] = {1, AST_FORMAT_H261, 90000},
+  [34] = {1, AST_FORMAT_H263, 90000},
+  [103] = {1, AST_FORMAT_H263_PLUS, 90000},
+  [97] = {1, AST_FORMAT_ILBC, 8000},
+  [101] = {0, AST_RTP_DTMF, 8000},
+  [110] = {1, AST_FORMAT_SPEEX, 32000}, /* 32 kHz ultra wide band */
+  [111] = {1, AST_FORMAT_SPEEX, 16000}, /* 16 kHz wide band       */
+  [112] = {1, AST_FORMAT_SPEEX,  8000}, /*  8 kHz narrow band     */
+  [111] = {1, AST_FORMAT_G726, 8000},
+  [121] = {0, AST_RTP_CISCO_DTMF, 8000}, /* Must be type 121 */
 };
 
 void ast_rtp_pt_clear(struct ast_rtp* rtp) 
@@ -640,6 +645,7 @@
 	for (i = 0; i < MAX_RTP_PT; ++i) {
 		rtp->current_RTP_PT[i].isAstFormat = 0;
 		rtp->current_RTP_PT[i].code = 0;
+		rtp->current_RTP_PT[i].rate = 0;
 	}
 
 	rtp->rtp_lookup_code_cache_isAstFormat = 0;
@@ -653,8 +659,7 @@
 
 	/* Initialize to default payload types */
 	for (i = 0; i < MAX_RTP_PT; ++i) {
-		rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
-		rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
+		memcpy(&rtp->current_RTP_PT[i], &static_RTP_PT[i], sizeof(struct rtpPayloadType));
 	}
 
 	rtp->rtp_lookup_code_cache_isAstFormat = 0;
@@ -670,14 +675,14 @@
 		return; /* bogus payload type */
 
 	if (static_RTP_PT[pt].code != 0) {
-		rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
+		memcpy(&rtp->current_RTP_PT[pt], &static_RTP_PT[pt], sizeof(struct rtpPayloadType));
 	}
 } 
 
 /* Make a note of a RTP payload type (with MIME type) that was seen in */
 /* a SDP "a=rtpmap:" line. */
 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
-			 char* mimeType, char* mimeSubtype) {
+			     char* mimeType, char* mimeSubtype, unsigned int rate) {
 	int i;
 
 	if (pt < 0 || pt > MAX_RTP_PT) 
@@ -685,9 +690,10 @@
 
 	for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
 		if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
-		     strcasecmp(mimeType, mimeTypes[i].type) == 0) {
-			rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
-		return;
+		     strcasecmp(mimeType, mimeTypes[i].type) == 0 &&
+		    rate==mimeTypes[i].payloadType.rate) {
+			memcpy(&rtp->current_RTP_PT[pt], &mimeTypes[i].payloadType, sizeof(struct rtpPayloadType));
+			return;
 		}
 	}
 } 
@@ -767,12 +773,14 @@
 	return -1;
 }
 
-char* ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code) {
+char* ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code, unsigned int *rate) {
 
 	int i;
 
 	for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
 	if (mimeTypes[i].payloadType.code == code && mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
+		if(rate)
+			*rate = mimeTypes[i].payloadType.rate;
       		return mimeTypes[i].subtype;
 		}
 	}
@@ -798,7 +806,7 @@
 
 	for (format = 1; format < AST_RTP_MAX; format <<= 1) {
 		if (capability & format) {
-			const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format);
+			const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format, NULL);
 			snprintf(end, size, "%s|", name);
 			len = strlen(end);
 			end += len;
@@ -1165,7 +1173,7 @@
                 pred = rtp->lastts + ast_codec_get_samples(f);
 
 		/* Re-calculate last TS */
-		rtp->lastts = rtp->lastts + ms * 8;
+		rtp->lastts = rtp->lastts + ms * 32000/1000;
 		if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
 			/* If this isn't an absolute delivery time, Check if it is close to our prediction, 
 			   and if so, go with our prediction */
Index: translate.c
===================================================================
RCS file: /usr/cvsroot/asterisk/translate.c,v
retrieving revision 1.36
diff -u -3 -r1.36 translate.c
--- translate.c	29 Apr 2005 17:24:58 -0000	1.36
+++ translate.c	5 Jun 2005 23:52:02 -0000
@@ -175,8 +175,8 @@
 			path->nextout.tv_usec = f->delivery.tv_usec;
 		}
 		/* Predict next incoming sample */
-		path->nextin.tv_sec += (f->samples / 8000);
-		path->nextin.tv_usec += ((f->samples % 8000) * 125);
+		path->nextin.tv_sec += (f->samples / 32000);
+		path->nextin.tv_usec += ((f->samples % 32000) * 1000/32);
 		if (path->nextin.tv_usec >= 1000000) {
 			path->nextin.tv_usec -= 1000000;
 			path->nextin.tv_sec++;
@@ -203,8 +203,8 @@
 				
 				/* Predict next outgoing timestamp from samples in this
 				   frame. */
-				path->nextout.tv_sec += (out->samples / 8000);
-				path->nextout.tv_usec += ((out->samples % 8000) * 125);
+				path->nextout.tv_sec += (out->samples / 32000);
+				path->nextout.tv_usec += ((out->samples % 32000) * 1000/32);
 				if (path->nextout.tv_usec >= 1000000) {
 					path->nextout.tv_sec++;
 					path->nextout.tv_usec -= 1000000;
@@ -246,7 +246,7 @@
 	}
 	gettimeofday(&start, NULL);
 	/* Call the encoder until we've processed one second of time */
-	while(sofar < samples * 8000) {
+	while(sofar < samples * 32000) {
 		f = t->sample();
 		if (!f) {
 			ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
Index: apps/app_mp3.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_mp3.c,v
retrieving revision 1.24
diff -u -3 -r1.24 app_mp3.c
--- apps/app_mp3.c	21 Apr 2005 06:02:43 -0000	1.24
+++ apps/app_mp3.c	5 Jun 2005 23:52:02 -0000
@@ -59,22 +59,23 @@
 		if (x != STDOUT_FILENO)
 			close(x);
 	}
+	const char *rate = "32000";
 	/* Execute mpg123, but buffer if it's a net connection */
 	if (!strncasecmp(filename, "http://", 7)) {
 		/* Most commonly installed in /usr/local/bin */
-	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
+	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", rate, filename, (char *)NULL);
 		/* But many places has it in /usr/bin */
-	    execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
+	    execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", rate, filename, (char *)NULL);
 		/* As a last-ditch effort, try to use PATH */
-	    execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
+	    execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024",  "-f", "8192", "--mono", "-r", rate, filename, (char *)NULL);
 	}
 	else {
 		/* Most commonly installed in /usr/local/bin */
-	    execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
+	    execl(MPG_123, "mpg123", "-q", "-s", "--mono", "-r", rate, filename, (char *)NULL);
 		/* But many places has it in /usr/bin */
-	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
+	    execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "--mono", "-r", rate, filename, (char *)NULL);
 		/* As a last-ditch effort, try to use PATH */
-	    execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
+	    execlp("mpg123", "mpg123", "-q", "-s", "--mono", "-r", rate, filename, (char *)NULL);
 	}
 	ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
 	return -1;
@@ -109,7 +110,7 @@
 	struct myframe {
 		struct ast_frame f;
 		char offset[AST_FRIENDLY_OFFSET];
-		short frdata[160];
+		short frdata[640];
 	} myf;
 	if (!data) {
 		ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
@@ -179,7 +180,7 @@
 					res = 0;
 					break;
 				}
-				next.tv_usec += res / 2 * 125;
+				next.tv_usec += res / 2 * (1000/32);
 				if (next.tv_usec >= 1000000) {
 					next.tv_usec -= 1000000;
 					next.tv_sec++;
Index: channels/chan_h323.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_h323.c,v
retrieving revision 1.117
diff -u -3 -r1.117 chan_h323.c
--- channels/chan_h323.c	21 May 2005 17:09:30 -0000	1.117
+++ channels/chan_h323.c	5 Jun 2005 23:52:04 -0000
@@ -1504,7 +1504,7 @@
 		return;
 	}
 	if (pvt->rtp) {
-		ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event");
+		ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 8000);
 	}
 	ast_mutex_unlock(&pvt->lock);
 	if (h323debug)
Index: channels/chan_mgcp.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_mgcp.c,v
retrieving revision 1.122
diff -u -3 -r1.122 chan_mgcp.c
--- channels/chan_mgcp.c	25 May 2005 17:18:05 -0000	1.122
+++ channels/chan_mgcp.c	5 Jun 2005 23:52:06 -0000
@@ -1812,10 +1812,11 @@
 	sdpLineNum_iterator_init(&iterator);
 	while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
 		char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
-		if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2)
+		unsigned int rate;
+		if (sscanf(a, "rtpmap: %u %[^/]/%u", &codec, mimeSubtype, &rate) != 3)
 			continue;
 		/* Note: should really look at the 'freq' and '#chans' params too */
-		ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype);
+		ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype, rate);
 	}
 
 	/* Now gather all of the codecs that were asked for: */
@@ -2014,7 +2015,8 @@
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
+				unsigned int rate = 0;
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, x, &rate), rate);
 				strncat(a, costr, sizeof(a) - strlen(a) - 1);
 			}
 		}
@@ -2028,7 +2030,8 @@
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x));
+				unsigned int rate = 0;
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(0, x, &rate), rate);
 				strncat(a, costr, sizeof(a) - strlen(a) - 1);
 				if (x == AST_RTP_DTMF) {
 					/* Indicate we support DTMF...  Not sure about 16,
@@ -2073,7 +2076,7 @@
 	snprintf(local, sizeof(local), "p:20");
 	for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
 		if (p->capability & x) {
-			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
+			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x, NULL));
 			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 		}
 	}
@@ -2104,7 +2107,7 @@
 	snprintf(local, sizeof(local), "p:20");
 	for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) {
 		if (p->capability & x) {
-			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x));
+			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x, NULL));
 			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 		}
 	}
Index: channels/chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.752
diff -u -3 -r1.752 chan_sip.c
--- channels/chan_sip.c	5 Jun 2005 14:47:09 -0000	1.752
+++ channels/chan_sip.c	5 Jun 2005 23:52:14 -0000
@@ -3145,13 +3145,14 @@
 		if (!strcasecmp(a, "sendrecv")) {
 		  	sendonly=0;
 		}
-		if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
+		unsigned int rate;
+		if (sscanf(a, "rtpmap: %u %[^/]/%u", &codec, mimeSubtype, &rate) != 3) continue;
 		if (debug)
-			ast_verbose("Found description format %s\n", mimeSubtype);
+			ast_verbose("Found description format %u %s, %u Hz\n", codec, mimeSubtype, rate);
 		/* Note: should really look at the 'freq' and '#chans' params too */
-		ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
+		ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype, rate);
 		if (p->vrtp)
-			ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype);
+			ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype, rate);
 	}
 
 	/* Now gather all of the codecs that were asked for: */
@@ -3864,13 +3865,14 @@
 		codec = ast_rtp_lookup_code(p->rtp, 1, p->prefcodec);
 		if (codec > -1) {
 			snprintf(costr, sizeof(costr), " %d", codec);
+			unsigned int rate = 0;
 			if (p->prefcodec <= AST_FORMAT_MAX_AUDIO) {
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, p->prefcodec));
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, p->prefcodec, &rate), rate);
 				ast_copy_string(a, costr, sizeof(a));
 			} else {
 				strncat(m2, costr, sizeof(m2) - strlen(m2) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/90000\r\n", codec, ast_rtp_lookup_mime_subtype(1, p->prefcodec));
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, p->prefcodec, &rate), rate);
 				ast_copy_string(a2, costr, sizeof(a2));
 			}
 		}
@@ -3888,11 +3890,13 @@
 				snprintf(costr, sizeof(costr), " %d", codec);
 				if (pref_codec <= AST_FORMAT_MAX_AUDIO) {
 					strncat(m, costr, sizeof(m) - strlen(m) - 1);
-					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, pref_codec));
+					unsigned int rate = 0;
+					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, pref_codec, &rate), rate);
 					strncat(a, costr, sizeof(a) - strlen(a) - 1);
 				} else {
 					strncat(m2, costr, sizeof(m2) - strlen(m2) - 1);
-					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/90000\r\n", codec, ast_rtp_lookup_mime_subtype(1, pref_codec));
+					unsigned int rate = 0;
+					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, pref_codec, &rate), rate);
 					strncat(a2, costr, sizeof(a2) - strlen(a) - 1);
 				}
 			}
@@ -3910,11 +3914,13 @@
 				snprintf(costr, sizeof(costr), " %d", codec);
 				if (x <= AST_FORMAT_MAX_AUDIO) {
 					strncat(m, costr, sizeof(m) - strlen(m) - 1);
-					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
+					unsigned int rate = 0;
+					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, x, &rate), rate);
 					strncat(a, costr, sizeof(a) - strlen(a) - 1);
 				} else {
 					strncat(m2, costr, sizeof(m2) - strlen(m2) - 1);
-					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/90000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x));
+					unsigned int rate = 0;
+					snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(1, x, &rate), rate);
 					strncat(a2, costr, sizeof(a2) - strlen(a2) - 1);
 				}
 			}
@@ -3922,13 +3928,16 @@
 	}
 	for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
 		if (p->noncodeccapability & x) {
-			if (debug)
-				ast_verbose("Answering with non-codec capability 0x%x (%s)\n", x, ast_rtp_lookup_mime_subtype(0, x));
+			if (debug) {
+				unsigned int rate = 0;
+				ast_verbose("Answering with non-codec capability 0x%x (%s %u Hz)\n", x, ast_rtp_lookup_mime_subtype(0, x, &rate), rate);
+			}
 			codec = ast_rtp_lookup_code(p->rtp, 0, x);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x));
+				unsigned int rate = 0;
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/%u\r\n", codec, ast_rtp_lookup_mime_subtype(0, x, &rate), rate);
 				strncat(a, costr, sizeof(a) - strlen(a) - 1);
 				if (x == AST_RTP_DTMF) {
 				  /* Indicate we support DTMF and FLASH... */
Index: codecs/codec_speex.c
===================================================================
RCS file: /usr/cvsroot/asterisk/codecs/codec_speex.c,v
retrieving revision 1.13
diff -u -3 -r1.13 codec_speex.c
--- codecs/codec_speex.c	12 May 2005 17:40:44 -0000	1.13
+++ codecs/codec_speex.c	5 Jun 2005 23:52:15 -0000
@@ -74,12 +74,13 @@
 	struct speex_coder_pvt *tmp;
 	tmp = malloc(sizeof(struct speex_coder_pvt));
 	if (tmp) {
-		if (!(tmp->speex = speex_encoder_init(&speex_nb_mode))) {
+		if (!(tmp->speex = speex_encoder_init(&speex_uwb_mode))) {
 			free(tmp);
 			tmp = NULL;
 		} else {
 			speex_bits_init(&tmp->bits);
 			speex_bits_reset(&tmp->bits);
+
 			speex_encoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
 			speex_encoder_ctl(tmp->speex, SPEEX_SET_COMPLEXITY, &complexity);
 
@@ -109,7 +110,7 @@
 	struct speex_coder_pvt *tmp;
 	tmp = malloc(sizeof(struct speex_coder_pvt));
 	if (tmp) {
-		if (!(tmp->speex = speex_decoder_init(&speex_nb_mode))) {
+		if (!(tmp->speex = speex_decoder_init(&speex_uwb_mode))) {
 			free(tmp);
 			tmp = NULL;
 		} else {
@@ -146,7 +147,7 @@
 	f.subclass = AST_FORMAT_SPEEX;
 	f.datalen = sizeof(speex_slin_ex);
 	/* All frames are 20 ms long */
-	f.samples = 160;
+	f.samples = 640;
 	f.mallocd = 0;
 	f.offset = 0;
 	f.src = __PRETTY_FUNCTION__;
@@ -264,7 +265,7 @@
 	speex_bits_pack(&tmp->bits, 15, 5);
 	len = speex_bits_write(&tmp->bits, (char *)tmp->outbuf, sizeof(tmp->outbuf));
 	tmp->f.datalen = len;
-	tmp->f.samples = y * 160;
+	tmp->f.samples = y * tmp->framesize;
 #if 0
 	{
 		static int fd = -1;
Index: include/asterisk/rtp.h
===================================================================
RCS file: /usr/cvsroot/asterisk/include/asterisk/rtp.h,v
retrieving revision 1.22
diff -u -3 -r1.22 rtp.h
--- include/asterisk/rtp.h	21 Apr 2005 06:02:44 -0000	1.22
+++ include/asterisk/rtp.h	5 Jun 2005 23:52:15 -0000
@@ -91,18 +91,18 @@
 void ast_rtp_pt_default(struct ast_rtp* rtp);
 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt);
 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
-			 char* mimeType, char* mimeSubtype);
+			     char* mimeType, char* mimeSubtype, unsigned int rate);
 
 /*  Mapping between RTP payload format codes and Asterisk codes: */
 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
-int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
+int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code);
 void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local);
 
 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
 			     int* astFormats, int* nonAstFormats);
 
 /*  Mapping an Asterisk code into a MIME subtype (string): */
-char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code);
+char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code, unsigned int *rate);
 
 /* Build a string of MIME subtype names from a capability list */
 char *ast_rtp_lookup_mime_multiple(char *buf, int size, const int capability, const int isAstFormat);
Index: res/res_musiconhold.c
===================================================================
RCS file: /usr/cvsroot/asterisk/res/res_musiconhold.c,v
retrieving revision 1.58
diff -u -3 -r1.58 res_musiconhold.c
--- res/res_musiconhold.c	21 Apr 2005 06:02:44 -0000	1.58
+++ res/res_musiconhold.c	5 Jun 2005 23:52:15 -0000
@@ -290,7 +290,7 @@
 	DIR *dir;
 	struct dirent *de;
 
-	
+
 	dir = opendir(class->dir);
 	if (!dir && !strstr(class->dir,"http://") && !strstr(class->dir,"HTTP://")) {
 		ast_log(LOG_WARNING, "%s is not a valid directory\n", class->dir);





More information about the asterisk-dev mailing list