diff options
author | Alfred E. Heggestad <aeh@db.org> | 2015-06-19 19:20:47 +0200 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2015-06-19 19:20:47 +0200 |
commit | fb624cb2e74ec627c0dd52e0f5eab725d0345601 (patch) | |
tree | 8814a50947ea1ec2f370633e830645f71993b836 | |
parent | fef6933d984b4a304c2e8f33163e046de54eb2c5 (diff) |
added new module CODEC2
-rw-r--r-- | modules/codec2/codec2.c | 201 | ||||
-rw-r--r-- | modules/codec2/module.mk | 11 |
2 files changed, 212 insertions, 0 deletions
diff --git a/modules/codec2/codec2.c b/modules/codec2/codec2.c new file mode 100644 index 0000000..422adc9 --- /dev/null +++ b/modules/codec2/codec2.c @@ -0,0 +1,201 @@ +/** + * @file codec2.c CODEC2 audio codec + * + * Copyright (C) 2015 Creytiv.com + */ +#include <re.h> +#include <rem.h> +#include <baresip.h> +#include <codec2/codec2.h> + + +/** + * @defgroup codec2 codec2 + * + * The CODEC2 audio codec + * + * https://en.wikipedia.org/wiki/Codec2 + */ + + +enum { + CODEC2_MODE = CODEC2_MODE_2400 +}; + + +struct auenc_state { + struct CODEC2 *c2; +}; + +struct audec_state { + struct CODEC2 *c2; +}; + + +static void encode_destructor(void *data) +{ + struct auenc_state *st = data; + + if (st->c2) + codec2_destroy(st->c2); +} + + +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->c2 = codec2_create(CODEC2_MODE); + if (!st->c2) { + err = ENOMEM; + goto out; + } + + info("codec2: %d samples per frame, %d bits per frame\n", + codec2_samples_per_frame(st->c2), + codec2_bits_per_frame(st->c2)); + + out: + if (err) + mem_deref(st); + else + *aesp = st; + + return err; +} + + +static void decode_destructor(void *data) +{ + struct audec_state *st = data; + + if (st->c2) + codec2_destroy(st->c2); +} + + +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->c2 = codec2_create(CODEC2_MODE); + if (!st->c2) { + err = ENOMEM; + goto out; + } + + out: + if (err) + mem_deref(st); + else + *adsp = st; + + return err; +} + + +static int encode(struct auenc_state *aes, uint8_t *buf, + size_t *len, const int16_t *sampv, size_t sampc) +{ + if (!buf || !len || !sampv) + return EINVAL; + + if (*len < (size_t)codec2_bits_per_frame(aes->c2)/8) + return ENOMEM; + if (sampc != (size_t)codec2_samples_per_frame(aes->c2)) + return EPROTO; + + codec2_encode(aes->c2, buf, (short *)sampv); + + *len = codec2_bits_per_frame(aes->c2)/8; + + return 0; +} + + +static int decode(struct audec_state *ads, int16_t *sampv, + size_t *sampc, const uint8_t *buf, size_t len) +{ + if (!sampv || !sampc || !buf) + return EINVAL; + + if (*sampc < (size_t)codec2_samples_per_frame(ads->c2)) + return ENOMEM; + if (len < (size_t)codec2_bits_per_frame(ads->c2)/8) + return EPROTO; + + codec2_decode(ads->c2, sampv, buf); + + *sampc = codec2_samples_per_frame(ads->c2); + + return 0; +} + + +static struct aucodec codec2 = { + LE_INIT, + NULL, + "CODEC2", + 8000, + 1, + NULL, + encode_update, + encode, + decode_update, + decode, + NULL, + NULL, + NULL +}; + + +static int module_init(void) +{ + aucodec_register(&codec2); + + return 0; +} + + +static int module_close(void) +{ + aucodec_unregister(&codec2); + + return 0; +} + + +EXPORT_SYM const struct mod_export DECL_EXPORTS(codec2) = { + "codec2", + "audio codec", + module_init, + module_close, +}; diff --git a/modules/codec2/module.mk b/modules/codec2/module.mk new file mode 100644 index 0000000..2d4d5d8 --- /dev/null +++ b/modules/codec2/module.mk @@ -0,0 +1,11 @@ +# +# module.mk +# +# Copyright (C) 2010 Creytiv.com +# + +MOD := codec2 +$(MOD)_SRCS += codec2.c +$(MOD)_LFLAGS += -lcodec2 + +include mk/mod.mk |