Add GSM (libgsm) codec support

This commit is contained in:
Andreas Eversberg 2022-11-24 19:26:19 +01:00
parent 3265559164
commit 137c50a33f
6 changed files with 125 additions and 4 deletions

View File

@ -74,8 +74,13 @@ AC_SUBST(SYMBOL_VISIBILITY)
dnl Generate the output
AM_CONFIG_HEADER(config.h)
AC_CHECK_LIB([m], [main])
AC_CHECK_LIB([pthread], [main])
AC_CHECK_LIB([m], [main], [], [echo "Failed to find lib!" ; exit -1])
AC_CHECK_LIB([pthread], [main], [], [echo "Failed to find lib!" ; exit -1])
AC_ARG_WITH([gsm], [AS_HELP_STRING([--with-gsm], [compile with GSM codec support @<:@default=check@:>@]) ], [], [with_gsm="check"])
AS_IF([test "x$with_gsm" != xno], [AC_CHECK_LIB([gsm], [main], [with_gsm="yes"], [with_gsm="no"])])
AM_CONDITIONAL(HAVE_GSM, test "x$with_gsm" == "xyes" )
AS_IF([test "x$with_gsm" == "xyes"],[AC_MSG_NOTICE( Compiling with GSM codec support )], [AC_MSG_NOTICE( Compiling without GSM codec not found )])
AC_OUTPUT(
src/liboptions/Makefile

View File

@ -24,3 +24,13 @@ osmo_cc_router_LDADD = \
../libfilter/libfilter.a \
../libwave/libwave.a
if HAVE_GSM
AM_CPPFLAGS += -DHAVE_GSM
osmo_cc_router_SOURCES += \
gsm_codec.c
osmo_cc_router_LDADD += \
-lgsm
endif

View File

@ -75,6 +75,9 @@
#include "call.h"
#include "audio.h"
#include "display.h"
#ifdef HAVE_GSM
#include "gsm_codec.h"
#endif
call_t *call_list = NULL;
struct timer status_timer;
@ -85,7 +88,11 @@ static struct osmo_cc_helper_audio_codecs codecs_def[] = {
{ "PCMA", 8000, 1, g711_encode_alaw, g711_decode_alaw },
{ "PCMU", 8000, 1, g711_encode_ulaw, g711_decode_ulaw },
{ "telephone-event", 8000, 1, encode_te, decode_te },
/* non-default (selectable) codecs */
{ "L16", 8000, 1, encode_l16, decode_l16 },
#ifdef HAVE_GSM
{ "GSM", 8000, 1, gsm_fr_encode, gsm_fr_decode },
#endif
{ NULL, 0, 0, NULL, NULL},
};
@ -282,6 +289,10 @@ static call_relation_t *relation_create(call_t *call)
}
*relation_p = relation;
#ifdef HAVE_GSM
gsm_fr_create(relation);
#endif
PDEBUG(DROUTER, DEBUG_DEBUG, "%s Created new endpoint relation instance.\n", relation_name(relation));
return relation;
@ -312,6 +323,11 @@ static void relation_destroy(call_relation_t *relation)
}
*relation_p = relation->next;
#ifdef HAVE_GSM
if (relation->gsm_fr_encoder)
gsm_fr_destroy(relation);
#endif
PDEBUG(DROUTER, DEBUG_DEBUG, "%s Destroyed endpoint relation instance.\n", relation_name(relation));
free(relation);
@ -1287,8 +1303,8 @@ static int parse_params(int argc, char *argv[], struct command_def *command_def)
/* routing orders us to activate rtp proxy */
struct param_def param_rtp_proxy[] = {
{ .n = "orig-codecs", .o = param.orig_codecs, .d = "Define allowed codecs to be accepted by originating endpoint." },
{ .n = "term-codecs", .t = param.term_codecs, .d = "Define allowed codecs on terminating endpoint in order of preference." },
{ .n = "orig-codecs", .o = param.orig_codecs, .d = "Define allowed codecs to be accepted by originating endpoint. (codec1,[codec2[,...]])" },
{ .n = "term-codecs", .t = param.term_codecs, .d = "Define allowed codecs on terminating endpoint in order of preference. (codec1,[codec2[,...]])" },
{ .n = NULL }
};

View File

@ -37,6 +37,9 @@ typedef struct call_relation {
char id[256]; /* caller ID / dialing*/
enum call_state state; /* state for status display */
void *gsm_fr_encoder;/* instance for FR codec */
void *gsm_fr_decoder;
osmo_cc_session_t *cc_session;
int codec_negotiated;
struct osmo_cc_helper_audio_codecs orig_codecs[MAX_CODECS + 1]; /* codecs for originator */

81
src/router/gsm_codec.c Normal file
View File

@ -0,0 +1,81 @@
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <gsm.h>
#include "call.h"
#include "gsm_codec.h"
#include "../libdebug/debug.h"
/* create gsm instance */
int gsm_fr_create(call_relation_t *relation)
{
int value = 1;
gsm encoder, decoder;
encoder = gsm_create();
if (!encoder) {
fprintf(stderr, "gsm codec failed to intialize.\n");
abort();
}
gsm_option(encoder, 0/*GSM_OPT_WAV49*/, &value);
decoder = gsm_create();
if (!decoder) {
fprintf(stderr, "gsm codec failed to intialize.\n");
abort();
}
gsm_option(decoder, 0/*GSM_OPT_WAV49*/, &value);
relation->gsm_fr_encoder = encoder;
relation->gsm_fr_decoder = decoder;
return -ENOMEM;
}
/* free gsm instance */
void gsm_fr_destroy(call_relation_t *relation)
{
gsm_destroy((gsm)relation->gsm_fr_encoder);
gsm_destroy((gsm)relation->gsm_fr_decoder);
}
/* encode samples into frame */
void gsm_fr_encode(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len, void *priv)
{
call_relation_t *relation = (call_relation_t *)priv;
gsm_signal *src = (gsm_signal *)src_data;
gsm_byte *dst;
dst = malloc(33);
if (!dst)
return;
if (src_len / 2 != 160)
fprintf(stderr, "GSM encoder requires 160 samples per chunk! Please fix!\n");
else
gsm_encode((gsm)relation->gsm_fr_encoder, src, dst);
*dst_data = (uint8_t *)dst;
*dst_len = 33;
}
/* decode frame into samples */
void gsm_fr_decode(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len, void *priv)
{
call_relation_t *relation = (call_relation_t *)priv;
gsm_byte *src = (gsm_byte *)src_data;
gsm_signal *dst;
dst = malloc(160 * 2);
if (!dst)
return;
if (src_len != 33)
fprintf(stderr, "GSM decoder requires 33 bytes per chunk! Please fix!\n");
else
gsm_decode((gsm)relation->gsm_fr_decoder, src, dst);
*dst_data = (uint8_t *)dst;
*dst_len = 160 * 2;
}

6
src/router/gsm_codec.h Normal file
View File

@ -0,0 +1,6 @@
int gsm_fr_create(call_relation_t *relation);
void gsm_fr_destroy(call_relation_t *relation);
void gsm_fr_encode(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len, void *priv);
void gsm_fr_decode(uint8_t *src_data, int src_len, uint8_t **dst_data, int *dst_len, void *priv);