diff --git a/lib/decoding/tch_h_decoder_impl.cc b/lib/decoding/tch_h_decoder_impl.cc
new file mode 100644
index 0000000..b7672e3
--- /dev/null
+++ b/lib/decoding/tch_h_decoder_impl.cc
@@ -0,0 +1,357 @@
+/* -*- c++ -*- */
+/*
+ * @file
+ * @author (C) 2018 by Vasil Velichkov <vvvelichkov@gmail.com>
+ * @section LICENSE
+ *
+ * Gr-gsm is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * Gr-gsm is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gr-gsm; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <grgsm/gsmtap.h>
+#include "tch_h_decoder_impl.h"
+
+extern "C" {
+#include "osmocom/gsm/protocol/gsm_04_08.h"
+#include "osmocom/coding/gsm0503_coding.h"
+}
+
+namespace gr {
+    namespace gsm {
+
+        static int ubits2sbits(ubit_t *ubits, sbit_t *sbits, int count)
+        {
+            int i;
+
+            for (i = 0; i < count; i++) {
+                if (*ubits == 0x23) {
+                    ubits++;
+                    sbits++;
+                    continue;
+                }
+                if ((*ubits++) & 1)
+                    *sbits++ = -127;
+                else
+                    *sbits++ = 127;
+            }
+
+            return count;
+        }
+
+
+        tch_h_decoder::sptr
+        tch_h_decoder::make(unsigned int sub_channel, std::string multi_rate, bool boundary_check)
+        {
+            return gnuradio::get_initial_sptr
+                (new tch_h_decoder_impl(sub_channel, multi_rate, boundary_check));
+        }
+
+        /*
+         * Constructor
+         */
+        tch_h_decoder_impl::tch_h_decoder_impl(unsigned int sub_channel, std::string multi_rate, bool boundary_check)
+            : gr::block("tch_h_decoder",
+                    gr::io_signature::make(0, 0, 0),
+                    gr::io_signature::make(0, 0, 0)),
+            d_collected_bursts_num(0),
+            d_tch_mode(TCH_HS),
+            d_sub_channel(sub_channel),
+            d_boundary_check(boundary_check),
+            d_boundary_decode(false),
+            d_header_sent(false),
+            d_ft(0),
+            d_cmr(0)
+        {
+            //setup input/output ports
+            message_port_register_in(pmt::mp("bursts"));
+            set_msg_handler(pmt::mp("bursts"), boost::bind(&tch_h_decoder_impl::decode, this, _1));
+            message_port_register_out(pmt::mp("msgs"));
+            message_port_register_out(pmt::mp("voice"));
+
+            if(multi_rate.length())
+            {
+                std::cout<<"multi_rate configuration: "<<multi_rate<<std::endl;
+                if (multi_rate.length() < 4 || multi_rate.length() % 2)
+                {
+                    throw std::invalid_argument("Invalid multi_rate hexstring");
+                }
+
+                std::vector<uint8_t> binary;
+                for (std::string::const_iterator it = multi_rate.begin();
+                        it != multi_rate.end(); it += 2)
+                {
+                    std::string byte(it, it + 2);
+                    char* end = NULL;
+                    errno = 0;
+                    uint8_t b = strtoul(byte.c_str(), &end, 16);
+                    if (errno != 0 || *end != '\0')
+                    {
+                        throw std::invalid_argument("Invalid multi_rate hexstring");
+                    }
+                    binary.push_back(b);
+                }
+
+                if (binary.size() < 2) {
+                    throw std::invalid_argument("The multi_rate is too short");
+                }
+
+                //GSM A-I/F DTAP - Assignment Command
+                //    Protocol Discriminator: Radio Resources Management messages (6)
+                //    DTAP Radio Resources Management Message Type: Assignment Command (0x2e)
+                //    Channel Description 2 - Description of the First Channel, after time
+                //    Power Command
+                //    Channel Mode - Mode of the First Channel(Channel Set 1)
+                //    MultiRate configuration
+                //        Element ID: 0x03
+                //        Length: 4
+                //        001. .... = Multirate speech version: Adaptive Multirate speech version 1 (1)
+                //        ...0 .... = NSCB: Noise Suppression Control Bit: Noise Suppression can be used (default) (0)
+                //        .... 1... = ICMI: Initial Codec Mode Indicator: The initial codec mode is defined by the Start Mode field (1)
+                //        .... ..00 = Start Mode: 0
+                //        0... .... = 12,2 kbit/s codec rate: is not part of the subset
+                //        .0.. .... = 10,2 kbit/s codec rate: is not part of the subset
+                //        ..0. .... = 7,95 kbit/s codec rate: is not part of the subset
+                //        ...1 .... = 7,40 kbit/s codec rate: is part of the subset
+                //        .... 0... = 6,70 kbit/s codec rate: is not part of the subset
+                //        .... .0.. = 5,90 kbit/s codec rate: is not part of the subset
+                //        .... ..0. = 5,15 kbit/s codec rate: is not part of the subset
+                //        .... ...1 = 4,75 kbit/s codec rate: is part of the subset
+                //        ..01 1010 = AMR Threshold: 13.0 dB (26)
+                //        0100 .... = AMR Hysteresis: 2.0 dB (4)
+
+                const uint8_t first = binary[0];
+                uint8_t multirate_speech_ver = (first >> 5) & 0x07;
+                if (multirate_speech_ver == 1)
+                {
+                    d_tch_mode = TCH_AFS4_75;
+                }
+                else if (multirate_speech_ver == 2)
+                {
+                    throw std::invalid_argument("Adaptive Multirate speech version 2 is not supported");
+                }
+                else
+                {
+                    throw std::invalid_argument("Multirate speech version");
+                }
+
+                bool ncsb = (first >> 4) & 0x01;
+                bool icmi = (first >> 3) & 0x01;
+                uint8_t start = first & 0x03;
+
+                const uint8_t codecs = binary[1];
+                for (int i = 0; i < 8; i++)
+                {
+                    if ((codecs >> i) & 1)
+                    {
+                        d_multi_rate_codes.push_back(i);
+                    }
+                }
+
+                std::cout<<"Enabled AMR Codecs:"<<std::endl;
+                for(std::vector<uint8_t>::const_iterator it = d_multi_rate_codes.begin();
+                        it != d_multi_rate_codes.end();
+                        it ++)
+                {
+                    switch(*it)
+                    {
+                        case 0:
+                            std::cout<<"4,75 kbit/s codec rate: is part of the subset"<<std::endl;
+                            break;
+                        case 1:
+                            std::cout<<"5,15 kbit/s codec rate: is part of the subset"<<std::endl;
+                            break;
+                        case 2:
+                            std::cout<<"6,90 kbit/s codec rate: is part of the subset"<<std::endl;
+                            break;
+                        case 3:
+                            std::cout<<"6,70 kbit/s codec rate: is part of the subset"<<std::endl;
+                            break;
+                        case 4:
+                            std::cout<<"7,40 kbit/s codec rate: is part of the subset"<<std::endl;
+                            break;
+                        case 5:
+                            std::cout<<"7,95 kbit/s codec rate: is part of the subset"<<std::endl;
+                            break;
+                        case 6:
+                            std::cout<<"12,2 kbit/s codec rate: is part of the subset"<<std::endl;
+                    }
+                }
+                if (d_multi_rate_codes.size() > 4) {
+                    throw std::invalid_argument("More then 4 multirate codes");
+                }
+            }
+        }
+
+        tch_h_decoder_impl::~tch_h_decoder_impl()
+        {
+        }
+
+        void tch_h_decoder_impl::decode(pmt::pmt_t msg)
+        {
+            d_bursts[d_collected_bursts_num++] = msg;
+            if (d_collected_bursts_num <= 7)
+            {
+                return;
+            }
+
+            gsmtap_hdr* header = (gsmtap_hdr*)(pmt::blob_data(pmt::cdr(msg)));
+            uint32_t frame_nr = be32toh(header->frame_number);
+            bool uplink_burst = (be16toh(header->arfcn) & 0x4000) ? true : false;
+
+            //TODO: Check in 3gpp specs which frames could contains facch/h frames
+            //and replace this ugly formula with table
+            int fn_is_odd = (((frame_nr - (uplink_burst ? 10 : 15)) % 26) >> 2) & 1;
+
+            ubit_t bursts_u[116 * 6] = {0}; //facch/h is 6 bursts
+
+            //reorganize data
+            for (int ii = 0; ii < 8; ii++)
+            {
+                //skip the 4th and 5th bursts
+                if (ii == 4 || ii == 5) continue;
+
+                int8_t* burst_bits = (int8_t*)(pmt::blob_data(pmt::cdr(d_bursts[ii])))+sizeof(gsmtap_hdr);
+
+                //copy 6th and 7th burst to 4th and 5th position
+                int n = ii < 6 ? ii : ii - 2;
+
+                memcpy(&bursts_u[n*116], &burst_bits[3],58);
+                memcpy(&bursts_u[n*116+58], &burst_bits[3+57+1+26],58);
+            }
+
+            //Convert to sbits
+            sbit_t bursts_s[116 * 6] = {0};
+            ubits2sbits(bursts_u, bursts_s, 116 * 6);
+
+            //Prepare burst for the next iteration by shifting them by 4
+            for (int ii = 0; ii < 4; ii++) {
+                d_bursts[ii] = d_bursts[ii + 4];
+            }
+            d_collected_bursts_num = 4;
+
+            uint8_t frameBuffer[64];
+            int frameLength = -1;
+            int n_errors, n_bits_total;
+
+            if (d_tch_mode == TCH_HS)
+            {
+                frameLength = gsm0503_tch_hr_decode(frameBuffer, bursts_s, fn_is_odd, &n_errors, &n_bits_total);
+            }
+            else
+            {
+                frameLength = gsm0503_tch_ahs_decode(frameBuffer, bursts_s, fn_is_odd,
+                        fn_is_odd, //int codec_mode_req,
+                        &d_multi_rate_codes.front(), d_multi_rate_codes.size(),
+                        &d_ft,
+                        &d_cmr,
+                        &n_errors, &n_bits_total);
+            }
+
+            if (frameLength < 12)
+            {
+                if (!d_boundary_check || d_boundary_decode) {
+                    std::cerr<<"Error! frame_nr:"<<frame_nr<<" mod26:"<<frame_nr%26
+                        <<" fn_is_odd:"<<fn_is_odd<<" length:"<<frameLength<<std::endl;
+                }
+                return;
+            }
+            else if (frameLength == GSM_MACBLOCK_LEN) //FACCH/H
+            {
+                pmt::pmt_t first_header_plus_burst = pmt::cdr(d_bursts[0]);
+                gsmtap_hdr* header = (gsmtap_hdr *)pmt::blob_data(first_header_plus_burst);
+                int8_t header_plus_data[sizeof(gsmtap_hdr)+frameLength];
+                memcpy(header_plus_data, header, sizeof(gsmtap_hdr));
+                memcpy(header_plus_data+sizeof(gsmtap_hdr), frameBuffer, frameLength);
+                ((gsmtap_hdr*)header_plus_data)->type = GSMTAP_TYPE_UM;
+
+                pmt::pmt_t msg_binary_blob = pmt::make_blob(header_plus_data, frameLength + sizeof(gsmtap_hdr));
+                pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob);
+
+                message_port_pub(pmt::mp("msgs"), msg_out);
+
+                // if d_boundary_check is enabled, we set d_boundary_decode to true, when a
+                // "Connect" or "Connect Acknowledge" message is received, and
+                // we set d_boundary_decode back to false, when "Release" message is received
+                if (d_boundary_check)
+                {
+                    // check if this is a call control message
+                    if ((frameBuffer[3] & 0x0f) == 0x03)
+                    {
+                        // Connect specified in GSM 04.08, 9.3.5
+                        if ((frameBuffer[4] & 0x3f) == 0x07)
+                        {
+                            d_boundary_decode = true;
+                        }
+                        // Connect Acknowledge specified in GSM 04.08, 9.3.6
+                        else if ((frameBuffer[4] & 0x3f) == 0x0f)
+                        {
+                            d_boundary_decode = true;
+                        }
+                        // Release specified in GSM 04.08, 9.3.18
+                        else if ((frameBuffer[4] & 0x3f) == 0x2d)
+                        {
+                            d_boundary_decode = false;
+                        }
+                    }
+                }
+                return;
+            }
+
+            if (!d_header_sent && d_tch_mode != TCH_HS)
+            {
+                const unsigned char amr_nb_magic[7] = "#!AMR\n";
+                message_port_pub(pmt::mp("voice"), pmt::cons(pmt::PMT_NIL, pmt::make_blob(amr_nb_magic, 6)));
+                d_header_sent = true;
+            }
+
+            if (!n_errors && (!d_boundary_check || d_boundary_decode))
+            {
+                //std::cerr<<"Voice frame_nr:"<<frame_nr<<" mod26:"<<frame_nr%26<<" is_odd:"<<fn_is_odd
+                //    <<" type:"<<(uint32_t)d_ft<<" cmr:"<<(uint32_t)d_cmr
+                //    <<" errors:"<<n_errors<<std::endl;
+
+                if (d_tch_mode != TCH_HS)
+                {
+                    //Move one byte to make space for the header
+                    memmove(frameBuffer + 1, frameBuffer, frameLength);
+                    //Add the AMR header
+                    switch(frameLength)
+                    {
+                        case 12: frameBuffer[0] = (0 << 3); break; //TCH/AHS4.75
+                        case 13: frameBuffer[0] = (1 << 3); break; //TCH/AHS5.15
+                        case 15: frameBuffer[0] = (2 << 3); break; //TCH/AHS5.9
+                        case 17: frameBuffer[0] = (3 << 3); break; //TCH/AHS6.7
+                        case 19: frameBuffer[0] = (4 << 3); break; //TCH/AHS7.4
+                        case 20: frameBuffer[0] = (5 << 3); break; //TCH/AHS7.95
+                        default: std::cerr<<"Unexpected voice frame length:"<<frameLength<<std::endl; return;
+                    }
+                    frameLength += 1;
+                }
+
+                //std::ostringstream out;
+                //out << "voice frame: ";
+                //for (int i = 0; i < frameLength; i++)
+                //    out << " " << (std::hex) << std::setw(2) << std::setfill('0') << (uint32_t)*(frameBuffer + i);
+                //std::cerr << out.str() << std::endl;
+                message_port_pub(pmt::mp("voice"), pmt::cons(pmt::PMT_NIL, pmt::make_blob(frameBuffer, frameLength)));
+            }
+        }
+    } /* namespace gsm */
+} /* namespace gr */
+
