diff options
author | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-06-17 17:23:43 +0000 |
---|---|---|
committer | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-06-17 17:23:43 +0000 |
commit | 637447be7d05aaac944171053df4f82e2cb8ab07 (patch) | |
tree | 200243a6d4e70905af7d2e36981d2928f03e6936 /main | |
parent | a4f9ce35cfe885eb10082d20c46884da7891c3c1 (diff) |
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
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@271231 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r-- | main/channel.c | 1 | ||||
-rw-r--r-- | main/frame.c | 24 | ||||
-rw-r--r-- | main/rtp_engine.c | 2 |
3 files changed, 16 insertions, 11 deletions
diff --git a/main/channel.c b/main/channel.c index 90ac32de0..af2c036a9 100644 --- a/main/channel.c +++ b/main/channel.c @@ -813,6 +813,7 @@ format_t ast_best_codec(format_t fmts) /*! 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 */ diff --git a/main/frame.c b/main/frame.c index 1eb7d411b..9f599a991 100644 --- a/main/frame.c +++ b/main/frame.c @@ -104,6 +104,7 @@ static const struct ast_format_list AST_FORMAT_LIST[] = { { 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 @@ static const struct ast_format_list AST_FORMAT_LIST[] = { { 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 unsigned char get_n_bits_at(unsigned char *data, int n, int bit) 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 @@ static int speex_samples(unsigned char *data, int len) } bit += off; - if ((len * 8 - bit) == 0) { + if ((len * 8 - bit) < 5) break; - } else if ((len * 8 - bit) < 5) { - ast_log(LOG_WARNING, "Not enough bits remaining after wide band for speex samples.\n"); - break; - } /* get control bits */ c = get_n_bits_at(data, 5, bit); @@ -1427,12 +1424,14 @@ static int speex_samples(unsigned char *data, int len) 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) */ @@ -1452,6 +1451,9 @@ int ast_codec_get_samples(struct ast_frame *f) 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); break; diff --git a/main/rtp_engine.c b/main/rtp_engine.c index c42d3f6fb..5e4db2309 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -102,6 +102,7 @@ static const struct ast_rtp_mime_type { {{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 @@ static const struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT] = { [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 */ }; |