Adding handling of bad GSM audio frames
authorAndreas Eversberg <jolly@eversberg.eu>
Fri, 20 Jan 2012 19:28:55 +0000 (20:28 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Fri, 20 Jan 2012 19:28:55 +0000 (20:28 +0100)
In this case the frame is dropped, but audio of the last frame is repeated
with a reduced level. The level is reduced again an again until a new
valid frame is received. This way there is no silent gap in the audio
stream.

gsm.cpp
gsm.h
gsm_bs.cpp
gsm_ms.cpp
mncc.h

diff --git a/gsm.cpp b/gsm.cpp
index 8e5a2d6..9bfa1a5 100644 (file)
--- a/gsm.cpp
+++ b/gsm.cpp
@@ -139,6 +139,7 @@ Pgsm::Pgsm(int type, char *portname, struct port_settings *settings, struct inte
        p_g_rtp_bridge = 0;
        if (interface->rtp_bridge)
                p_g_rtp_bridge = 1;
+       memset(&p_g_samples, 0, sizeof(p_g_samples));
        SCPY(p_g_interface_name, interface->name); 
        p_callerinfo.itype = (interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
        memset(&p_g_delete, 0, sizeof(p_g_delete));
@@ -193,22 +194,42 @@ Pgsm::~Pgsm()
 void Pgsm::frame_receive(void *arg)
 {
        struct gsm_data_frame *frame = (struct gsm_data_frame *)arg;
-       signed short samples[160];
        unsigned char data[160];
        int i;
 
        if (!p_g_decoder)
                return;
 
-       if ((frame->data[0]>>4) != 0xd)
-               PERROR("received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
+       if (frame->msg_type != GSM_TCHF_BAD_FRAME) {
+               if ((frame->data[0]>>4) != 0xd)
+                       PERROR("received GSM frame with wrong magig 0x%x\n", frame->data[0]>>4);
        
-       /* decode */
-       gsm_audio_decode(p_g_decoder, frame->data, samples);
-       for (i = 0; i < 160; i++) {
-               data[i] = audio_s16_to_law[samples[i] & 0xffff];
+               /* decode */
+               gsm_audio_decode(p_g_decoder, frame->data, p_g_samples);
+               for (i = 0; i < 160; i++) {
+                       data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+               }
+       } else if (p_echotest) {
+               /* beep on bad frame */
+               for (i = 0; i < 160; i++) {
+                       if ((i & 3) > 2)
+                               p_g_samples[i] = 15000;
+                       else
+                               p_g_samples[i] = -15000;
+                       data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+               }
+       } else {
+               /* repeat on bad frame */
+               for (i = 0; i < 160; i++) {
+                       p_g_samples[i] = (p_g_samples[i] * 14) >> 4;
+                       data[i] = audio_s16_to_law[p_g_samples[i] & 0xffff];
+               }
        }
 
+       /* local echo */
+       if (p_echotest)
+               bridge_rx(data, 160);
+
        /* send to remote*/
        bridge_tx(data, 160);
 }
diff --git a/gsm.h b/gsm.h
index 724a4c2..0ccac2b 100644 (file)
--- a/gsm.h
+++ b/gsm.h
@@ -35,6 +35,7 @@ class Pgsm : public Port
        ~Pgsm();
 
        char p_g_interface_name[64];
+       signed short p_g_samples[160]; /* last received audi packet */
        int p_g_tones; /* set, if tones are to be generated */
        int p_g_earlyb; /* set, if patterns are available */
        struct lcr_gsm *p_g_lcr_gsm; /* pointer to network/ms instance */
index 7748f7a..d062e3d 100644 (file)
@@ -396,7 +396,8 @@ int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
                port = port->next;
        }
 
-       if (msg_type == GSM_TCHF_FRAME) {
+       if (msg_type == GSM_TCHF_FRAME
+        || msg_type == GSM_TCHF_BAD_FRAME) {
                if (port) {
                        /* inject DTMF, if enabled */
                        if (pgsm_bs->p_g_dtmf) {
index cfb1bf6..bb2ad67 100644 (file)
@@ -345,7 +345,8 @@ int message_ms(struct lcr_gsm *gsm_ms, int msg_type, void *arg)
                port = port->next;
        }
 
-       if (msg_type == GSM_TCHF_FRAME) {
+       if (msg_type == GSM_TCHF_FRAME
+        || msg_type == GSM_TCHF_BAD_FRAME) {
                if (port)
                        pgsm_ms->frame_receive(arg);
                return 0;
diff --git a/mncc.h b/mncc.h
index 04b3241..4028b67 100644 (file)
--- a/mncc.h
+++ b/mncc.h
@@ -58,6 +58,7 @@
 
 #define GSM_TCHF_FRAME         0x0300
 #define GSM_TCHF_FRAME_EFR     0x0301
+#define GSM_TCHF_BAD_FRAME     0x03ff
 
 #define GSM_MAX_FACILITY       128
 #define GSM_MAX_SSVERSION      128