diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/codec_fr.c | 3 | ||||
-rw-r--r-- | src/ecu_fr.c | 78 | ||||
-rw-r--r-- | src/pq_ecu.c | 88 |
4 files changed, 175 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 50ffda4..8fdeff7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,6 +43,12 @@ libosmogapk_la_SOURCES = \ pq_file.c \ pq_alsa.c \ pq_rtp.c \ + pq_ecu.c \ + $(NULL) + +# ECU (Error Concealment Unit) implementation +libosmogapk_la_SOURCES += \ + ecu_fr.c \ $(NULL) # Formats implementation diff --git a/src/codec_fr.c b/src/codec_fr.c index eddbee6..75efeb7 100644 --- a/src/codec_fr.c +++ b/src/codec_fr.c @@ -83,6 +83,8 @@ codec_fr_decode(void *state, uint8_t *pcm, const uint8_t *cod, unsigned int cod_ #endif /* HAVE_LIBGSM */ +/* Forward declaration of ECU (Error Concealment Unit) function */ +int ecu_proc_fr(void *state, uint8_t *out, const uint8_t *in, unsigned int in_len); const struct osmo_gapk_codec_desc codec_fr_desc = { .type = CODEC_FR, @@ -97,4 +99,5 @@ const struct osmo_gapk_codec_desc codec_fr_desc = { .codec_encode = codec_fr_encode, .codec_decode = codec_fr_decode, #endif + .ecu_proc = ecu_proc_fr, }; diff --git a/src/ecu_fr.c b/src/ecu_fr.c new file mode 100644 index 0000000..db55fec --- /dev/null +++ b/src/ecu_fr.c @@ -0,0 +1,78 @@ +/* ECU (Error Concealment Unit) for FR */ + +/* + * This file is part of GAPK (GSM Audio Pocket Knife). + * + * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com> + * + * All Rights Reserved + * + * GAPK is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GAPK is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GAPK. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <string.h> +#include <assert.h> +#include <stdbool.h> + +#include <osmocom/gapk/codecs.h> +#include <osmocom/codec/ecu.h> + +int +ecu_proc_fr(void *_state, uint8_t *out, const uint8_t *in, unsigned int in_len) +{ + struct osmo_ecu_fr_state *state = (struct osmo_ecu_fr_state *) _state; + bool backup = false; + bool bfi = true; + int i, rc; + + assert(in_len == FR_CANON_LEN); + + /* Check if a frame is BFI */ + for (i = 1; i < in_len; i++) { + if (in[i] != 0x00) { + bfi = false; + break; + } + } + + /* We have got a good frame, nothing to do */ + if (!bfi) { + osmo_ecu_fr_reset(state, (uint8_t *) in); + memcpy(out, in, in_len); + return in_len; + } + + /* Check if ECU state contains a backup frame */ + for (i = 0; i < in_len; i++) { + if (state->frame_backup[i] != 0x00) { + backup = true; + break; + } + } + + /* There is no back-up frame */ + if (!backup) { + /* Copy BFI 'as-is' */ + memcpy(out, in, in_len); + return in_len; + } + + /* Attempt to perform error concealment */ + rc = osmo_ecu_fr_conceal(state, out); + if (rc) + return rc; + + return in_len; +} diff --git a/src/pq_ecu.c b/src/pq_ecu.c new file mode 100644 index 0000000..fad853c --- /dev/null +++ b/src/pq_ecu.c @@ -0,0 +1,88 @@ +/* ECU (Error Concealment Unit) */ + +/* + * This file is part of GAPK (GSM Audio Pocket Knife). + * + * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com> + * + * All Rights Reserved + * + * GAPK is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GAPK is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GAPK. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <talloc.h> +#include <errno.h> + +#include <osmocom/gapk/procqueue.h> +#include <osmocom/gapk/logging.h> +#include <osmocom/gapk/formats.h> +#include <osmocom/gapk/codecs.h> + +#include <osmocom/codec/ecu.h> + +static void +clean_up(void *state) +{ + talloc_free(state); +} + +/*! Add a ECU block to the processing queue + * (To be placed between frame source and decoder) + * \param pq Processing Queue to which the block is added + * \returns 0 on success; negative on error */ +int +osmo_gapk_pq_queue_ecu(struct osmo_gapk_pq *pq, + const struct osmo_gapk_codec_desc *codec) +{ + const struct osmo_gapk_format_desc *fmt; + struct osmo_gapk_pq_item *item; + + /* Make sure that a codec has corresponding ECU implementation */ + if (codec->ecu_proc == NULL) { + LOGPGAPK(LOGL_ERROR, "Codec '%s' has no ECU implementation\n", codec->name); + return -ENOTSUP; + } + + /* Allocate a new item to the processing queue */ + item = osmo_gapk_pq_add_item(pq); + if (!item) + return -ENOMEM; + + /* Allocate the ECU state */ + item->state = talloc_zero(item, struct osmo_ecu_fr_state); + if (!item->state) { + talloc_free(item); + return -ENOMEM; + } + + /* I/O signature shall match the input signature of a codec */ + fmt = osmo_gapk_fmt_get_from_type(codec->codec_dec_format_type); + item->len_in = fmt->frame_len; + item->len_out = fmt->frame_len; + + item->proc = codec->ecu_proc; + item->exit = &clean_up; + item->wait = NULL; + + /* Meta information */ + item->type = OSMO_GAPK_ITEM_TYPE_PROC; + item->cat_name = "ecu"; + item->sub_name = codec->name; + + LOGPGAPK(LOGL_DEBUG, "PQ '%s': Adding ECU for codec '%s', " + "format '%s'\n", pq->name, codec->name, fmt->name); + + return 0; +} |