Exemple #1
0
 /// <summary>Decode the given input bits.</summary>
 /// <remarks>Decode the given input bits.</remarks>
 /// <param name="bits">- Speex bits buffer.</param>
 /// <param name="out">- the decoded mono audio frame.</param>
 /// <returns>1 if a terminator was found, 0 if not.</returns>
 /// <exception cref="java.io.StreamCorruptedException">
 /// If there is an error detected in the
 /// data stream.
 /// </exception>
 public virtual int decode(org.xiph.speex.Bits bits, float[] @out)
 {
     int i;
     int sub;
     int wideband;
     int ret;
     float[] low_pi_gain;
     float[] low_exc;
     float[] low_innov;
     ret = lowdec.decode(bits, x0d);
     if (ret != 0)
     {
         return ret;
     }
     bool dtx = lowdec.getDtx();
     if (bits == null)
     {
         decodeLost(@out, dtx);
         return 0;
     }
     wideband = bits.peek();
     if (wideband != 0)
     {
         wideband = bits.unpack(1);
         submodeID = bits.unpack(3);
     }
     else
     {
         submodeID = 0;
     }
     for (i = 0; i < frameSize; i++)
     {
         excBuf[i] = 0;
     }
     if (submodes[submodeID] == null)
     {
         if (dtx)
         {
             decodeLost(@out, true);
             return 0;
         }
         for (i = 0; i < frameSize; i++)
         {
             excBuf[i] = VERY_SMALL;
         }
         first = 1;
         org.xiph.speex.Filters.iir_mem2(excBuf, excIdx, interp_qlpc, high, 0, frameSize,
             lpcSize, mem_sp);
         filters.fir_mem_up(x0d, h0, y0, fullFrameSize, QMF_ORDER, g0_mem);
         filters.fir_mem_up(high, h1, y1, fullFrameSize, QMF_ORDER, g1_mem);
         for (i = 0; i < fullFrameSize; i++)
         {
             @out[i] = 2 * (y0[i] - y1[i]);
         }
         return 0;
     }
     low_pi_gain = lowdec.getPiGain();
     low_exc = lowdec.getExc();
     low_innov = lowdec.getInnov();
     submodes[submodeID].lsqQuant.unquant(qlsp, lpcSize, bits);
     if (first != 0)
     {
         for (i = 0; i < lpcSize; i++)
         {
             old_qlsp[i] = qlsp[i];
         }
     }
     for (sub = 0; sub < nbSubframes; sub++)
     {
         float tmp;
         float filter_ratio;
         float el = 0.0f;
         float rl = 0.0f;
         float rh = 0.0f;
         int subIdx = subframeSize * sub;
         tmp = (1.0f + sub) / nbSubframes;
         for (i = 0; i < lpcSize; i++)
         {
             interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i];
         }
         org.xiph.speex.Lsp.enforce_margin(interp_qlsp, lpcSize, .05f);
         for (i = 0; i < lpcSize; i++)
         {
             interp_qlsp[i] = (float)System.Math.Cos(interp_qlsp[i]);
         }
         m_lsp.lsp2lpc(interp_qlsp, interp_qlpc, lpcSize);
         if (enhanced)
         {
             float k1;
             float k2;
             float k3;
             k1 = submodes[submodeID].lpc_enh_k1;
             k2 = submodes[submodeID].lpc_enh_k2;
             k3 = k1 - k2;
             org.xiph.speex.Filters.bw_lpc(k1, interp_qlpc, awk1, lpcSize);
             org.xiph.speex.Filters.bw_lpc(k2, interp_qlpc, awk2, lpcSize);
             org.xiph.speex.Filters.bw_lpc(k3, interp_qlpc, awk3, lpcSize);
         }
         tmp = 1;
         pi_gain[sub] = 0;
         for (i = 0; i <= lpcSize; i++)
         {
             rh += tmp * interp_qlpc[i];
             tmp = -tmp;
             pi_gain[sub] += interp_qlpc[i];
         }
         rl = low_pi_gain[sub];
         rl = 1 / (System.Math.Abs(rl) + .01f);
         rh = 1 / (System.Math.Abs(rh) + .01f);
         filter_ratio = System.Math.Abs(.01f + rh) / (.01f + System.Math.Abs(rl));
         for (i = subIdx; i < subIdx + subframeSize; i++)
         {
             excBuf[i] = 0;
         }
         if (submodes[submodeID].innovation == null)
         {
             float g;
             int quant;
             quant = bits.unpack(5);
             g = (float)System.Math.Exp(((double)quant - 10) / 8.0);
             g /= filter_ratio;
             for (i = subIdx; i < subIdx + subframeSize; i++)
             {
                 excBuf[i] = foldingGain * g * low_innov[i];
             }
         }
         else
         {
             float gc;
             float scale;
             int qgc = bits.unpack(4);
             for (i = subIdx; i < subIdx + subframeSize; i++)
             {
                 el += low_exc[i] * low_exc[i];
             }
             gc = (float)System.Math.Exp((1 / 3.7f) * qgc - 2);
             scale = gc * (float)System.Math.Sqrt(1 + el) / filter_ratio;
             submodes[submodeID].innovation.unquant(excBuf, subIdx, subframeSize, bits);
             for (i = subIdx; i < subIdx + subframeSize; i++)
             {
                 excBuf[i] *= scale;
             }
             if (submodes[submodeID].double_codebook != 0)
             {
                 for (i = 0; i < subframeSize; i++)
                 {
                     innov2[i] = 0;
                 }
                 submodes[submodeID].innovation.unquant(innov2, 0, subframeSize, bits);
                 for (i = 0; i < subframeSize; i++)
                 {
                     innov2[i] *= scale * (1 / 2.5f);
                 }
                 for (i = 0; i < subframeSize; i++)
                 {
                     excBuf[subIdx + i] += innov2[i];
                 }
             }
         }
         for (i = subIdx; i < subIdx + subframeSize; i++)
         {
             high[i] = excBuf[i];
         }
         if (enhanced)
         {
             org.xiph.speex.Filters.filter_mem2(high, subIdx, awk2, awk1, subframeSize, lpcSize
                 , mem_sp, lpcSize);
             org.xiph.speex.Filters.filter_mem2(high, subIdx, awk3, interp_qlpc, subframeSize,
                 lpcSize, mem_sp, 0);
         }
         else
         {
             for (i = 0; i < lpcSize; i++)
             {
                 mem_sp[lpcSize + i] = 0;
             }
             org.xiph.speex.Filters.iir_mem2(high, subIdx, interp_qlpc, high, subIdx, subframeSize
                 , lpcSize, mem_sp);
         }
     }
     filters.fir_mem_up(x0d, h0, y0, fullFrameSize, QMF_ORDER, g0_mem);
     filters.fir_mem_up(high, h1, y1, fullFrameSize, QMF_ORDER, g1_mem);
     for (i = 0; i < fullFrameSize; i++)
     {
         @out[i] = 2 * (y0[i] - y1[i]);
     }
     for (i = 0; i < lpcSize; i++)
     {
         old_qlsp[i] = qlsp[i];
     }
     first = 0;
     return 0;
 }