From 98bf08bdcf2edd9d397f32650a8bfe62186fbecf Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Sun, 9 Feb 2014 11:50:07 +0100 Subject: baresip 0.4.10 --- modules/amr/amr.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++ modules/amr/module.mk | 64 ++++++++++ 2 files changed, 404 insertions(+) create mode 100644 modules/amr/amr.c create mode 100644 modules/amr/module.mk (limited to 'modules/amr') diff --git a/modules/amr/amr.c b/modules/amr/amr.c new file mode 100644 index 0000000..3b29788 --- /dev/null +++ b/modules/amr/amr.c @@ -0,0 +1,340 @@ +/** + * @file amr.c Adaptive Multi-Rate (AMR) audio codec + * + * Copyright (C) 2010 Creytiv.com + */ +#include +#ifdef AMR_NB +#include +#include +#endif +#ifdef AMR_WB +#ifdef _TYPEDEF_H +#define typedef_h +#endif +#include +#include +#endif +#include +#include + + +#define DEBUG_MODULE "amr" +#define DEBUG_LEVEL 5 +#include + + +#ifdef VO_AMRWBENC_ENC_IF_H +#define IF2E_IF_encode E_IF_encode +#define IF2D_IF_decode D_IF_decode +#endif + + +/* + * This module supports both AMR Narrowband (8000 Hz) and + * AMR Wideband (16000 Hz) audio codecs. + * + * Reference: + * + * http://tools.ietf.org/html/rfc4867 + * + * http://www.penguin.cz/~utx/amr + */ + + +#ifndef L_FRAME16k +#define L_FRAME16k 320 +#endif + +#ifndef NB_SERIAL_MAX +#define NB_SERIAL_MAX 61 +#endif + +enum { + FRAMESIZE_NB = 160 +}; + + +struct auenc_state { + const struct aucodec *ac; + void *enc; /**< Encoder state */ +}; + +struct audec_state { + const struct aucodec *ac; + void *dec; /**< Decoder state */ +}; + + +static void encode_destructor(void *arg) +{ + struct auenc_state *st = arg; + + switch (st->ac->srate) { + +#ifdef AMR_NB + case 8000: + Encoder_Interface_exit(st->enc); + break; +#endif + +#ifdef AMR_WB + case 16000: + E_IF_exit(st->enc); + break; +#endif + } +} + + +static void decode_destructor(void *arg) +{ + struct audec_state *st = arg; + + switch (st->ac->srate) { + +#ifdef AMR_NB + case 8000: + Decoder_Interface_exit(st->dec); + break; +#endif + +#ifdef AMR_WB + case 16000: + D_IF_exit(st->dec); + break; +#endif + } +} + + +static int encode_update(struct auenc_state **aesp, + const struct aucodec *ac, + struct auenc_param *prm, const char *fmtp) +{ + struct auenc_state *st; + int err = 0; + (void)prm; + (void)fmtp; + + if (!aesp || !ac) + return EINVAL; + + if (*aesp) + return 0; + + st = mem_zalloc(sizeof(*st), encode_destructor); + if (!st) + return ENOMEM; + + st->ac = ac; + + switch (ac->srate) { + +#ifdef AMR_NB + case 8000: + st->enc = Encoder_Interface_init(0); + break; +#endif + +#ifdef AMR_WB + case 16000: + st->enc = E_IF_init(); + break; +#endif + } + + if (!st->enc) + err = ENOMEM; + + if (err) + mem_deref(st); + else + *aesp = st; + + return err; +} + + +static int decode_update(struct audec_state **adsp, + const struct aucodec *ac, const char *fmtp) +{ + struct audec_state *st; + int err = 0; + (void)fmtp; + + if (!adsp || !ac) + return EINVAL; + + if (*adsp) + return 0; + + st = mem_zalloc(sizeof(*st), decode_destructor); + if (!st) + return ENOMEM; + + st->ac = ac; + + switch (ac->srate) { + +#ifdef AMR_NB + case 8000: + st->dec = Decoder_Interface_init(); + break; +#endif + +#ifdef AMR_WB + case 16000: + st->dec = D_IF_init(); + break; +#endif + } + + if (!st->dec) + err = ENOMEM; + + if (err) + mem_deref(st); + else + *adsp = st; + + return err; +} + + +#ifdef AMR_WB +static int encode_wb(struct auenc_state *st, uint8_t *buf, size_t *len, + const int16_t *sampv, size_t sampc) +{ + int n; + + if (sampc != L_FRAME16k) + return EINVAL; + + if (*len < NB_SERIAL_MAX) + return ENOMEM; + + n = IF2E_IF_encode(st->enc, 8, sampv, buf, 0); + if (n <= 0) { + DEBUG_WARNING("encode error: %d\n", n); + return EPROTO; + } + + *len = n; + + return 0; +} + + +static int decode_wb(struct audec_state *st, int16_t *sampv, size_t *sampc, + const uint8_t *buf, size_t len) +{ + if (*sampc < L_FRAME16k) + return ENOMEM; + if (len > NB_SERIAL_MAX) + return EINVAL; + + IF2D_IF_decode(st->dec, buf, sampv, 0); + + *sampc = L_FRAME16k; + + return 0; +} +#endif + + +#ifdef AMR_NB +static int encode_nb(struct auenc_state *st, uint8_t *buf, + size_t *len, const int16_t *sampv, size_t sampc) +{ + int r; + + if (!st || !buf || !len || !sampv || sampc != FRAMESIZE_NB) + return EINVAL; + if (*len < NB_SERIAL_MAX) + return ENOMEM; + + r = Encoder_Interface_Encode(st->enc, MR475, sampv, buf, 0); + if (r <= 0) + return EPROTO; + + *len = r; + + return 0; +} + + +static int decode_nb(struct audec_state *st, int16_t *sampv, + size_t *sampc, const uint8_t *buf, size_t len) +{ + if (!st || !sampv || !sampc || !buf) + return EINVAL; + + if (len > NB_SERIAL_MAX) + return EPROTO; + + if (*sampc < L_FRAME16k) + return ENOMEM; + + Decoder_Interface_Decode(st->dec, buf, sampv, 0); + + *sampc = FRAMESIZE_NB; + + return 0; +} +#endif + + +#ifdef AMR_WB +static struct aucodec amr_wb = { + LE_INIT, NULL, "AMR-WB", 16000, 1, NULL, + encode_update, encode_wb, + decode_update, decode_wb, + NULL, NULL, NULL +}; +#endif +#ifdef AMR_NB +static struct aucodec amr_nb = { + LE_INIT, NULL, "AMR", 8000, 1, NULL, + encode_update, encode_nb, + decode_update, decode_nb, + NULL, NULL, NULL +}; +#endif + + +static int module_init(void) +{ + int err = 0; + +#ifdef AMR_WB + aucodec_register(&amr_wb); +#endif +#ifdef AMR_NB + aucodec_register(&amr_nb); +#endif + + return err; +} + + +static int module_close(void) +{ +#ifdef AMR_WB + aucodec_unregister(&amr_wb); +#endif +#ifdef AMR_NB + aucodec_unregister(&amr_nb); +#endif + + return 0; +} + + +/** Module exports */ +EXPORT_SYM const struct mod_export DECL_EXPORTS(amr) = { + "amr", + "codec", + module_init, + module_close +}; diff --git a/modules/amr/module.mk b/modules/amr/module.mk new file mode 100644 index 0000000..cbe1013 --- /dev/null +++ b/modules/amr/module.mk @@ -0,0 +1,64 @@ +# +# module.mk +# +# Copyright (C) 2010 Creytiv.com +# + +MOD := amr +$(MOD)_SRCS += amr.c + + +ifneq ($(shell [ -d $(SYSROOT)/include/opencore-amrnb ] && echo 1 ),) +CFLAGS += -DAMR_NB=1 -I$(SYSROOT)/include/opencore-amrnb +$(MOD)_LFLAGS += -lopencore-amrnb +else +ifneq ($(shell [ -d $(SYSROOT_ALT)/include/opencore-amrnb ] && echo 1 ),) +CFLAGS += -DAMR_NB=1 -I$(SYSROOT_ALT)/include/opencore-amrnb +$(MOD)_LFLAGS += -lopencore-amrnb +else +ifneq ($(shell [ -d $(SYSROOT)/local/include/amrnb ] && echo 1),) +CFLAGS += -DAMR_NB=1 -I$(SYSROOT)/local/include/amrnb +$(MOD)_LFLAGS += -lamrnb +else +ifneq ($(shell [ -d $(SYSROOT)/include/amrnb ] && echo 1),) +CFLAGS += -DAMR_NB=1 -I$(SYSROOT)/include/amrnb +$(MOD)_LFLAGS += -lamrnb +endif +endif +endif +endif + + +ifneq ($(shell [ -f $(SYSROOT_ALT)/include/opencore-amrwb/enc_if.h ] && \ + echo 1 ),) +CFLAGS += -DAMR_WB=1 -I$(SYSROOT_ALT)/include/opencore-amrwb +$(MOD)_LFLAGS += -lopencore-amrwb +else +ifneq ($(shell [ -f $(SYSROOT)/local/include/amrwb/enc_if.h ] && echo 1),) +CFLAGS += -DAMR_WB=1 -I$(SYSROOT)/local/include/amrwb +$(MOD)_LFLAGS += -lamrwb +else +ifneq ($(shell [ -f $(SYSROOT)/include/amrwb/enc_if.h ] && echo 1),) +CFLAGS += -DAMR_WB=1 -I$(SYSROOT)/include/amrwb +$(MOD)_LFLAGS += -lamrwb +else +ifneq ($(shell [ -f $(SYSROOT)/include/vo-amrwbenc/enc_if.h ] && echo 1),) +CFLAGS += -DAMR_WB=1 -I$(SYSROOT)/include/vo-amrwbenc +$(MOD)_LFLAGS += -lvo-amrwbenc +endif +endif +endif +endif + + +# extra for decoder +ifneq ($(shell [ -f $(SYSROOT)/include/opencore-amrwb/dec_if.h ] && echo 1 ),) +CFLAGS += -I$(SYSROOT)/include/opencore-amrwb +$(MOD)_LFLAGS += -lopencore-amrwb +endif + + +$(MOD)_LFLAGS += -lm + + +include mk/mod.mk -- cgit v1.2.3