Add AMR codec, for supporting EFR transcoding
The AMR codec is added, but at this point only EFR payload is supported.
This commit is contained in:
parent
71066559a8
commit
9b2cabced4
|
@ -69,6 +69,14 @@ SUBDIRS += libgsmfr
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ENABLE_GSMAMR
|
||||||
|
|
||||||
|
GSM_INCLUDE += -DWITH_GSMAMR
|
||||||
|
|
||||||
|
GSM_LIB += -lopencore-amrnb
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
GSM_SOURCE += gsm_audio.c gsm.cpp
|
GSM_SOURCE += gsm_audio.c gsm.cpp
|
||||||
|
|
||||||
if ENABLE_GSM_BS
|
if ENABLE_GSM_BS
|
||||||
|
@ -86,6 +94,7 @@ GSM_INCLUDE += -DWITH_GSM_MS
|
||||||
GSM_SOURCE += gsm_ms.cpp
|
GSM_SOURCE += gsm_ms.cpp
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,14 @@ AM_CONDITIONAL(ENABLE_GSM_MS, test "x$with_gsm_ms" == "xyes" )
|
||||||
|
|
||||||
AM_CONDITIONAL(ENABLE_GSM, test "x$with_gsm_bs" == "xyes" -o "x$with_gsm_ms" == "xyes")
|
AM_CONDITIONAL(ENABLE_GSM, test "x$with_gsm_bs" == "xyes" -o "x$with_gsm_ms" == "xyes")
|
||||||
|
|
||||||
|
# check for opencore-amrnb for AMR and EFR decoding
|
||||||
|
found_opencore_amrnb=yes
|
||||||
|
PKG_CHECK_MODULES(OPENCORE_AMRNB, opencore-amrnb >= 0.1.0, , found_opencore_amrnb=no)
|
||||||
|
AM_CONDITIONAL(ENABLE_GSMAMR, test "$found_opencore_amrnb" = "yes")
|
||||||
|
if test "$found_opencore_amrnb" = yes; then
|
||||||
|
AC_DEFINE(HAVE_OPENCORE_AMRNB, 1, [Define to 1 if OpenCore AMR-NB library is available])
|
||||||
|
fi
|
||||||
|
|
||||||
# check for ss5
|
# check for ss5
|
||||||
AC_ARG_WITH([ss5],
|
AC_ARG_WITH([ss5],
|
||||||
[AS_HELP_STRING([--with-ss5],
|
[AS_HELP_STRING([--with-ss5],
|
||||||
|
@ -247,6 +255,7 @@ AC_OUTPUT
|
||||||
AS_IF([test "x$with_misdn" == xyes],[AC_MSG_NOTICE( Compiled with mISDN support )],[AC_MSG_NOTICE( Not compiled with mISDN support)])
|
AS_IF([test "x$with_misdn" == xyes],[AC_MSG_NOTICE( Compiled with mISDN support )],[AC_MSG_NOTICE( Not compiled with mISDN support)])
|
||||||
AS_IF([test "x$with_gsm_bs" == xyes],[AC_MSG_NOTICE( Compiled with GSM network side support )],[AC_MSG_NOTICE( Not compiled with GSM network side support)])
|
AS_IF([test "x$with_gsm_bs" == xyes],[AC_MSG_NOTICE( Compiled with GSM network side support )],[AC_MSG_NOTICE( Not compiled with GSM network side support)])
|
||||||
AS_IF([test "x$with_gsm_ms" == xyes],[AC_MSG_NOTICE( Compiled with GSM mobile side support )],[AC_MSG_NOTICE( Not compiled with GSM mobile side support)])
|
AS_IF([test "x$with_gsm_ms" == xyes],[AC_MSG_NOTICE( Compiled with GSM mobile side support )],[AC_MSG_NOTICE( Not compiled with GSM mobile side support)])
|
||||||
|
AS_IF([test "x$found_opencore_amrnb" == xyes],[AC_MSG_NOTICE( Compiled with GSM AMR codec support )],[AC_MSG_NOTICE( Not compiled with GSM AMR codec support)])
|
||||||
AS_IF([test "x$with_asterisk" == xyes],[AC_MSG_NOTICE( Compiled with Asterisk channel driver support )],[AC_MSG_NOTICE( Not compiled with Asterisk channel driver support)])
|
AS_IF([test "x$with_asterisk" == xyes],[AC_MSG_NOTICE( Compiled with Asterisk channel driver support )],[AC_MSG_NOTICE( Not compiled with Asterisk channel driver support)])
|
||||||
AS_IF([test "x$with_ss5" == xyes],[AC_MSG_NOTICE( Compiled with CCITT No.5 support )],[AC_MSG_NOTICE( Not compiled with CCITT No.5 support)])
|
AS_IF([test "x$with_ss5" == xyes],[AC_MSG_NOTICE( Compiled with CCITT No.5 support )],[AC_MSG_NOTICE( Not compiled with CCITT No.5 support)])
|
||||||
AS_IF([test "x$with_sip" == xyes],[AC_MSG_NOTICE( Compiled with SIP support )],[AC_MSG_NOTICE( Not compiled with SIP support)])
|
AS_IF([test "x$with_sip" == xyes],[AC_MSG_NOTICE( Compiled with SIP support )],[AC_MSG_NOTICE( Not compiled with SIP support)])
|
||||||
|
|
91
gsm.cpp
91
gsm.cpp
|
@ -193,6 +193,14 @@ Pgsm::Pgsm(int type, char *portname, struct port_settings *settings, struct inte
|
||||||
PERROR("Failed to create GSM FR codec instance\n");
|
PERROR("Failed to create GSM FR codec instance\n");
|
||||||
trigger_work(&p_g_delete);
|
trigger_work(&p_g_delete);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_GSMAMR
|
||||||
|
p_g_amr_decoder = gsm_amr_create();
|
||||||
|
p_g_amr_encoder = gsm_amr_create();
|
||||||
|
if (!p_g_amr_encoder || !p_g_amr_decoder) {
|
||||||
|
PERROR("Failed to create GSM AMR codec instance\n");
|
||||||
|
trigger_work(&p_g_delete);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
p_g_rxpos = 0;
|
p_g_rxpos = 0;
|
||||||
p_g_tch_connected = 0;
|
p_g_tch_connected = 0;
|
||||||
|
@ -225,6 +233,13 @@ Pgsm::~Pgsm()
|
||||||
if (p_g_fr_decoder)
|
if (p_g_fr_decoder)
|
||||||
gsm_fr_destroy(p_g_fr_decoder);
|
gsm_fr_destroy(p_g_fr_decoder);
|
||||||
//#endif
|
//#endif
|
||||||
|
#ifdef WITH_GSMAMR
|
||||||
|
/* close codec */
|
||||||
|
if (p_g_amr_encoder)
|
||||||
|
gsm_amr_destroy(p_g_amr_encoder);
|
||||||
|
if (p_g_amr_decoder)
|
||||||
|
gsm_amr_destroy(p_g_amr_decoder);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,6 +255,14 @@ void Pgsm::frame_receive(void *arg)
|
||||||
|
|
||||||
switch (frame->msg_type) {
|
switch (frame->msg_type) {
|
||||||
case GSM_TCHF_FRAME:
|
case GSM_TCHF_FRAME:
|
||||||
|
if (p_g_media_type != MEDIA_TYPE_GSM) {
|
||||||
|
PERROR("FR frame, but current media type mismatches.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!p_g_fr_decoder) {
|
||||||
|
PERROR("FR frame, but decoder not created.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ((frame->data[0]>>4) != 0xd) {
|
if ((frame->data[0]>>4) != 0xd) {
|
||||||
PDEBUG(DEBUG_GSM, "received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
|
PDEBUG(DEBUG_GSM, "received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
|
||||||
goto bfi;
|
goto bfi;
|
||||||
|
@ -250,6 +273,25 @@ void Pgsm::frame_receive(void *arg)
|
||||||
for (i = 0; i < 160; i++) {
|
for (i = 0; i < 160; i++) {
|
||||||
data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
|
data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case GSM_TCHF_FRAME_EFR:
|
||||||
|
if (p_g_media_type != MEDIA_TYPE_GSM_EFR) {
|
||||||
|
PERROR("EFR frame, but current media type mismatches.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!p_g_amr_decoder) {
|
||||||
|
PERROR("EFR frame, but decoder not created.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((frame->data[0]>>4) != 0xc)
|
||||||
|
goto bfi;
|
||||||
|
#ifdef WITH_GSMAMR
|
||||||
|
/* decode */
|
||||||
|
gsm_efr_decode(p_g_amr_decoder, frame->data, p_g_samples);
|
||||||
|
for (i = 0; i < 160; i++) {
|
||||||
|
data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case GSM_BAD_FRAME:
|
case GSM_BAD_FRAME:
|
||||||
|
@ -317,28 +359,47 @@ int Pgsm::audio_send(unsigned char *data, int len)
|
||||||
/* write to rx buffer */
|
/* write to rx buffer */
|
||||||
while(len--) {
|
while(len--) {
|
||||||
p_g_rxdata[p_g_rxpos++] = audio_law_to_s32[*data++];
|
p_g_rxdata[p_g_rxpos++] = audio_law_to_s32[*data++];
|
||||||
if (p_g_rxpos == 160) {
|
if (p_g_rxpos != 160)
|
||||||
p_g_rxpos = 0;
|
continue;
|
||||||
|
p_g_rxpos = 0;
|
||||||
|
|
||||||
|
switch (p_g_media_type) {
|
||||||
|
case MEDIA_TYPE_GSM:
|
||||||
|
if (!p_g_fr_encoder) {
|
||||||
|
PERROR("FR frame, but encoder not created.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef WITH_GSMFR
|
#ifdef WITH_GSMFR
|
||||||
/* encode data */
|
/* encode data */
|
||||||
gsm_fr_encode(p_g_fr_encoder, p_g_rxdata, frame);
|
gsm_fr_encode(p_g_fr_encoder, p_g_rxdata, frame);
|
||||||
frame_send(frame);
|
frame_send(frame, 33, GSM_TCHF_FRAME);
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
|
case MEDIA_TYPE_GSM_EFR:
|
||||||
|
if (!p_g_amr_encoder) {
|
||||||
|
PERROR("EFR frame, but encoder not created.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef WITH_GSMAMR
|
||||||
|
/* encode data */
|
||||||
|
gsm_efr_encode(p_g_amr_encoder, p_g_rxdata, frame);
|
||||||
|
frame_send(frame, 31, GSM_TCHF_FRAME_EFR);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pgsm::frame_send(void *_frame)
|
void Pgsm::frame_send(void *_frame, int len, int msg_type)
|
||||||
{
|
{
|
||||||
unsigned char buffer[sizeof(struct gsm_data_frame) + 33];
|
unsigned char buffer[sizeof(struct gsm_data_frame) + len];
|
||||||
struct gsm_data_frame *frame = (struct gsm_data_frame *)buffer;
|
struct gsm_data_frame *frame = (struct gsm_data_frame *)buffer;
|
||||||
|
|
||||||
frame->msg_type = GSM_TCHF_FRAME;
|
frame->msg_type = msg_type;
|
||||||
frame->callref = p_g_callref;
|
frame->callref = p_g_callref;
|
||||||
memcpy(frame->data, _frame, 33);
|
memcpy(frame->data, _frame, len);
|
||||||
|
|
||||||
if (p_g_lcr_gsm) {
|
if (p_g_lcr_gsm) {
|
||||||
mncc_send(p_g_lcr_gsm, frame->msg_type, frame);
|
mncc_send(p_g_lcr_gsm, frame->msg_type, frame);
|
||||||
|
@ -391,7 +452,7 @@ void Pgsm::modify_lchan(int media_type)
|
||||||
{
|
{
|
||||||
struct gsm_mncc *mode;
|
struct gsm_mncc *mode;
|
||||||
|
|
||||||
/* already modified to that payload type */
|
/* already modified to that media type */
|
||||||
if (p_g_media_type == media_type)
|
if (p_g_media_type == media_type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -438,6 +499,9 @@ void Pgsm::call_proc_ind(unsigned int msg_type, unsigned int callref, struct gsm
|
||||||
send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
|
send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
|
||||||
p_g_tch_connected = 1;
|
p_g_tch_connected = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* modify to GSM FR (this is GSM user side only, so there is FR supported only) */
|
||||||
|
modify_lchan(MEDIA_TYPE_GSM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ALERTING INDICATION */
|
/* ALERTING INDICATION */
|
||||||
|
@ -461,6 +525,11 @@ void Pgsm::alert_ind(unsigned int msg_type, unsigned int callref, struct gsm_mnc
|
||||||
send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
|
send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
|
||||||
p_g_tch_connected = 1;
|
p_g_tch_connected = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* modify to GSM FR, if not already */
|
||||||
|
if (!p_g_media_type) {
|
||||||
|
modify_lchan(MEDIA_TYPE_GSM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CONNECT INDICATION */
|
/* CONNECT INDICATION */
|
||||||
|
@ -516,8 +585,14 @@ void Pgsm::setup_cnf(unsigned int msg_type, unsigned int callref, struct gsm_mnc
|
||||||
message->param.connectinfo.rtpinfo.media_types[0] = p_g_media_type;
|
message->param.connectinfo.rtpinfo.media_types[0] = p_g_media_type;
|
||||||
message->param.connectinfo.rtpinfo.payload_types[0] = p_g_payload_type;
|
message->param.connectinfo.rtpinfo.payload_types[0] = p_g_payload_type;
|
||||||
message->param.connectinfo.rtpinfo.payloads = 1;
|
message->param.connectinfo.rtpinfo.payloads = 1;
|
||||||
|
} else {
|
||||||
|
/* modify to GSM FR, if not already
|
||||||
|
* for network side, this should have been already happened */
|
||||||
|
if (!p_g_media_type)
|
||||||
|
modify_lchan(MEDIA_TYPE_GSM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (p_g_rtp_bridge) {
|
if (p_g_rtp_bridge) {
|
||||||
struct gsm_mncc_rtp *rtp;
|
struct gsm_mncc_rtp *rtp;
|
||||||
|
|
||||||
|
|
2
gsm.h
2
gsm.h
|
@ -64,7 +64,7 @@ class Pgsm : public Port
|
||||||
int p_g_rtp_media_types[8];
|
int p_g_rtp_media_types[8];
|
||||||
unsigned char p_g_rtp_payload_types[8];
|
unsigned char p_g_rtp_payload_types[8];
|
||||||
|
|
||||||
void frame_send(void *_frame);
|
void frame_send(void *_frame, int len, int msg_type);
|
||||||
void frame_receive(void *_frame);
|
void frame_receive(void *_frame);
|
||||||
int audio_send(unsigned char *data, int len);
|
int audio_send(unsigned char *data, int len);
|
||||||
int bridge_rx(unsigned char *data, int len);
|
int bridge_rx(unsigned char *data, int len);
|
||||||
|
|
171
gsm_audio.c
171
gsm_audio.c
|
@ -50,5 +50,176 @@ void gsm_fr_encode(void *arg, signed short *samples, unsigned char *frame)
|
||||||
gsm_encode((gsm)arg, (gsm_signal *)samples, (gsm_byte *)frame);
|
gsm_encode((gsm)arg, (gsm_signal *)samples, (gsm_byte *)frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_GSMAMR
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <opencore-amrnb/interf_dec.h>
|
||||||
|
#include <opencore-amrnb/interf_enc.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct codec_efr_state {
|
||||||
|
void *encoder;
|
||||||
|
void *decoder;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* create gsm instance */
|
||||||
|
void *gsm_amr_create(void)
|
||||||
|
{
|
||||||
|
struct codec_efr_state *st;
|
||||||
|
|
||||||
|
st = (struct codec_efr_state *)calloc(1, sizeof(*st));
|
||||||
|
if (!st)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
st->encoder = Encoder_Interface_init(0);
|
||||||
|
st->decoder = Decoder_Interface_init();
|
||||||
|
|
||||||
|
return (void *)st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free gsm instance */
|
||||||
|
void gsm_amr_destroy(void *arg)
|
||||||
|
{
|
||||||
|
struct codec_efr_state *st = (struct codec_efr_state *)arg;
|
||||||
|
|
||||||
|
Decoder_Interface_exit(st->decoder);
|
||||||
|
Encoder_Interface_exit(st->encoder);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Mode amr_mode[8] = {
|
||||||
|
MR475, /* 4.75 kbps */
|
||||||
|
MR515, /* 5.15 kbps */
|
||||||
|
MR59, /* 5.90 kbps */
|
||||||
|
MR67, /* 6.70 kbps */
|
||||||
|
MR74, /* 7.40 kbps */
|
||||||
|
MR795, /* 7.95 kbps */
|
||||||
|
MR102, /* 10.2 kbps */
|
||||||
|
MR122, /* 12.2 kbps */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* decode frame into samples, return error */
|
||||||
|
int gsm_amr_decode(void *arg, unsigned char *frame, signed short *samples)
|
||||||
|
{
|
||||||
|
struct codec_efr_state *st = (struct codec_efr_state *)arg;
|
||||||
|
|
||||||
|
Decoder_Interface_Decode(
|
||||||
|
st->decoder,
|
||||||
|
(const unsigned char*) frame + 1,
|
||||||
|
(short *) samples,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode samples into frame */
|
||||||
|
int gsm_amr_encode(void *arg, signed short *samples, unsigned char *frame, int mode)
|
||||||
|
{
|
||||||
|
struct codec_efr_state *st = (struct codec_efr_state *)arg;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = Encoder_Interface_Encode(
|
||||||
|
st->encoder,
|
||||||
|
amr_mode[mode],
|
||||||
|
(const short*) samples,
|
||||||
|
(unsigned char*) frame + 1,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
frame[0] = 0xf0; /* no request */
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned short gsm690_12_2_bitorder[244] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
|
||||||
|
19, 20, 21, 22, 24, 25, 26, 27, 28, 38,
|
||||||
|
141, 39, 142, 40, 143, 41, 144, 42, 145, 43,
|
||||||
|
146, 44, 147, 45, 148, 46, 149, 47, 97, 150,
|
||||||
|
200, 48, 98, 151, 201, 49, 99, 152, 202, 86,
|
||||||
|
136, 189, 239, 87, 137, 190, 240, 88, 138, 191,
|
||||||
|
241, 91, 194, 92, 195, 93, 196, 94, 197, 95,
|
||||||
|
198, 29, 30, 31, 32, 33, 34, 35, 50, 100,
|
||||||
|
153, 203, 89, 139, 192, 242, 51, 101, 154, 204,
|
||||||
|
55, 105, 158, 208, 90, 140, 193, 243, 59, 109,
|
||||||
|
162, 212, 63, 113, 166, 216, 67, 117, 170, 220,
|
||||||
|
36, 37, 54, 53, 52, 58, 57, 56, 62, 61,
|
||||||
|
60, 66, 65, 64, 70, 69, 68, 104, 103, 102,
|
||||||
|
108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
|
||||||
|
119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
|
||||||
|
163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
|
||||||
|
211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
|
||||||
|
222, 221, 73, 72, 71, 76, 75, 74, 79, 78,
|
||||||
|
77, 82, 81, 80, 85, 84, 83, 123, 122, 121,
|
||||||
|
126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
|
||||||
|
134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
|
||||||
|
180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
|
||||||
|
229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
|
||||||
|
237, 236, 96, 199,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* decode frame into samples, return error */
|
||||||
|
int gsm_efr_decode(void *arg, unsigned char *frame, signed short *samples)
|
||||||
|
{
|
||||||
|
struct codec_efr_state *st = (struct codec_efr_state *)arg;
|
||||||
|
unsigned char cod[32], bit;
|
||||||
|
int i, si;
|
||||||
|
|
||||||
|
cod[0] = 0x3c; /* good AMR 12,2 frame */
|
||||||
|
memset(cod + 1, 0, 31);
|
||||||
|
|
||||||
|
for (i = 0; i < 244; i++) {
|
||||||
|
si = gsm690_12_2_bitorder[i] + 4;
|
||||||
|
bit = (frame[si >> 3] >> (7 - (si & 7))) & 1;
|
||||||
|
cod[(i >> 3) + 1] |= (bit << (7 - (i & 7)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Decoder_Interface_Decode(
|
||||||
|
st->decoder,
|
||||||
|
(const unsigned char*) cod,
|
||||||
|
(short *) samples,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* encode samples into frame */
|
||||||
|
int gsm_efr_encode(void *arg, signed short *samples, unsigned char *frame)
|
||||||
|
{
|
||||||
|
struct codec_efr_state *st = (struct codec_efr_state *)arg;
|
||||||
|
int rv;
|
||||||
|
unsigned char cod[32], bit;
|
||||||
|
int i, di;
|
||||||
|
|
||||||
|
rv = Encoder_Interface_Encode(
|
||||||
|
st->encoder,
|
||||||
|
MR122,
|
||||||
|
(const short*) samples,
|
||||||
|
(unsigned char*) cod,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (cod[0] != 0x3c)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
frame[0] = 0xc0;
|
||||||
|
memset(frame + 1, 0, 30);
|
||||||
|
|
||||||
|
for (i = 0; i < 244; i++) {
|
||||||
|
di = gsm690_12_2_bitorder[i] + 4;
|
||||||
|
bit = (cod[(i >> 3) + 1] >> (7 - (i & 7))) & 1;
|
||||||
|
frame[di >> 3] |= (bit << (7 - (di & 7)));
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
||||||
|
|
11
gsm_audio.h
11
gsm_audio.h
|
@ -1,6 +1,17 @@
|
||||||
|
|
||||||
|
#ifdef WITH_GSMFR
|
||||||
void *gsm_fr_create(void);
|
void *gsm_fr_create(void);
|
||||||
void gsm_fr_destroy(void *arg);
|
void gsm_fr_destroy(void *arg);
|
||||||
int gsm_fr_decode(void *arg, unsigned char *frame, signed short *samples);
|
int gsm_fr_decode(void *arg, unsigned char *frame, signed short *samples);
|
||||||
void gsm_fr_encode(void *arg, signed short *samples, unsigned char *frame);
|
void gsm_fr_encode(void *arg, signed short *samples, unsigned char *frame);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_GSMAMR
|
||||||
|
void *gsm_amr_create(void);
|
||||||
|
void gsm_amr_destroy(void *arg);
|
||||||
|
int gsm_amr_decode(void *arg, unsigned char *frame, signed short *samples);
|
||||||
|
int gsm_amr_encode(void *arg, signed short *samples, unsigned char *frame, int mode);
|
||||||
|
int gsm_efr_decode(void *arg, unsigned char *frame, signed short *samples);
|
||||||
|
int gsm_efr_encode(void *arg, signed short *samples, unsigned char *frame);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ void Pgsm_ms::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_
|
||||||
epointlist_new(epoint->ep_serial);
|
epointlist_new(epoint->ep_serial);
|
||||||
|
|
||||||
/* modify lchan to GSM codec V1 */
|
/* modify lchan to GSM codec V1 */
|
||||||
modify_lchan(RTP_PT_GSM_FULL);
|
modify_lchan(MEDIA_TYPE_GSM);
|
||||||
|
|
||||||
/* send call proceeding */
|
/* send call proceeding */
|
||||||
gsm_trace_header(p_interface_name, this, MNCC_CALL_CONF_REQ, DIRECTION_OUT);
|
gsm_trace_header(p_interface_name, this, MNCC_CALL_CONF_REQ, DIRECTION_OUT);
|
||||||
|
|
Loading…
Reference in New Issue