Index: build_tools/embed_modules.xml =================================================================== --- build_tools/embed_modules.xml (revision 51363) +++ build_tools/embed_modules.xml (working copy) @@ -8,7 +8,7 @@ gnu_ld - + gnu_ld Index: include/asterisk/frame.h =================================================================== --- include/asterisk/frame.h (revision 51363) +++ include/asterisk/frame.h (working copy) @@ -243,6 +243,8 @@ #define AST_FORMAT_G726 (1 << 11) /*! G.722 */ #define AST_FORMAT_G722 (1 << 12) +/*! AMR-NB */ +#define AST_FORMAT_AMRNB (1 << 13) /*! Maximum audio format */ #define AST_FORMAT_MAX_AUDIO (1 << 15) /*! Maximum audio mask */ Index: main/channel.c =================================================================== --- main/channel.c (revision 51363) +++ main/channel.c (working copy) @@ -578,6 +578,8 @@ /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good */ AST_FORMAT_GSM, + /*! Try AMR */ + AST_FORMAT_AMRNB, /*! iLBC is not too bad */ AST_FORMAT_ILBC, /*! Speex is free, but computationally more expensive than GSM */ Index: main/rtp.c =================================================================== --- main/rtp.c (revision 51363) +++ main/rtp.c (working copy) @@ -1273,10 +1273,12 @@ if (rtp->themssrc==0) rtp->themssrc = ntohl(rtpheader[2]); /* Record their SSRC to put in future RR */ - if (rtp_debug_test_addr(&sin)) - ast_verbose("Got RTP packet from %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", - ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); - + if (rtp_debug_test_addr(&sin)) { + unsigned char *data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET; + ast_verbose("Got RTP packet from %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u\n", + ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); + + } rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); if (!rtpPT.isAstFormat) { struct ast_frame *f = NULL; @@ -1375,6 +1377,7 @@ {{1, AST_FORMAT_ILBC}, "audio", "iLBC"}, {{1, AST_FORMAT_G722}, "audio", "G722"}, {{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"}, + {{1, AST_FORMAT_AMRNB}, "audio", "AMR"}, {{0, AST_RTP_DTMF}, "audio", "telephone-event"}, {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"}, {{0, AST_RTP_CN}, "audio", "CN"}, @@ -1413,6 +1416,7 @@ [26] = {1, AST_FORMAT_JPEG}, [31] = {1, AST_FORMAT_H261}, [34] = {1, AST_FORMAT_H263}, + [96] = {1, AST_FORMAT_AMRNB}, /* Added 96 = AMR-NB */ [97] = {1, AST_FORMAT_ILBC}, [99] = {1, AST_FORMAT_H264}, [101] = {0, AST_RTP_DTMF}, Index: main/frame.c =================================================================== --- main/frame.c (revision 51363) +++ main/frame.c (working copy) @@ -117,10 +117,10 @@ { 1, AST_FORMAT_ILBC, "ilbc", "iLBC", 50, 30, 30, 30, 30 }, /*!< 11: codec_ilbc.c */ /* inc=30ms - workaround */ { 1, AST_FORMAT_G726_AAL2, "g726aal2", "G.726 AAL2", 40, 10, 300, 10, 20 }, /*!< 12: codec_g726.c */ { 1, AST_FORMAT_G722, "g722", "G722"}, /*!< 13 */ + { 1, AST_FORMAT_AMRNB, "amr", "AMR NB", 32, 20, 300, 0, 20}, /*!< 14 codec_amr.c */ { 0, 0, "nothing", "undefined" }, { 0, 0, "nothing", "undefined" }, { 0, 0, "nothing", "undefined" }, - { 0, 0, "nothing", "undefined" }, { 0, AST_FORMAT_MAX_AUDIO, "maxaudio", "Maximum audio format" }, { 1, AST_FORMAT_JPEG, "jpeg", "JPEG image"}, /*!< 17: See format_jpeg.c */ { 1, AST_FORMAT_PNG, "png", "PNG image"}, /*!< 18: Image format */ @@ -1358,6 +1358,24 @@ return cnt; } +static int amr_samples(unsigned char *data, int datalen) +{ + short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; + int samples = 0; + while (datalen > 0) { + unsigned dec_mode = (data[0]>>3) & 0x000f; + unsigned psize = block_size[dec_mode]; + + if (psize) + samples += 160; + + data += psize+1; /* Skip over the block. */ + datalen -= psize+1; + /* ast_verbose("Got AMR frame size %d\n", psize); */ + } + return samples; +} + int ast_codec_get_samples(struct ast_frame *f) { int samples=0; @@ -1395,6 +1413,9 @@ case AST_FORMAT_G726_AAL2: samples = f->datalen * 2; break; + case AST_FORMAT_AMRNB: + samples = amr_samples(f->data, f->datalen); + break; default: ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass)); } Index: codecs/Makefile =================================================================== --- codecs/Makefile (revision 51363) +++ codecs/Makefile (working copy) @@ -26,6 +26,7 @@ LIBILBC:=ilbc/libilbc.a LIBLPC10:=lpc10/liblpc10.a LIBG722:=g722/libg722.a +LIBAMR:=amr/libamr.a all: _all @@ -41,6 +42,7 @@ $(MAKE) -C lpc10 clean $(MAKE) -C ilbc clean $(MAKE) -C g722 clean + $(MAKE) -C amr clean gsm/lib/libgsm.a: @mkdir -p gsm/lib @@ -60,3 +62,8 @@ @$(MAKE) -C g722 all $(if $(filter codec_g722,$(EMBEDDED_MODS)),modules.link,codec_g722.so): $(LIBG722) + +$(LIBAMR): + @$(MAKE) -C amr + +$(if $(filter codec_amr,$(EMBEDDED_MODS)),modules.link,codec_amr.so): $(LIBAMR)