From cfc875dfa13f74ffcaea66f5665efed7a8753ef3 Mon Sep 17 00:00:00 2001 From: Lubos Dolezel Date: Mon, 15 Jun 2015 11:27:49 +0200 Subject: Added G729A decoder/encoder wrappers (issue #15) --- src/audio/audio_codecs.cpp | 1 + src/audio/audio_decoder.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++ src/audio/audio_decoder.h | 25 ++++++++++++++++++++++++ src/audio/audio_encoder.cpp | 31 ++++++++++++++++++++++++++++++ src/audio/audio_encoder.h | 21 ++++++++++++++++++++ 5 files changed, 125 insertions(+) (limited to 'src/audio') diff --git a/src/audio/audio_codecs.cpp b/src/audio/audio_codecs.cpp index 75a9262..849638d 100644 --- a/src/audio/audio_codecs.cpp +++ b/src/audio/audio_codecs.cpp @@ -26,6 +26,7 @@ unsigned short audio_sample_rate(t_audio_codec codec) { case CODEC_GSM: case CODEC_SPEEX_NB: case CODEC_ILBC: + case CODEC_G729A: case CODEC_G726_16: case CODEC_G726_24: case CODEC_G726_32: diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index e4c1d74..0f32214 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -521,3 +521,50 @@ bool t_g726_audio_decoder::valid_payload_size(uint16 payload_size, return (payload_size * 8 / _bits_per_sample ) <= sample_buf_size; } + +#ifdef HAVE_BCG729 + +t_g729a_audio_decoder::t_g729a_audio_decoder(uint16 default_ptime, t_user *user_config) + : t_audio_decoder(default_ptime, true, user_config) +{ + _context = initBcg729DecoderChannel(); +} + +t_g729a_audio_decoder::~t_g729a_audio_decoder() +{ + closeBcg729DecoderChannel(_context); +} + +uint16 t_g729a_audio_decoder::get_ptime(uint16 payload_size) const +{ + return (payload_size * 8) / (audio_sample_rate(_codec) / 1000); +} + +uint16 t_g729a_audio_decoder::decode(uint8 *payload, uint16 payload_size, + int16 *pcm_buf, uint16 pcm_buf_size) +{ + assert((payload_size % 10) == 0); + assert(pcm_buf_size >= payload_size*8); + + for (uint16 done = 0; done < payload_size; done += 10) + { + bcg729Decoder(_context, &payload[done], false, &pcm_buf[done * 8]); + } + + return payload_size * 8; +} + +bool t_g729a_audio_decoder::valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const +{ + return payload_size > 0 && (payload_size % 10) == 0; +} + +uint16 t_g729a_audio_decoder::conceal(int16 *pcm_buf, uint16 pcm_buf_size) +{ + assert(pcm_buf_size >= 80); + + bcg729Decoder(_context, nullptr, true, pcm_buf); + return 80; +} + +#endif diff --git a/src/audio/audio_decoder.h b/src/audio/audio_decoder.h index cee198f..48ef29c 100644 --- a/src/audio/audio_decoder.h +++ b/src/audio/audio_decoder.h @@ -36,6 +36,12 @@ #include #endif +#ifdef HAVE_BCG729 +extern "C" { +# include +} +#endif + #ifdef HAVE_ILBC #ifndef HAVE_ILBC_CPP extern "C" { @@ -197,4 +203,23 @@ public: virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const; }; +#ifdef HAVE_BCG729 + +// G.729A +class t_g729a_audio_decoder : public t_audio_decoder { +public: + t_g729a_audio_decoder(uint16 default_ptime, t_user *user_config); + ~t_g729a_audio_decoder(); + + virtual uint16 get_ptime(uint16 payload_size) const override; + virtual uint16 decode(uint8 *payload, uint16 payload_size, + int16 *pcm_buf, uint16 pcm_buf_size) override; + virtual bool valid_payload_size(uint16 payload_size, uint16 sample_buf_size) const override; + virtual uint16 conceal(int16 *pcm_buf, uint16 pcm_buf_size) override; +private: + bcg729DecoderChannelContextStruct* _context; +}; + +#endif + #endif diff --git a/src/audio/audio_encoder.cpp b/src/audio/audio_encoder.cpp index 94e82b4..e77ab14 100644 --- a/src/audio/audio_encoder.cpp +++ b/src/audio/audio_encoder.cpp @@ -428,3 +428,34 @@ uint16 t_g726_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, return 0; } + +#ifdef HAVE_BCG729 + +t_g729a_audio_encoder::t_g729a_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config) + : t_audio_encoder(payload_id, ptime, user_config) +{ + _context = initBcg729EncoderChannel(); +} + +t_g729a_audio_encoder::~t_g729a_audio_encoder() +{ + closeBcg729EncoderChannel(_context); +} + +uint16 t_g729a_audio_encoder::encode(int16 *sample_buf, uint16 nsamples, + uint8 *payload, uint16 payload_size, bool &silence) +{ + assert ((nsamples % 80) == 0); + assert (payload_size >= (nsamples/8)); + + silence = false; + + for (uint16 done = 0; done < nsamples; done += 80) + { + bcg729Encoder(_context, &sample_buf[done], &payload[done / 8]); + } + + return nsamples / 8; +} + +#endif diff --git a/src/audio/audio_encoder.h b/src/audio/audio_encoder.h index e2fb874..b900414 100644 --- a/src/audio/audio_encoder.h +++ b/src/audio/audio_encoder.h @@ -35,6 +35,12 @@ #include #endif +#ifdef HAVE_BCG729 +extern "C" { +# include +} +#endif + #ifdef HAVE_ILBC #ifndef HAVE_ILBC_CPP extern "C" { @@ -179,4 +185,19 @@ public: uint8 *payload, uint16 payload_size, bool &silence); }; +#ifdef HAVE_BCG729 +class t_g729a_audio_encoder : public t_audio_encoder +{ +public: + t_g729a_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config); + virtual ~t_g729a_audio_encoder(); + + virtual uint16 encode(int16 *sample_buf, uint16 nsamples, + uint8 *payload, uint16 payload_size, bool &silence); +private: + bcg729EncoderChannelContextStruct* _context; +}; + +#endif + #endif -- cgit v1.2.3