Added handling of channel mode modify messages for AMR
diff --git a/lib/decoding/tch_f_decoder_impl.cc b/lib/decoding/tch_f_decoder_impl.cc
index 3ec7205..a3b09fb 100644
--- a/lib/decoding/tch_f_decoder_impl.cc
+++ b/lib/decoding/tch_f_decoder_impl.cc
@@ -68,7 +68,7 @@
         {
             throw std::runtime_error("TCH/F Decoder: can't open file\n");
         }
-        
+
         const unsigned char amr_nb_magic[6] = { 0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a };
 
         if (d_tch_mode != TCH_FS)
@@ -163,6 +163,56 @@
                     pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob);
 
                     message_port_pub(pmt::mp("msgs"), msg_out);
+
+                    // if we are in an AMR-mode and we receive a channel mode modify message,
+                    // we set the mode according to the multirate configuration from the message
+                    // see GSM 04.18, section 9.1.5 and 10.5.2.21aa
+                    if (d_tch_mode  != TCH_FS && d_tch_mode != TCH_EFR)
+                    {
+                        if (outmsg[3] == 0x06 && outmsg[4] == 0x10)
+                        {
+                            // Verify that multirate version 1 is set
+                            if ((outmsg[11] >> 5) == 1)
+                            {
+                                // the set of active codecs, max 4 modes
+                                // active_codec_set[0] corresponds to CODEC_MODE_1 with lowest bit rate
+                                // active_codec_set[3] corresponds to CODEC_MODE_4 with highest bit rate
+                                tch_mode active_codec_set[4];
+                                uint8_t mode_count = 0;
+                                for (i = 0; i<8; i++)
+                                {
+                                    if (((outmsg[12] >> i) & 0x1) == 1 && mode_count < 4)
+                                    {
+                                        active_codec_set[mode_count++] = static_cast<tch_mode>(7-i);
+                                    }
+                                }
+
+                                // check Initial Codec Mode Indicator ICMI
+                                // if ICMI == 1, then use the one defined in start mode field
+                                // else use implicit rule defined in GSM 05.09, section 3.4.3
+                                if (((outmsg[11] >> 3) & 0x1) == 1)
+                                {
+                                    // from start field
+                                    setCodingMode(active_codec_set[ (outmsg[11] & 0x3) ]);
+                                }
+                                else
+                                {
+                                    // implicit mode
+                                    // if the set contains only 1 codec, we use that one
+                                    // else if there are 2 or 3 codecs in the set, we use the one with lowest bitrate
+                                    if (mode_count >= 1 && mode_count <= 3)
+                                    {
+                                        setCodingMode(active_codec_set[0]);
+                                    }
+                                    // if there are 4 codecs in the set, we use the second lowest bitrate
+                                    else if (mode_count == 4)
+                                    {
+                                        setCodingMode(active_codec_set[1]);
+                                    }
+                                }
+                            }
+                        }
+                    }
                 }
             }
 
@@ -302,8 +352,9 @@
 
     void tch_f_decoder_impl::setCodingMode(tch_mode mode)
     {
-        if (d_tch_mode  != TCH_FS && d_tch_mode != TCH_EFR)
+        if (mode  != TCH_FS && d_tch_mode != TCH_EFR)
         {
+            d_tch_mode = mode;
             mKd = GSM::gAMRKd[d_tch_mode];
             mTCHD.resize(mKd);
             mTCHU.resize(mKd+6);