summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorDavid Vossel <dvossel@digium.com>2010-06-17 17:23:43 +0000
committerDavid Vossel <dvossel@digium.com>2010-06-17 17:23:43 +0000
commitb00f58da25df6d86a409a7e278b987f6ee863fb4 (patch)
tree200243a6d4e70905af7d2e36981d2928f03e6936 /main
parent0ef555074237d2db34bc99bf1fb913bbe9746a25 (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: https://origsvn.digium.com/svn/asterisk/trunk@271231 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/channel.c1
-rw-r--r--main/frame.c24
-rw-r--r--main/rtp_engine.c2
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 */
};