summaryrefslogtreecommitdiff
path: root/modules/gsm
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-02-09 11:50:07 +0100
committerAlfred E. Heggestad <aeh@db.org>2014-02-09 11:50:07 +0100
commit98bf08bdcf2edd9d397f32650a8bfe62186fbecf (patch)
treeebc6ec71f44bff8c42e4eefced61948623df02fc /modules/gsm
parente6ad5cf4401b860ba402d4b7b3c7c254bc87a019 (diff)
baresip 0.4.10
Diffstat (limited to 'modules/gsm')
-rw-r--r--modules/gsm/gsm.c171
-rw-r--r--modules/gsm/module.mk12
2 files changed, 183 insertions, 0 deletions
diff --git a/modules/gsm/gsm.c b/modules/gsm/gsm.c
new file mode 100644
index 0000000..798bae7
--- /dev/null
+++ b/modules/gsm/gsm.c
@@ -0,0 +1,171 @@
+/**
+ * @file gsm.c GSM Audio Codec
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <gsm.h> /* please report if you have problems finding this file */
+#include <re.h>
+#include <baresip.h>
+
+
+enum {
+ FRAME_SIZE = 160
+};
+
+
+struct auenc_state {
+ gsm enc;
+};
+
+struct audec_state {
+ gsm dec;
+};
+
+
+static void encode_destructor(void *arg)
+{
+ struct auenc_state *st = arg;
+
+ gsm_destroy(st->enc);
+}
+
+
+static void decode_destructor(void *arg)
+{
+ struct audec_state *st = arg;
+
+ gsm_destroy(st->dec);
+}
+
+
+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)ac;
+ (void)prm;
+ (void)fmtp;
+
+ if (!aesp)
+ return EINVAL;
+ if (*aesp)
+ return 0;
+
+ st = mem_zalloc(sizeof(*st), encode_destructor);
+ if (!st)
+ return ENOMEM;
+
+ st->enc = gsm_create();
+ if (!st->enc) {
+ err = EPROTO;
+ goto out;
+ }
+
+ out:
+ 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)ac;
+ (void)fmtp;
+
+ if (!adsp)
+ return EINVAL;
+ if (*adsp)
+ return 0;
+
+ st = mem_zalloc(sizeof(*st), decode_destructor);
+ if (!st)
+ return ENOMEM;
+
+ st->dec = gsm_create();
+ if (!st->dec) {
+ err = EPROTO;
+ goto out;
+ }
+
+ out:
+ if (err)
+ mem_deref(st);
+ else
+ *adsp = st;
+
+ return err;
+}
+
+
+static int encode(struct auenc_state *st, uint8_t *buf, size_t *len,
+ const int16_t *sampv, size_t sampc)
+{
+ if (sampc != FRAME_SIZE)
+ return EPROTO;
+ if (*len < sizeof(gsm_frame))
+ return ENOMEM;
+
+ gsm_encode(st->enc, (gsm_signal *)sampv, buf);
+
+ *len = sizeof(gsm_frame);
+
+ return 0;
+}
+
+
+static int decode(struct audec_state *st, int16_t *sampv, size_t *sampc,
+ const uint8_t *buf, size_t len)
+{
+ int ret;
+
+ if (*sampc < FRAME_SIZE)
+ return ENOMEM;
+ if (len < sizeof(gsm_frame))
+ return EBADMSG;
+
+ ret = gsm_decode(st->dec, (gsm_byte *)buf, (gsm_signal *)sampv);
+ if (ret)
+ return EPROTO;
+
+ *sampc = 160;
+
+ return 0;
+}
+
+
+static struct aucodec ac_gsm = {
+ LE_INIT, "3", "GSM", 8000, 1, NULL,
+ encode_update, encode, decode_update, decode, NULL, NULL, NULL
+};
+
+
+static int module_init(void)
+{
+ debug("gsm: GSM v%u.%u.%u\n", GSM_MAJOR, GSM_MINOR, GSM_PATCHLEVEL);
+
+ aucodec_register(&ac_gsm);
+ return 0;
+}
+
+
+static int module_close(void)
+{
+ aucodec_unregister(&ac_gsm);
+ return 0;
+}
+
+
+EXPORT_SYM const struct mod_export DECL_EXPORTS(gsm) = {
+ "gsm",
+ "codec",
+ module_init,
+ module_close
+};
diff --git a/modules/gsm/module.mk b/modules/gsm/module.mk
new file mode 100644
index 0000000..48c8ff0
--- /dev/null
+++ b/modules/gsm/module.mk
@@ -0,0 +1,12 @@
+#
+# module.mk
+#
+# Copyright (C) 2010 Creytiv.com
+#
+
+MOD := gsm
+$(MOD)_SRCS += gsm.c
+$(MOD)_LFLAGS += -L$(SYSROOT)/lib -lgsm
+CFLAGS += -I$(SYSROOT)/include/gsm -I$(SYSROOT)/local/include
+
+include mk/mod.mk