Ejemplo n.º 1
0
        /*----------------------------------------------------------------*
         *  main decoder function
         *---------------------------------------------------------------*/

        void iLBC_decode(
                 float[] decblock,            /* (o) decoded signal block */
                 bitstream bytes,           /* (i) encoded signal bits */
                 int mode)                   /* (i) 0: bad packet, PLC,
                            1: normal */
        {
            float[] data = new float[ilbc_constants.BLOCKL_MAX];
            float[] lsfdeq = new float[ilbc_constants.LPC_FILTERORDER * ilbc_constants.LPC_N_MAX];
            float[] PLCresidual = new float[ilbc_constants.BLOCKL_MAX];
            float[] PLClpc = new float[ilbc_constants.LPC_FILTERORDER + 1];
            float[] zeros = new float[ilbc_constants.BLOCKL_MAX];
            float[] one = new float[ilbc_constants.LPC_FILTERORDER + 1];
            int k, i, start, idxForMax, /*pos,*/ lastpart, ulp;
            int lag, ilag;
            float cc, maxcc;
            int[] idxVec = new int[ilbc_constants.STATE_LEN];
            //    int check;
            int[] gain_index = new int[ilbc_constants.NASUB_MAX * ilbc_constants.CB_NSTAGES];
            int[] extra_gain_index = new int[ilbc_constants.CB_NSTAGES];
            int[] cb_index = new int[ilbc_constants.CB_NSTAGES * ilbc_constants.NASUB_MAX];
            int[] extra_cb_index = new int[ilbc_constants.CB_NSTAGES];
            int[] lsf_i = new int[ilbc_constants.LSF_NSPLIT * ilbc_constants.LPC_N_MAX];
            int state_first;
            int last_bit;
            //    unsigned char *pbytes;
            float[] weightdenum = new float[(ilbc_constants.LPC_FILTERORDER + 1) *
                               ilbc_constants.NSUB_MAX];
            int order_plus_one;
            float[] syntdenum = new float[ilbc_constants.NSUB_MAX * (ilbc_constants.LPC_FILTERORDER + 1)];
            float[] decresidual = new float[ilbc_constants.BLOCKL_MAX];

            if (mode > 0) { /* the data are good */

                /* decode data */

                //        pbytes=bytes;
                // pos=0;

                /* Set everything to zero before decoding */

                for (k = 0;k < ilbc_constants.LSF_NSPLIT * ilbc_constants.LPC_N_MAX;k++) {
                    lsf_i[k] = 0;
                }
                start = 0;
                state_first = 0;
                idxForMax = 0;
                for (k = 0;k < this.ULP_inst.state_short_len;k++) {
                    idxVec[k] = 0;
                }
                for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                    extra_cb_index[k] = 0;
                }
                for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                    extra_gain_index[k] = 0;
                }
                for (i = 0;i < this.ULP_inst.nasub;i++) {
                    for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                        cb_index[i * ilbc_constants.CB_NSTAGES + k] = 0;
                    }
                }
                for (i = 0;i < this.ULP_inst.nasub;i++) {
                    for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                        gain_index[i * ilbc_constants.CB_NSTAGES + k] = 0;
                    }
                }

                /* loop over ULP classes */

                for (ulp = 0;ulp < 3;ulp++) {

                    /* LSF */
                    for (k = 0;k < ilbc_constants.LSF_NSPLIT * this.ULP_inst.lpc_n;k++) {
                        lastpart = bytes.unpack(this.ULP_inst.lsf_bits[k, ulp]);
                        //             unpack( &pbytes, &lastpart,
                        //                 this.ULP_inst.lsf_bits[k,ulp], &pos);
                        lsf_i[k] = bytes.packcombine(lsf_i[k], lastpart,
                                     this.ULP_inst.lsf_bits[k, ulp]);
                        //            System.out.println("lsf_i["+k+"] = " + lsf_i[k]);
                        //             packcombine(&lsf_i[k], lastpart,
                        //                 this.ULP_inst.lsf_bits[k,ulp]);
                    }

                    /* Start block info */

                    lastpart = bytes.unpack(this.ULP_inst.start_bits[ulp]);
                    //         unpack( &pbytes, &lastpart,
                    //             this.ULP_inst.start_bits[ulp], &pos);
                    start = bytes.packcombine(start, lastpart,
                                this.ULP_inst.start_bits[ulp]);
                    //        System.out.println("start = " + start);
                    //         packcombine(&start, lastpart,
                    //                 this.ULP_inst.start_bits[ulp]);

                    lastpart = bytes.unpack(this.ULP_inst.startfirst_bits[ulp]);
                    //         unpack( &pbytes, &lastpart,
                    //             this.ULP_inst.startfirst_bits[ulp], &pos);
                    state_first = bytes.packcombine(state_first, lastpart,
                                    this.ULP_inst.startfirst_bits[ulp]);
                    //        System.out.println("state_first = " + state_first);
                    //         packcombine(&state_first, lastpart,
                    //                 this.ULP_inst.startfirst_bits[ulp]);

                    lastpart = bytes.unpack(this.ULP_inst.scale_bits[ulp]);
                    //         unpack( &pbytes, &lastpart,
                    //             this.ULP_inst.scale_bits[ulp], &pos);
                    idxForMax = bytes.packcombine(idxForMax, lastpart,
                                      this.ULP_inst.scale_bits[ulp]);
                    //        System.out.println("idxForMax = " + idxForMax);
                    //         packcombine(&idxForMax, lastpart,
                    //                 this.ULP_inst.scale_bits[ulp]);

                    for (k = 0;k < this.ULP_inst.state_short_len;k++) {
                        lastpart = bytes.unpack(this.ULP_inst.state_bits[ulp]);
                        //             unpack( &pbytes, &lastpart,
                        //                 this.ULP_inst.state_bits[ulp], &pos);
                        idxVec[k] = bytes.packcombine(idxVec[k], lastpart,
                                      this.ULP_inst.state_bits[ulp]);
                        //            System.out.println("idxVec["+k+"] = " + idxVec[k]);
                        //             packcombine(idxVec+k, lastpart,
                        //                 this.ULP_inst.state_bits[ulp]);
                    }

                    /* 23/22 (20ms/30ms) sample block */

                    for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                        lastpart = bytes.unpack(this.ULP_inst.extra_cb_index[k, ulp]);
                        //             unpack( &pbytes, &lastpart,
                        //                 this.ULP_inst.extra_cb_index[k,ulp],
                        //                 &pos);
                        extra_cb_index[k] = bytes.packcombine(extra_cb_index[k], lastpart,
                                          this.ULP_inst.extra_cb_index[k, ulp]);
                        //            System.out.println("extra_cb_index["+k+"] = " + extra_cb_index[k]);
                        //             packcombine(extra_cb_index+k, lastpart,
                        //                 this.ULP_inst.extra_cb_index[k,ulp]);
                    }
                    for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                        lastpart = bytes.unpack(this.ULP_inst.extra_cb_gain[k, ulp]);
                        //             unpack( &pbytes, &lastpart,
                        //                 this.ULP_inst.extra_cb_gain[k,ulp],
                        //                 &pos);
                        extra_gain_index[k] = bytes.packcombine(extra_gain_index[k], lastpart,
                                            this.ULP_inst.extra_cb_gain[k, ulp]);
                        //            System.out.println("extra_gain_index["+k+"] = " + extra_gain_index[k]);
                        //             packcombine(extra_gain_index+k, lastpart,
                        //                 this.ULP_inst.extra_cb_gain[k,ulp]);
                    }

                    /* The two/four (20ms/30ms) 40 sample sub-blocks */

                    for (i = 0;i < this.ULP_inst.nasub;i++) {
                        for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                            lastpart = bytes.unpack(this.ULP_inst.cb_index[i, k, ulp]);
                            //             unpack( &pbytes, &lastpart,
                            //                 this.ULP_inst.cb_index[i,k,ulp],
                            //                 &pos);
                            cb_index[i * ilbc_constants.CB_NSTAGES + k] =
                                bytes.packcombine(cb_index[i * ilbc_constants.CB_NSTAGES + k], lastpart,
                                          this.ULP_inst.cb_index[i, k, ulp]);
                            //            System.out.println("cb_index["+(i*ilbc_constants.CB_NSTAGES+k)+"] = " + cb_index[(i*ilbc_constants.CB_NSTAGES+k)]);
                            //             packcombine(cb_index+i*CB_NSTAGES+k, lastpart,
                            //                     this.ULP_inst.cb_index[i,k,ulp]);
                        }
                    }

                    for (i = 0;i < this.ULP_inst.nasub;i++) {
                        for (k = 0;k < ilbc_constants.CB_NSTAGES;k++) {
                            lastpart = bytes.unpack(this.ULP_inst.cb_gain[i, k, ulp]);
                            gain_index[i * ilbc_constants.CB_NSTAGES + k] =
                                bytes.packcombine(gain_index[i * ilbc_constants.CB_NSTAGES + k], lastpart,
                                          this.ULP_inst.cb_gain[i, k, ulp]);
                            //            System.out.println("gain_index["+(i*ilbc_constants.CB_NSTAGES+k)+"] = " + gain_index[(i*ilbc_constants.CB_NSTAGES+k)]);
                        }
                    }
                }
                /* Extract last bit. If it is 1 this indicates an
                   empty/lost frame */
                last_bit = bytes.unpack(1);
                //        System.out.println("last_bit = "  + last_bit);

                /* Check for bit errors or empty/lost frames */
                if (start < 1)
                    mode = 0;
                if (this.ULP_inst.mode == 20 && start > 3)
                    mode = 0;
                if (this.ULP_inst.mode == 30 && start > 5)
                    mode = 0;
                if (last_bit == 1)
                    mode = 0;

                if (mode == 1) { /* No bit errors was detected,
                  continue decoding */

                    /* adjust index */
                    index_conv_dec(cb_index);

                    //         for (int li = 0; li < cb_index.Length; li++)
                    //             System.out.println("cb_index["+li+"] = " + cb_index[li]);

                    /* decode the lsf */

                    SimplelsfDEQ(lsfdeq, lsf_i, this.ULP_inst.lpc_n);
                    //         for (int li = 0; li < lsfdeq.Length; li++)
                    //             System.out.println("lsfdeq["+li+"] = " + lsfdeq[li]);
                    ilbc_common.LSF_check(lsfdeq, ilbc_constants.LPC_FILTERORDER,
                            this.ULP_inst.lpc_n);
                    //        check=ilbc_common.LSF_check(lsfdeq, ilbc_constants.LPC_FILTERORDER,
                    //                this.ULP_inst.lpc_n);
                    //         System.out.println("check returns " + check);
                    DecoderInterpolateLSF(syntdenum, weightdenum,
                                  lsfdeq, ilbc_constants.LPC_FILTERORDER);
                    //         for (int li = 0; li < syntdenum.Length; li++)
                    //             System.out.println("syntdenum[" + li + "] = " + syntdenum[li]);
                    //         for (int li = 0; li < weightdenum.Length; li++)
                    //             System.out.println("weightdenum[" + li + "] = " + weightdenum[li]);

                    Decode(decresidual, start, idxForMax,
                           idxVec, syntdenum, cb_index, gain_index,
                           extra_cb_index, extra_gain_index,
                           state_first);

                    //         for (int li = 0; li < decresidual.Length; li++)
                    //             System.out.println("decresidual[" + li + "] = " + decresidual[li]);

                    /* preparing the plc for a future loss! */

                    doThePLC(PLCresidual, PLClpc, 0, decresidual,
                         syntdenum,
                         (ilbc_constants.LPC_FILTERORDER + 1) * (this.ULP_inst.nsub - 1),
                         last_lag);

                    System.Array.Copy(PLCresidual, 0, decresidual, 0, this.ULP_inst.blockl);
                    //         for (int li = 0; li < decresidual.Length; li++)
                    //             System.out.println("decresidual[" + li + "] = " + decresidual[li]);
                    //         memcpy(decresidual, PLCresidual,
                    //                this.ULP_inst.blockl*sizeof(float));
                }

            }

            if (mode == 0) {
                /* the data is bad (either a PLC call
                 * was made or a severe bit error was detected)
                 */

                /* packet loss conceal */

                for (int li = 0;li < ilbc_constants.BLOCKL_MAX;li++)
                    zeros[li] = 0.0f;
                //        memset(zeros, 0, BLOCKL_MAX*sizeof(float));

                one[0] = 1;
                for (int li = 0;li < ilbc_constants.LPC_FILTERORDER;li++)
                    one[li + 1] = 0.0f;
                //        memset(one+1, 0, LPC_FILTERORDER*sizeof(float));

                start = 0;

                doThePLC(PLCresidual, PLClpc, 1, zeros, one, 0,
                     last_lag);
                System.Array.Copy(PLCresidual, 0, decresidual, 0, this.ULP_inst.blockl);
                //         memcpy(decresidual, PLCresidual,
                //            this.ULP_inst.blockl*sizeof(float));

                order_plus_one = ilbc_constants.LPC_FILTERORDER + 1;
                for (i = 0;i < this.ULP_inst.nsub;i++) {
                    System.Array.Copy(PLClpc, 0, syntdenum, (i * order_plus_one), order_plus_one);
                    //         memcpy(syntdenum+(i*order_plus_one), PLClpc,
                    //                order_plus_one*sizeof(float));
                }
            }

            if (this.use_enhancer == 1) {

                /* post filtering */

                this.last_lag = enhancerInterface(data, decresidual);

                //         System.out.println("last_lag : " + this.last_lag);

                //        for (int li = 0; li < data.Length; li++)
                //          System.out.println("data["+li+"] = " + data[li]);

                //        for (li = 0; li <

                /* synthesis filtering */

                if (this.ULP_inst.mode == 20) {
                    /* Enhancer has 40 samples delay */
                    i = 0;
                    //         System.out.println("run 1");
                    syntFilter(data, i * ilbc_constants.SUBL,
                           this.old_syntdenum,
                           (i + this.ULP_inst.nsub - 1) * (ilbc_constants.LPC_FILTERORDER + 1),
                           ilbc_constants.SUBL, this.syntMem);
                    //         System.out.println("runs 2");
                    for (i = 1;i < this.ULP_inst.nsub;i++) {
                        //             System.out.println("pass " + i);
                        syntFilter(data, i * ilbc_constants.SUBL,
                               syntdenum, (i - 1) * (ilbc_constants.LPC_FILTERORDER + 1),
                               ilbc_constants.SUBL, this.syntMem);
                        //             System.out.println("pass " + i + " ends");
                    }
                    //        for (int li = 0; li < data.Length; li++)
                    //          System.out.println("psdata["+li+"] = " + data[li]);

                } else if (this.ULP_inst.mode == 30) {
                    /* Enhancer has 80 samples delay */
                    //         System.out.println("runs 3");
                    for (i = 0;i < 2;i++) {
                        syntFilter(data, i * ilbc_constants.SUBL,
                               this.old_syntdenum,
                               (i + this.ULP_inst.nsub - 2) * (ilbc_constants.LPC_FILTERORDER + 1),
                               ilbc_constants.SUBL, this.syntMem);
                    }
                    for (i = 2;i < this.ULP_inst.nsub;i++) {
                        //             System.out.println("runs 4");
                        syntFilter(data, i * ilbc_constants.SUBL,
                               syntdenum, (i - 2) * (ilbc_constants.LPC_FILTERORDER + 1),
                               ilbc_constants.SUBL, this.syntMem);
                    }
                }

            } else {

                /* Find last lag */
                lag = 20;
                maxcc = xCorrCoef(decresidual,
                          ilbc_constants.BLOCKL_MAX - ilbc_constants.ENH_BLOCKL,
                          decresidual,
                          ilbc_constants.BLOCKL_MAX - ilbc_constants.ENH_BLOCKL - lag,
                          ilbc_constants.ENH_BLOCKL);

                for (ilag = 21;ilag < 120;ilag++) {
                    cc = xCorrCoef(decresidual,
                               ilbc_constants.BLOCKL_MAX - ilbc_constants.ENH_BLOCKL,
                               decresidual,
                               ilbc_constants.BLOCKL_MAX - ilbc_constants.ENH_BLOCKL - ilag,
                               ilbc_constants.ENH_BLOCKL);

                    if (cc > maxcc) {
                        maxcc = cc;
                        lag = ilag;
                    }
                }
                this.last_lag = lag;

                /* copy data and run synthesis filter */

                System.Array.Copy(decresidual, 0, data, 0, this.ULP_inst.blockl);
                //         memcpy(data, decresidual,
                //            this.ULP_inst.blockl*sizeof(float));
                //         System.out.println("runs 5");
                for (i = 0;i < this.ULP_inst.nsub;i++) {
                    syntFilter(data, i * ilbc_constants.SUBL,
                           syntdenum, i * (ilbc_constants.LPC_FILTERORDER + 1),
                           ilbc_constants.SUBL, this.syntMem);
                }

            }

            /* high pass filtering on output if desired, otherwise
               copy to out */

            hpOutput(data, this.ULP_inst.blockl, decblock, this.hpomem);

            /* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/

            System.Array.Copy(syntdenum, 0, this.old_syntdenum, 0,
                     this.ULP_inst.nsub * (ilbc_constants.LPC_FILTERORDER + 1));
            //     memcpy(this.old_syntdenum, syntdenum,
            //            this.ULP_inst.nsub*(LPC_FILTERORDER+1)*sizeof(float));

            this.prev_enh_pl = 0;

            if (mode == 0) { /* PLC was used */
                this.prev_enh_pl = 1;
            }
        }
Ejemplo n.º 2
0
        //     public int decode(short decoded_data[], short encoded_data[], int mode)
        //     {
        //     return this.ULP_inst.blockl;
        //     }

        public short decode(       /* (o) Number of decoded samples */
           short[] decoded_data,        /* (o) Decoded signal block*/
           short[] encoded_data,        /* (i) Encoded bytes */
           short mode)                       /* (i) 0=PL, 1=Normal */
        {
            int k;
            float[] decblock = new float[ilbc_constants.BLOCKL_MAX];
            float dtmp;
            //       char en_data[] = new char [this.ULP_inst.no_of_bytes];
            bitstream en_data = new bitstream(this.ULP_inst.no_of_bytes);

            /* check if mode is valid */

            if ((mode < 0) || (mode > 1)) {
                //System.Diagnostics.Debug.WriteLine("\nERROR - Wrong mode - 0, 1 allowed\n");
                throw new System.ArgumentException("mode");
            }

            /* do actual decoding of block */
            for (k = 0;k < encoded_data.Length;k++) {
                en_data.buffer[2 * k + 1] = (byte) (encoded_data[k] >> 8);
                en_data.buffer[2 * k] = (byte) (encoded_data[k] & 0xff);
                //        System.out.println("on decode " + (en_data.buffer[2*k]+0) + " et " + (en_data.buffer[2*k+1]+0));
            }

            iLBC_decode(decblock, en_data, mode);

            /* convert to short */
            for (k = 0;k < this.ULP_inst.blockl;k++) {
                dtmp = decblock[k];
                //        System.out.println("on a eu : " + dtmp);

                if (dtmp < ilbc_constants.MIN_SAMPLE)
                    dtmp = ilbc_constants.MIN_SAMPLE;
                else if (dtmp > ilbc_constants.MAX_SAMPLE)
                    dtmp = ilbc_constants.MAX_SAMPLE;
                decoded_data[k] = (short) dtmp;
            }

            return ((short) this.ULP_inst.blockl);
        }