[asterisk-commits] dvossel: trunk r271231 - in /trunk: ./ codecs/ include/asterisk/ main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 17 12:23:48 CDT 2010


Author: dvossel
Date: Thu Jun 17 12:23:43 2010
New Revision: 271231

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=271231
Log:
adds speex 16khz audio support

(closes issue #17501)
Reported by: fabled
Patches:
      asterisk-trunk-speex-wideband-v2.patch uploaded by fabled (license 448)
Tested by: malcolmd, fabled, dvossel


Modified:
    trunk/CHANGES
    trunk/codecs/codec_speex.c
    trunk/include/asterisk/frame.h
    trunk/main/channel.c
    trunk/main/frame.c
    trunk/main/rtp_engine.c
    trunk/res/res_rtp_asterisk.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Thu Jun 17 12:23:43 2010
@@ -500,6 +500,8 @@
  * Distributed devicestate now supports the use of the XMPP protocol, in addition to
    AIS.  For more information, please see doc/distributed_devstate-XMPP.txt
  * The addition of G.719 pass-through support.
+ * Added support for 16khz Speex audio.  This can be enabled by using 'allow=speex16'
+   during device configuration.
 
 
 CLI Changes

Modified: trunk/codecs/codec_speex.c
URL: http://svnview.digium.com/svn/asterisk/trunk/codecs/codec_speex.c?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/codecs/codec_speex.c (original)
+++ trunk/codecs/codec_speex.c Thu Jun 17 12:23:43 2010
@@ -97,12 +97,11 @@
 #endif
 };
 
-
-static int lintospeex_new(struct ast_trans_pvt *pvt)
+static int speex_encoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile, int sampling_rate)
 {
 	struct speex_coder_pvt *tmp = pvt->pvt;
 
-	if (!(tmp->speex = speex_encoder_init(&speex_nb_mode)))
+	if (!(tmp->speex = speex_encoder_init(profile)))
 		return -1;
 
 	speex_bits_init(&tmp->bits);
@@ -111,7 +110,7 @@
 	speex_encoder_ctl(tmp->speex, SPEEX_SET_COMPLEXITY, &complexity);
 #ifdef _SPEEX_TYPES_H
 	if (preproc) {
-		tmp->pp = speex_preprocess_state_init(tmp->framesize, 8000); /* XXX what is this 8000 ? */
+		tmp->pp = speex_preprocess_state_init(tmp->framesize, sampling_rate);
 		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_VAD, &pp_vad);
 		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC, &pp_agc);
 		speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &pp_agc_level);
@@ -139,11 +138,21 @@
 	return 0;
 }
 
-static int speextolin_new(struct ast_trans_pvt *pvt)
+static int lintospeex_new(struct ast_trans_pvt *pvt)
+{
+	return speex_encoder_construct(pvt, &speex_nb_mode, 8000);
+}
+
+static int lin16tospeexwb_new(struct ast_trans_pvt *pvt)
+{
+	return speex_encoder_construct(pvt, &speex_wb_mode, 16000);
+}
+
+static int speex_decoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *profile)
 {
 	struct speex_coder_pvt *tmp = pvt->pvt;
 	
-	if (!(tmp->speex = speex_decoder_init(&speex_nb_mode)))
+	if (!(tmp->speex = speex_decoder_init(profile)))
 		return -1;
 
 	speex_bits_init(&tmp->bits);
@@ -152,6 +161,16 @@
 		speex_decoder_ctl(tmp->speex, SPEEX_SET_ENH, &enhancement);
 
 	return 0;
+}
+
+static int speextolin_new(struct ast_trans_pvt *pvt)
+{
+	return speex_decoder_construct(pvt, &speex_nb_mode);
+}
+
+static int speexwbtolin16_new(struct ast_trans_pvt *pvt)
+{
+	return speex_decoder_construct(pvt, &speex_wb_mode);
 }
 
 /*! \brief convert and store into outbuf */
@@ -328,6 +347,34 @@
 	.srcfmt = AST_FORMAT_SLINEAR,
 	.dstfmt = AST_FORMAT_SPEEX,
 	.newpvt = lintospeex_new,
+	.framein = lintospeex_framein,
+	.frameout = lintospeex_frameout,
+	.destroy = lintospeex_destroy,
+	.sample = slin8_sample,
+	.desc_size = sizeof(struct speex_coder_pvt),
+	.buffer_samples = BUFFER_SAMPLES,
+	.buf_size = BUFFER_SAMPLES * 2, /* XXX maybe a lot less ? */
+};
+
+static struct ast_translator speexwbtolin16 = {
+	.name = "speexwbtolin16", 
+	.srcfmt = AST_FORMAT_SPEEX16,
+	.dstfmt =  AST_FORMAT_SLINEAR16,
+	.newpvt = speexwbtolin16_new,
+	.framein = speextolin_framein,
+	.destroy = speextolin_destroy,
+	.sample = speex_sample,
+	.desc_size = sizeof(struct speex_coder_pvt),
+	.buffer_samples = BUFFER_SAMPLES,
+	.buf_size = BUFFER_SAMPLES * 2,
+	.native_plc = 1,
+};
+
+static struct ast_translator lin16tospeexwb = {
+	.name = "lin16tospeexwb", 
+	.srcfmt = AST_FORMAT_SLINEAR16,
+	.dstfmt = AST_FORMAT_SPEEX16,
+	.newpvt = lin16tospeexwb_new,
 	.framein = lintospeex_framein,
 	.frameout = lintospeex_frameout,
 	.destroy = lintospeex_destroy,
@@ -441,28 +488,29 @@
 
 static int unload_module(void)
 {
-	int res;
-
-	res = ast_unregister_translator(&lintospeex);
+	int res = 0;
+
 	res |= ast_unregister_translator(&speextolin);
+	res |= ast_unregister_translator(&lintospeex);
+	res |= ast_unregister_translator(&speexwbtolin16);
+	res |= ast_unregister_translator(&lin16tospeexwb);
 
 	return res;
 }
 
 static int load_module(void)
 {
-	int res;
+	int res = 0;
 
 	if (parse_config(0))
 		return AST_MODULE_LOAD_DECLINE;
-	res=ast_register_translator(&speextolin);
-	if (!res) 
-		res=ast_register_translator(&lintospeex);
-	else
-		ast_unregister_translator(&speextolin);
-	if (res)
-		return AST_MODULE_LOAD_FAILURE;
-	return AST_MODULE_LOAD_SUCCESS;
+
+	res |= ast_register_translator(&speextolin);
+	res |= ast_register_translator(&lintospeex);
+	res |= ast_register_translator(&speexwbtolin16);
+	res |= ast_register_translator(&lin16tospeexwb);
+
+	return res;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Speex Coder/Decoder",

Modified: trunk/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/frame.h?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Thu Jun 17 12:23:43 2010
@@ -296,8 +296,10 @@
 #define AST_FORMAT_TEXT_MASK  (((1ULL << 30)-1) & ~(AST_FORMAT_AUDIO_MASK) & ~(AST_FORMAT_VIDEO_MASK))
 /*! G.719 (64 kbps assumed) */
 #define AST_FORMAT_G719	      (1ULL << 32)
+/*! SpeeX Wideband (16kHz) Free Compression */
+#define AST_FORMAT_SPEEX16    (1ULL << 33)
 /*! Raw mu-law data (G.711) */
-#define AST_FORMAT_TESTLAW       (1ULL << 47)
+#define AST_FORMAT_TESTLAW    (1ULL << 47)
 /*! Reserved bit - do not use */
 #define AST_FORMAT_RESERVED   (1ULL << 63)
 
@@ -745,6 +747,7 @@
 	case AST_FORMAT_G722:
 	case AST_FORMAT_SLINEAR16:
 	case AST_FORMAT_SIREN7:
+	case AST_FORMAT_SPEEX16:
 		return 16000;
 	case AST_FORMAT_SIREN14:
 		return 32000;

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Jun 17 12:23:43 2010
@@ -813,6 +813,7 @@
 		/*! iLBC is not too bad */
 		AST_FORMAT_ILBC,
 		/*! Speex is free, but computationally more expensive than GSM */
+		AST_FORMAT_SPEEX16,
 		AST_FORMAT_SPEEX,
 		/*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
 		    to use it */

Modified: trunk/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/frame.c?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/main/frame.c (original)
+++ trunk/main/frame.c Thu Jun 17 12:23:43 2010
@@ -104,6 +104,7 @@
 	{ AST_FORMAT_LPC10, "lpc10", 8000, "LPC10", 7, 20, 20, 20, 20 },                                       /*!< codec_lpc10.c */ 
 	{ AST_FORMAT_G729A, "g729", 8000, "G.729A", 10, 10, 230, 10, 20, AST_SMOOTHER_FLAG_G729 },             /*!< Binary commercial distribution */
 	{ AST_FORMAT_SPEEX, "speex", 8000, "SpeeX", 10, 10, 60, 10, 20 },                                      /*!< codec_speex.c */
+	{ AST_FORMAT_SPEEX16, "speex16", 16000, "SpeeX 16khz", 10, 10, 60, 10, 20 },                          /*!< codec_speex.c */
 	{ AST_FORMAT_ILBC, "ilbc", 8000, "iLBC", 50, 30, 30, 30, 30 },                                         /*!< codec_ilbc.c */ /* inc=30ms - workaround */
 	{ AST_FORMAT_G726_AAL2, "g726aal2", 8000, "G.726 AAL2", 40, 10, 300, 10, 20 },                         /*!< codec_g726.c */
 	{ AST_FORMAT_G722, "g722", 16000, "G722", 80, 10, 150, 10, 20 },                                       /*!< codec_g722.c */
@@ -119,7 +120,7 @@
 	{ AST_FORMAT_T140, "t140", 0, "Passthrough T.140 Realtime Text" },                                     /*!< Passthrough support for T.140 Realtime Text */
 	{ AST_FORMAT_SIREN7, "siren7", 16000, "ITU G.722.1 (Siren7, licensed from Polycom)", 80, 20, 80, 20, 20 },			/*!< Binary commercial distribution */
 	{ AST_FORMAT_SIREN14, "siren14", 32000, "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)", 120, 20, 80, 20, 20 },	/*!< Binary commercial distribution */
-	{ AST_FORMAT_TESTLAW, "testlaw", 8000, "G.711 test-law", 80, 10, 150, 10, 20 },                                 /*!< codec_ulaw.c */
+	{ AST_FORMAT_TESTLAW, "testlaw", 8000, "G.711 test-law", 80, 10, 150, 10, 20 },                        /*!< codec_ulaw.c */
 	{ AST_FORMAT_G719, "g719", 48000, "ITU G.719", 160, 20, 80, 20, 20 },
 };
 
@@ -1354,7 +1355,7 @@
 static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
 {
 	static const int SpeexWBSubModeSz[] = {
-		0, 36, 112, 192,
+		4, 36, 112, 192,
 		352, 0, 0, 0 };
 	int off = bit;
 	unsigned char c;
@@ -1407,12 +1408,8 @@
 		}
 		bit += off;
 
-		if ((len * 8 - bit) == 0) {
-			break;
-		} else if ((len * 8 - bit) < 5) {
-			ast_log(LOG_WARNING, "Not enough bits remaining after wide band for speex samples.\n");
-			break;
-		}
+		if ((len * 8 - bit) < 5)
+			break;
 
 		/* get control bits */
 		c = get_n_bits_at(data, 5, bit);
@@ -1427,12 +1424,14 @@
 			bit += 4;
 			bit += SpeexInBandSz[c];
 		} else if (c == 13) {
-			/* user in-band; next 5 bits contain msg len */
-			c = get_n_bits_at(data, 5, bit);
-			bit += 5;
-			bit += c * 8;
+			/* user in-band; next 4 bits contain msg len */
+			c = get_n_bits_at(data, 4, bit);
+			bit += 4;
+			/* after which it's 5-bit signal id + c bytes of data */
+			bit += 5 + c * 8;
 		} else if (c > 8) {
 			/* unknown */
+			ast_log(LOG_WARNING, "Unknown speex control frame %d\n", c);
 			break;
 		} else {
 			/* skip number bits for submode (less the 5 control bits) */
@@ -1451,6 +1450,9 @@
 	switch (f->subclass.codec) {
 	case AST_FORMAT_SPEEX:
 		samples = speex_samples(f->data.ptr, f->datalen);
+		break;
+	case AST_FORMAT_SPEEX16:
+		samples = 2 * speex_samples(f->data.ptr, f->datalen);
 		break;
 	case AST_FORMAT_G723_1:
 		samples = g723_samples(f->data.ptr, f->datalen);

Modified: trunk/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/rtp_engine.c?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/main/rtp_engine.c (original)
+++ trunk/main/rtp_engine.c Thu Jun 17 12:23:43 2010
@@ -102,6 +102,7 @@
 	{{1, AST_FORMAT_G729A}, "audio", "G729A", 8000},
 	{{1, AST_FORMAT_G729A}, "audio", "G.729", 8000},
 	{{1, AST_FORMAT_SPEEX}, "audio", "speex", 8000},
+	{{1, AST_FORMAT_SPEEX16}, "audio", "speex", 16000},
 	{{1, AST_FORMAT_ILBC}, "audio", "iLBC", 8000},
 	/* this is the sample rate listed in the RTP profile for the G.722
 	              codec, *NOT* the actual sample rate of the media stream
@@ -171,6 +172,7 @@
 	[112] = {1, AST_FORMAT_G726_AAL2},
 	[115] = {1, AST_FORMAT_SIREN14},
 	[116] = {1, AST_FORMAT_G719},
+	[117] = {1, AST_FORMAT_SPEEX16},
 	[121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
 };
 

Modified: trunk/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_rtp_asterisk.c?view=diff&rev=271231&r1=271230&r2=271231
==============================================================================
--- trunk/res/res_rtp_asterisk.c (original)
+++ trunk/res/res_rtp_asterisk.c Thu Jun 17 12:23:43 2010
@@ -1228,6 +1228,7 @@
 
 		switch (subclass) {
 		case AST_FORMAT_SPEEX:
+		case AST_FORMAT_SPEEX16:
 		case AST_FORMAT_G723_1:
 		case AST_FORMAT_SIREN7:
 		case AST_FORMAT_SIREN14:




More information about the asterisk-commits mailing list