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
p_g_rxpos = 0;
p_g_tch_connected = 0;
p_g_media_type = 0;
if (p_g_fr_decoder)
gsm_fr_destroy(p_g_fr_decoder);
//#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
}
switch (frame->msg_type) {
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) {
PDEBUG(DEBUG_GSM, "received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
goto bfi;
}
#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
+ break;
case GSM_BAD_FRAME:
default:
bfi:
/* write to rx buffer */
while(len--) {
p_g_rxdata[p_g_rxpos++] = audio_law_to_s32[*data++];
- if (p_g_rxpos == 160) {
- p_g_rxpos = 0;
-
+ if (p_g_rxpos != 160)
+ 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
/* encode data */
gsm_fr_encode(p_g_fr_encoder, p_g_rxdata, frame);
- frame_send(frame);
+ frame_send(frame, 33, GSM_TCHF_FRAME);
+#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;
}
-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;
- frame->msg_type = GSM_TCHF_FRAME;
+ frame->msg_type = msg_type;
frame->callref = p_g_callref;
- memcpy(frame->data, _frame, 33);
+ memcpy(frame->data, _frame, len);
if (p_g_lcr_gsm) {
mncc_send(p_g_lcr_gsm, frame->msg_type, frame);
{
struct gsm_mncc *mode;
- /* already modified to that payload type */
+ /* already modified to that media type */
if (p_g_media_type == media_type)
return;
send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
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 */
send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
p_g_tch_connected = 1;
}
+
+ /* modify to GSM FR, if not already */
+ if (!p_g_media_type) {
+ modify_lchan(MEDIA_TYPE_GSM);
+ }
}
/* CONNECT INDICATION */
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.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) {
struct gsm_mncc_rtp *rtp;
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" */