public sealed override void Unquantify(float[] exc, int es, int nsf, Bits bits) { for (int i = 0; i < this.nb_subvect; i++) { if (this.have_sign != 0) { this.signs[i] = bits.Unpack(1); } else { this.signs[i] = 0; } this.ind[i] = bits.Unpack(this.shape_bits); } for (int i = 0; i < this.nb_subvect; i++) { float num = 1f; if (this.signs[i] != 0) { num = -1f; } for (int j = 0; j < this.subvect_size; j++) { exc[es + this.subvect_size * i + j] += num * 0.03125f * (float)this.shape_cb[this.ind[i] * this.subvect_size + j]; } } }
public void Init(Bits bits) { float num = 1f; if (bits.Unpack(1) != 0) { num = -1f; } int num2 = bits.Unpack(5); this.balance = (float)Math.Exp((double)num * 0.25 * (double)num2); num2 = bits.Unpack(2); this.e_ratio = Stereo.e_ratio_quant[num2]; }
/// <summary> /// Codebook Search Unquantification (Split Shape). /// </summary> public sealed override void Unquantify(SpeexWord32[] exc, int es, int nsf, Bits bits) { int i, j; /* Decode codewords and gains */ for (i = 0; i < nb_subvect; i++) { if (have_sign != 0) { signs[i] = bits.Unpack(1); } else { signs[i] = 0; } ind[i] = bits.Unpack(shape_bits); } /* Compute decoded excitation */ for (i = 0; i < nb_subvect; i++) { float s = 1.0f; if (signs[i] != 0) { s = -1.0f; } #if FIXED_POINT if (s == 1) { for (j = 0; j < subvect_size; j++) { exc[subvect_size * i + j] = (int)(shape_cb[ind[i] * subvect_size + j]) >> (14 - 5); } } else { for (j = 0; j < subvect_size; j++) { exc[subvect_size * i + j] = -((int)(shape_cb[ind[i] * subvect_size + j]) << (14 - 5)); } } #else for (j = 0; j < subvect_size; j++) { exc[es + subvect_size * i + j] += s * 0.03125f * (float)shape_cb[ind[i] * subvect_size + j]; } #endif } }
protected internal void UnpackPlus(float[] lsp, int[] tab, Bits bits, float k, int ti, int li) { int num = bits.Unpack(6); for (int i = 0; i < ti; i++) { lsp[i + li] += k * (float)tab[num * ti + i]; } }
/// <summary> /// Callback handler for intensity stereo info /// </summary> public void Init(Bits bits) { SpeexWord16 sign = 1; int tmp; if (bits.Unpack(1) != 0) { sign = -1; } tmp = bits.Unpack(5); #if FIXED_POINT balance = (int)Math.Exp(sign * (tmp << 9)); #else balance = (float)Math.Exp(sign * .25d * tmp); #endif tmp = bits.Unpack(2); e_ratio = e_ratio_quant[tmp]; }
/// <summary> /// Long Term Prediction Unquantification (3Tap). /// </summary> /// <returns>pitch</returns> public sealed override int Unquant( float[] exc, int es, int start, float pitch_coef, int nsf, float[] gain_val, Bits bits, int count_lost, int subframe_offset, float last_pitch_gain) { int i, pitch, gain_index; pitch = bits.Unpack(pitch_bits); pitch += start; gain_index = bits.Unpack(gain_bits); gain[0] = 0.015625f * (float)gain_cdbk[gain_index * 3] + .5f; gain[1] = 0.015625f * (float)gain_cdbk[gain_index * 3 + 1] + .5f; gain[2] = 0.015625f * (float)gain_cdbk[gain_index * 3 + 2] + .5f; if (count_lost != 0 && pitch > subframe_offset) { float gain_sum = Math.Abs(gain[1]); float tmp = (count_lost < 4) ? last_pitch_gain : 0.4f * last_pitch_gain; if (tmp > .95f) { tmp = .95f; } if (gain[0] > 0) { gain_sum += gain[0]; } else { gain_sum -= .5f * gain[0]; } if (gain[2] > 0) { gain_sum += gain[2]; } else { gain_sum -= .5f * gain[0]; } if (gain_sum > tmp) { float fact = tmp / gain_sum; for (i = 0; i < 3; i++) { gain[i] *= fact; } } } gain_val[0] = gain[0]; gain_val[1] = gain[1]; gain_val[2] = gain[2]; for (i = 0; i < 3; i++) { int j, tmp1, tmp2, pp = pitch + 1 - i; tmp1 = nsf; if (tmp1 > pp) { tmp1 = pp; } tmp2 = nsf; if (tmp2 > pp + pitch) { tmp2 = pp + pitch; } for (j = 0; j < tmp1; j++) { e[i][j] = exc[es + j - pp]; } for (j = tmp1; j < tmp2; j++) { e[i][j] = exc[es + j - pp - pitch]; } for (j = tmp2; j < nsf; j++) { e[i][j] = 0; } } for (i = 0; i < nsf; i++) { exc[es + i] = gain[0] * e[2][i] + gain[1] * e[1][i] + gain[2] * e[0][i]; } return(pitch); }
/// <summary> /// Decode the given input bits. /// </summary> /// <returns>1 if a terminator was found, 0 if not.</returns> public virtual int Decode(Bits bits, float[] xout) { int i, sub, wideband, ret; float[] low_pi_gain, low_exc, low_innov; /* Decode the low-band */ ret = lowdec.Decode(bits, x0d); if (ret != 0) { return(ret); } bool dtx = lowdec.Dtx; if (bits == null) { DecodeLost(xout, dtx); return(0); } /* Check "wideband bit" */ wideband = bits.Peek(); if (wideband != 0) { /* Regular wideband frame, read the submode */ wideband = bits.Unpack(1); submodeID = bits.Unpack(3); } else { /* was a narrowband frame, set "null submode" */ submodeID = 0; } for (i = 0; i < frameSize; i++) { excBuf[i] = 0; } /* If null mode (no transmission), just set a couple things to zero */ if (submodes[submodeID] == null) { if (dtx) { DecodeLost(xout, true); return(0); } for (i = 0; i < frameSize; i++) { excBuf[i] = NSpeex.NbCodec.VERY_SMALL; } first = 1; /* Final signal synthesis from excitation */ NSpeex.Filters.Iir_mem2(excBuf, excIdx, interp_qlpc, high, 0, frameSize, lpcSize, mem_sp); filters.Fir_mem_up(x0d, NSpeex.Codebook_Constants.h0, y0, fullFrameSize, NSpeex.SbCodec.QMF_ORDER, g0_mem); filters.Fir_mem_up(high, NSpeex.Codebook_Constants.h1, y1, fullFrameSize, NSpeex.SbCodec.QMF_ORDER, g1_mem); for (i = 0; i < fullFrameSize; i++) { xout[i] = 2 * (y0[i] - y1[i]); } return(0); } low_pi_gain = lowdec.PiGain; low_exc = lowdec.Exc; low_innov = lowdec.Innov; 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, filter_ratio, el = 0.0f, rl = 0.0f, rh = 0.0f; int subIdx = subframeSize * sub; /* LSP interpolation */ tmp = (1.0f + sub) / nbSubframes; for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i]; } NSpeex.Lsp.Enforce_margin(interp_qlsp, lpcSize, .05f); /* LSPs to x-domain */ for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (float)System.Math.Cos(interp_qlsp[i]); } /* LSP to LPC */ m_lsp.Lsp2lpc(interp_qlsp, interp_qlpc, lpcSize); if (enhanced) { float k1, k2, k3; k1 = submodes[submodeID].LpcEnhK1; k2 = submodes[submodeID].LpcEnhK2; k3 = k1 - k2; NSpeex.Filters.Bw_lpc(k1, interp_qlpc, awk1, lpcSize); NSpeex.Filters.Bw_lpc(k2, interp_qlpc, awk2, lpcSize); NSpeex.Filters.Bw_lpc(k3, interp_qlpc, awk3, lpcSize); } /* * Calculate reponse ratio between low & high filter in band middle * (4000 Hz) */ 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 / (Math.Abs(rl) + .01f); rh = 1 / (Math.Abs(rh) + .01f); filter_ratio = Math.Abs(.01f + rh) / (.01f + Math.Abs(rl)); /* reset excitation buffer */ 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)Math.Exp(((double)quant - 10) / 8.0d); g /= filter_ratio; /* High-band excitation using the low-band excitation and a gain */ for (i = subIdx; i < subIdx + subframeSize; i++) { excBuf[i] = foldingGain * g * low_innov[i]; } } else { float gc, scale; int qgc = bits.Unpack(4); for (i = subIdx; i < subIdx + subframeSize; i++) { el += low_exc[i] * low_exc[i]; } gc = (float)Math.Exp((1 / 3.7f) * qgc - 2); scale = gc * (float)Math.Sqrt(1 + el) / filter_ratio; submodes[submodeID].Innovation.Unquantify(excBuf, subIdx, subframeSize, bits); for (i = subIdx; i < subIdx + subframeSize; i++) { excBuf[i] *= scale; } if (submodes[submodeID].DoubleCodebook != 0) { for (i = 0; i < subframeSize; i++) { innov2[i] = 0; } submodes[submodeID].Innovation.Unquantify(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) { /* Use enhanced LPC filter */ NSpeex.Filters.Filter_mem2(high, subIdx, awk2, awk1, subframeSize, lpcSize, mem_sp, lpcSize); NSpeex.Filters.Filter_mem2(high, subIdx, awk3, interp_qlpc, subframeSize, lpcSize, mem_sp, 0); } else { /* Use regular filter */ for (i = 0; i < lpcSize; i++) { mem_sp[lpcSize + i] = 0; } NSpeex.Filters.Iir_mem2(high, subIdx, interp_qlpc, high, subIdx, subframeSize, lpcSize, mem_sp); } } filters.Fir_mem_up(x0d, NSpeex.Codebook_Constants.h0, y0, fullFrameSize, NSpeex.SbCodec.QMF_ORDER, g0_mem); filters.Fir_mem_up(high, NSpeex.Codebook_Constants.h1, y1, fullFrameSize, NSpeex.SbCodec.QMF_ORDER, g1_mem); for (i = 0; i < fullFrameSize; i++) { xout[i] = 2 * (y0[i] - y1[i]); } for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } first = 0; return(0); }
public void UserInbandRequest(Bits bits) { int num = bits.Unpack(4); bits.Advance(5 + 8 * num); }
public void SpeexInbandRequest(Bits bits) { switch (bits.Unpack(4)) { case 0: bits.Advance(1); break; case 1: bits.Advance(1); break; case 2: bits.Advance(4); break; case 3: bits.Advance(4); break; case 4: bits.Advance(4); break; case 5: bits.Advance(4); break; case 6: bits.Advance(4); break; case 7: bits.Advance(4); break; case 8: bits.Advance(8); break; case 9: this.stereo.Init(bits); break; case 10: bits.Advance(16); break; case 11: bits.Advance(16); break; case 12: bits.Advance(32); break; case 13: bits.Advance(32); break; case 14: bits.Advance(64); break; case 15: bits.Advance(64); break; } }
public virtual int Decode(Bits bits, float[] xout) { int num = this.lowdec.Decode(bits, this.x0d); if (num != 0) { return(num); } bool dtx = this.lowdec.Dtx; if (bits == null) { this.DecodeLost(xout, dtx); return(0); } int num2 = bits.Peek(); if (num2 != 0) { num2 = bits.Unpack(1); this.submodeID = bits.Unpack(3); } else { this.submodeID = 0; } for (int i = 0; i < this.frameSize; i++) { this.excBuf[i] = 0f; } if (this.submodes[this.submodeID] != null) { float[] piGain = this.lowdec.PiGain; float[] exc = this.lowdec.Exc; float[] innov = this.lowdec.Innov; this.submodes[this.submodeID].LsqQuant.Unquant(this.qlsp, this.lpcSize, bits); if (this.first != 0) { for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } } for (int j = 0; j < this.nbSubframes; j++) { float num3 = 0f; float num4 = 0f; int num5 = this.subframeSize * j; float num6 = (1f + (float)j) / (float)this.nbSubframes; for (int i = 0; i < this.lpcSize; i++) { this.interp_qlsp[i] = (1f - num6) * this.old_qlsp[i] + num6 * this.qlsp[i]; } Lsp.Enforce_margin(this.interp_qlsp, this.lpcSize, 0.05f); for (int i = 0; i < this.lpcSize; i++) { this.interp_qlsp[i] = (float)Math.Cos((double)this.interp_qlsp[i]); } this.m_lsp.Lsp2lpc(this.interp_qlsp, this.interp_qlpc, this.lpcSize); if (this.enhanced) { float lpcEnhK = this.submodes[this.submodeID].LpcEnhK1; float lpcEnhK2 = this.submodes[this.submodeID].LpcEnhK2; float gamma = lpcEnhK - lpcEnhK2; Filters.Bw_lpc(lpcEnhK, this.interp_qlpc, this.awk1, this.lpcSize); Filters.Bw_lpc(lpcEnhK2, this.interp_qlpc, this.awk2, this.lpcSize); Filters.Bw_lpc(gamma, this.interp_qlpc, this.awk3, this.lpcSize); } num6 = 1f; this.pi_gain[j] = 0f; for (int i = 0; i <= this.lpcSize; i++) { num4 += num6 * this.interp_qlpc[i]; num6 = -num6; this.pi_gain[j] += this.interp_qlpc[i]; } float value = piGain[j]; value = 1f / (Math.Abs(value) + 0.01f); num4 = 1f / (Math.Abs(num4) + 0.01f); float num7 = Math.Abs(0.01f + num4) / (0.01f + Math.Abs(value)); for (int i = num5; i < num5 + this.subframeSize; i++) { this.excBuf[i] = 0f; } if (this.submodes[this.submodeID].Innovation == null) { int num8 = bits.Unpack(5); float num9 = (float)Math.Exp(((double)num8 - 10.0) / 8.0); num9 /= num7; for (int i = num5; i < num5 + this.subframeSize; i++) { this.excBuf[i] = this.foldingGain * num9 * innov[i]; } } else { int num10 = bits.Unpack(4); for (int i = num5; i < num5 + this.subframeSize; i++) { num3 += exc[i] * exc[i]; } float num11 = (float)Math.Exp((double)(0.270270258f * (float)num10 - 2f)); float num12 = num11 * (float)Math.Sqrt((double)(1f + num3)) / num7; this.submodes[this.submodeID].Innovation.Unquantify(this.excBuf, num5, this.subframeSize, bits); for (int i = num5; i < num5 + this.subframeSize; i++) { this.excBuf[i] *= num12; } if (this.submodes[this.submodeID].DoubleCodebook != 0) { for (int i = 0; i < this.subframeSize; i++) { this.innov2[i] = 0f; } this.submodes[this.submodeID].Innovation.Unquantify(this.innov2, 0, this.subframeSize, bits); for (int i = 0; i < this.subframeSize; i++) { this.innov2[i] *= num12 * 0.4f; } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num5 + i] += this.innov2[i]; } } } for (int i = num5; i < num5 + this.subframeSize; i++) { this.high[i] = this.excBuf[i]; } if (this.enhanced) { Filters.Filter_mem2(this.high, num5, this.awk2, this.awk1, this.subframeSize, this.lpcSize, this.mem_sp, this.lpcSize); Filters.Filter_mem2(this.high, num5, this.awk3, this.interp_qlpc, this.subframeSize, this.lpcSize, this.mem_sp, 0); } else { for (int i = 0; i < this.lpcSize; i++) { this.mem_sp[this.lpcSize + i] = 0f; } Filters.Iir_mem2(this.high, num5, this.interp_qlpc, this.high, num5, this.subframeSize, this.lpcSize, this.mem_sp); } } this.filters.Fir_mem_up(this.x0d, Codebook_Constants.h0, this.y0, this.fullFrameSize, 64, this.g0_mem); this.filters.Fir_mem_up(this.high, Codebook_Constants.h1, this.y1, this.fullFrameSize, 64, this.g1_mem); for (int i = 0; i < this.fullFrameSize; i++) { xout[i] = 2f * (this.y0[i] - this.y1[i]); } for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } this.first = 0; return(0); } if (dtx) { this.DecodeLost(xout, true); return(0); } for (int i = 0; i < this.frameSize; i++) { this.excBuf[i] = 0f; } this.first = 1; Filters.Iir_mem2(this.excBuf, this.excIdx, this.interp_qlpc, this.high, 0, this.frameSize, this.lpcSize, this.mem_sp); this.filters.Fir_mem_up(this.x0d, Codebook_Constants.h0, this.y0, this.fullFrameSize, 64, this.g0_mem); this.filters.Fir_mem_up(this.high, Codebook_Constants.h1, this.y1, this.fullFrameSize, 64, this.g1_mem); for (int i = 0; i < this.fullFrameSize; i++) { xout[i] = 2f * (this.y0[i] - this.y1[i]); } return(0); }
public sealed override int Unquant(float[] exc, int es, int start, float pitch_coef, int nsf, float[] gain_val, Bits bits, int count_lost, int subframe_offset, float last_pitch_gain) { int num = bits.Unpack(this.pitch_bits); num += start; int num2 = bits.Unpack(this.gain_bits); this.gain[0] = 0.015625f * (float)this.gain_cdbk[num2 * 3] + 0.5f; this.gain[1] = 0.015625f * (float)this.gain_cdbk[num2 * 3 + 1] + 0.5f; this.gain[2] = 0.015625f * (float)this.gain_cdbk[num2 * 3 + 2] + 0.5f; if (count_lost != 0 && num > subframe_offset) { float num3 = Math.Abs(this.gain[1]); float num4 = (count_lost >= 4) ? (0.4f * last_pitch_gain) : last_pitch_gain; if (num4 > 0.95f) { num4 = 0.95f; } if (this.gain[0] > 0f) { num3 += this.gain[0]; } else { num3 -= 0.5f * this.gain[0]; } if (this.gain[2] > 0f) { num3 += this.gain[2]; } else { num3 -= 0.5f * this.gain[0]; } if (num3 > num4) { float num5 = num4 / num3; for (int i = 0; i < 3; i++) { this.gain[i] *= num5; } } } gain_val[0] = this.gain[0]; gain_val[1] = this.gain[1]; gain_val[2] = this.gain[2]; for (int i = 0; i < 3; i++) { int num6 = num + 1 - i; int num7 = nsf; if (num7 > num6) { num7 = num6; } int num8 = nsf; if (num8 > num6 + num) { num8 = num6 + num; } for (int j = 0; j < num7; j++) { this.e[i][j] = exc[es + j - num6]; } for (int j = num7; j < num8; j++) { this.e[i][j] = exc[es + j - num6 - num]; } for (int j = num8; j < nsf; j++) { this.e[i][j] = 0f; } } for (int i = 0; i < nsf; i++) { exc[es + i] = this.gain[0] * this.e[2][i] + this.gain[1] * this.e[1][i] + this.gain[2] * this.e[0][i]; } return(num); }
public virtual int Decode(Bits bits, float[] xout) { int num = 0; float[] array = new float[3]; float num2 = 0f; int num3 = 40; float num4 = 0f; float num5 = 0f; if (bits == null && this.dtx_enabled != 0) { this.submodeID = 0; } else { if (bits == null) { this.DecodeLost(xout); return(0); } while (bits.BitsRemaining() >= 5) { int num6; if (bits.Unpack(1) != 0) { num6 = bits.Unpack(3); int num7 = SbCodec.SB_FRAME_SIZE[num6]; if (num7 < 0) { throw new InvalidFormatException("Invalid sideband mode encountered (1st sideband): " + num6); } num7 -= 4; bits.Advance(num7); if (bits.Unpack(1) != 0) { num6 = bits.Unpack(3); num7 = SbCodec.SB_FRAME_SIZE[num6]; if (num7 < 0) { throw new InvalidFormatException("Invalid sideband mode encountered. (2nd sideband): " + num6); } num7 -= 4; bits.Advance(num7); if (bits.Unpack(1) != 0) { throw new InvalidFormatException("More than two sideband layers found"); } } } if (bits.BitsRemaining() < 4) { return(1); } num6 = bits.Unpack(4); if (num6 == 15) { return(1); } if (num6 == 14) { this.inband.SpeexInbandRequest(bits); } else if (num6 == 13) { this.inband.UserInbandRequest(bits); } else if (num6 > 8) { throw new InvalidFormatException("Invalid mode encountered: " + num6); } if (num6 <= 8) { this.submodeID = num6; goto IL_199; } } return(-1); } IL_199: Array.Copy(this.frmBuf, this.frameSize, this.frmBuf, 0, this.bufSize - this.frameSize); Array.Copy(this.excBuf, this.frameSize, this.excBuf, 0, this.bufSize - this.frameSize); if (this.submodes[this.submodeID] == null) { Filters.Bw_lpc(0.93f, this.interp_qlpc, this.lpc, 10); float num8 = 0f; for (int i = 0; i < this.frameSize; i++) { num8 += this.innov[i] * this.innov[i]; } num8 = (float)Math.Sqrt((double)(num8 / (float)this.frameSize)); for (int i = this.excIdx; i < this.excIdx + this.frameSize; i++) { this.excBuf[i] = (float)((double)(3f * num8) * (this.random.NextDouble() - 0.5)); } this.first = 1; Filters.Iir_mem2(this.excBuf, this.excIdx, this.lpc, this.frmBuf, this.frmIdx, this.frameSize, this.lpcSize, this.mem_sp); xout[0] = this.frmBuf[this.frmIdx] + this.preemph * this.pre_mem; for (int i = 1; i < this.frameSize; i++) { xout[i] = this.frmBuf[this.frmIdx + i] + this.preemph * xout[i - 1]; } this.pre_mem = xout[this.frameSize - 1]; this.count_lost = 0; return(0); } this.submodes[this.submodeID].LsqQuant.Unquant(this.qlsp, this.lpcSize, bits); if (this.count_lost != 0) { float num9 = 0f; for (int i = 0; i < this.lpcSize; i++) { num9 += Math.Abs(this.old_qlsp[i] - this.qlsp[i]); } float num10 = (float)(0.6 * Math.Exp(-0.2 * (double)num9)); for (int i = 0; i < 2 * this.lpcSize; i++) { this.mem_sp[i] *= num10; } } if (this.first != 0 || this.count_lost != 0) { for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } } if (this.submodes[this.submodeID].LbrPitch != -1) { num = this.min_pitch + bits.Unpack(7); } if (this.submodes[this.submodeID].ForcedPitchGain != 0) { int num11 = bits.Unpack(4); num2 = 0.066667f * (float)num11; } int num12 = bits.Unpack(5); float num13 = (float)Math.Exp((double)num12 / 3.5); if (this.submodeID == 1) { int num14 = bits.Unpack(4); if (num14 == 15) { this.dtx_enabled = 1; } else { this.dtx_enabled = 0; } } if (this.submodeID > 1) { this.dtx_enabled = 0; } for (int j = 0; j < this.nbSubframes; j++) { int num15 = this.subframeSize * j; int num16 = this.frmIdx + num15; int num17 = this.excIdx + num15; float num18 = (1f + (float)j) / (float)this.nbSubframes; for (int i = 0; i < this.lpcSize; i++) { this.interp_qlsp[i] = (1f - num18) * this.old_qlsp[i] + num18 * this.qlsp[i]; } Lsp.Enforce_margin(this.interp_qlsp, this.lpcSize, 0.002f); for (int i = 0; i < this.lpcSize; i++) { this.interp_qlsp[i] = (float)Math.Cos((double)this.interp_qlsp[i]); } this.m_lsp.Lsp2lpc(this.interp_qlsp, this.interp_qlpc, this.lpcSize); if (this.enhanced) { float num19 = 0.9f; float lpcEnhK = this.submodes[this.submodeID].LpcEnhK1; float lpcEnhK2 = this.submodes[this.submodeID].LpcEnhK2; float gamma = (1f - (1f - num19 * lpcEnhK) / (1f - num19 * lpcEnhK2)) / num19; Filters.Bw_lpc(lpcEnhK, this.interp_qlpc, this.awk1, this.lpcSize); Filters.Bw_lpc(lpcEnhK2, this.interp_qlpc, this.awk2, this.lpcSize); Filters.Bw_lpc(gamma, this.interp_qlpc, this.awk3, this.lpcSize); } num18 = 1f; this.pi_gain[j] = 0f; for (int i = 0; i <= this.lpcSize; i++) { this.pi_gain[j] += num18 * this.interp_qlpc[i]; num18 = -num18; } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num17 + i] = 0f; } int num20; if (this.submodes[this.submodeID].LbrPitch != -1) { int lbrPitch = this.submodes[this.submodeID].LbrPitch; if (lbrPitch != 0) { num20 = num - lbrPitch + 1; if (num20 < this.min_pitch) { num20 = this.min_pitch; } int num21 = num + lbrPitch; if (num21 > this.max_pitch) { num21 = this.max_pitch; } } else { num20 = num; } } else { num20 = this.min_pitch; int num21 = this.max_pitch; } int num22 = this.submodes[this.submodeID].Ltp.Unquant(this.excBuf, num17, num20, num2, this.subframeSize, array, bits, this.count_lost, num15, this.last_pitch_gain); if (this.count_lost != 0 && num13 < this.last_ol_gain) { float num23 = num13 / (this.last_ol_gain + 1f); for (int i = 0; i < this.subframeSize; i++) { this.excBuf[this.excIdx + i] *= num23; } } num18 = Math.Abs(array[0] + array[1] + array[2]); num18 = Math.Abs(array[1]); if (array[0] > 0f) { num18 += array[0]; } else { num18 -= 0.5f * array[0]; } if (array[2] > 0f) { num18 += array[2]; } else { num18 -= 0.5f * array[0]; } num5 += num18; if (num18 > num4) { num3 = num22; num4 = num18; } int num24 = j * this.subframeSize; for (int i = num24; i < num24 + this.subframeSize; i++) { this.innov[i] = 0f; } float num26; if (this.submodes[this.submodeID].HaveSubframeGain == 3) { int num25 = bits.Unpack(3); num26 = (float)((double)num13 * Math.Exp((double)NbCodec.exc_gain_quant_scal3[num25])); } else if (this.submodes[this.submodeID].HaveSubframeGain == 1) { int num25 = bits.Unpack(1); num26 = (float)((double)num13 * Math.Exp((double)NbCodec.exc_gain_quant_scal1[num25])); } else { num26 = num13; } if (this.submodes[this.submodeID].Innovation != null) { this.submodes[this.submodeID].Innovation.Unquantify(this.innov, num24, this.subframeSize, bits); } for (int i = num24; i < num24 + this.subframeSize; i++) { this.innov[i] *= num26; } if (this.submodeID == 1) { float num27 = num2; for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num17 + i] = 0f; } while (this.voc_offset < this.subframeSize) { if (this.voc_offset >= 0) { this.excBuf[num17 + this.voc_offset] = (float)Math.Sqrt((double)(1f * (float)num)); } this.voc_offset += num; } this.voc_offset -= this.subframeSize; num27 = 0.5f + 2f * (num27 - 0.6f); if (num27 < 0f) { num27 = 0f; } if (num27 > 1f) { num27 = 1f; } for (int i = 0; i < this.subframeSize; i++) { float voc_m = this.excBuf[num17 + i]; this.excBuf[num17 + i] = 0.8f * num27 * this.excBuf[num17 + i] * num13 + 0.6f * num27 * this.voc_m1 * num13 + 0.5f * num27 * this.innov[num24 + i] - 0.5f * num27 * this.voc_m2 + (1f - num27) * this.innov[num24 + i]; this.voc_m1 = voc_m; this.voc_m2 = this.innov[num24 + i]; this.voc_mean = 0.95f * this.voc_mean + 0.05f * this.excBuf[num17 + i]; this.excBuf[num17 + i] -= this.voc_mean; } } else { for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num17 + i] += this.innov[num24 + i]; } } if (this.submodes[this.submodeID].DoubleCodebook != 0) { for (int i = 0; i < this.subframeSize; i++) { this.innov2[i] = 0f; } this.submodes[this.submodeID].Innovation.Unquantify(this.innov2, 0, this.subframeSize, bits); for (int i = 0; i < this.subframeSize; i++) { this.innov2[i] *= num26 * 0.454545438f; } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num17 + i] += this.innov2[i]; } } for (int i = 0; i < this.subframeSize; i++) { this.frmBuf[num16 + i] = this.excBuf[num17 + i]; } if (this.enhanced && this.submodes[this.submodeID].CombGain > 0f) { this.filters.Comb_filter(this.excBuf, num17, this.frmBuf, num16, this.subframeSize, num22, array, this.submodes[this.submodeID].CombGain); } if (this.enhanced) { Filters.Filter_mem2(this.frmBuf, num16, this.awk2, this.awk1, this.subframeSize, this.lpcSize, this.mem_sp, this.lpcSize); Filters.Filter_mem2(this.frmBuf, num16, this.awk3, this.interp_qlpc, this.subframeSize, this.lpcSize, this.mem_sp, 0); } else { for (int i = 0; i < this.lpcSize; i++) { this.mem_sp[this.lpcSize + i] = 0f; } Filters.Iir_mem2(this.frmBuf, num16, this.interp_qlpc, this.frmBuf, num16, this.subframeSize, this.lpcSize, this.mem_sp); } } xout[0] = this.frmBuf[this.frmIdx] + this.preemph * this.pre_mem; for (int i = 1; i < this.frameSize; i++) { xout[i] = this.frmBuf[this.frmIdx + i] + this.preemph * xout[i - 1]; } this.pre_mem = xout[this.frameSize - 1]; for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } this.first = 0; this.count_lost = 0; this.last_pitch = num3; this.last_pitch_gain = 0.25f * num5; this.pitch_gain_buf[this.pitch_gain_buf_idx++] = this.last_pitch_gain; if (this.pitch_gain_buf_idx > 2) { this.pitch_gain_buf_idx = 0; } this.last_ol_gain = num13; return(0); }
/// <summary> /// Decode the given input bits. /// </summary> /// <returns>1 if a terminator was found, 0 if not.</returns> /// <exception cref="InvalidFormatException">If there is an error detected in the data stream.</exception> public virtual int Decode(Bits bits, float[] xout) { int i, sub, pitch, ol_pitch = 0, m; float[] pitch_gain = new float[3]; float ol_gain = 0.0f, ol_pitch_coef = 0.0f; int best_pitch = 40; float best_pitch_gain = 0; float pitch_average = 0; if (bits == null && dtx_enabled != 0) { submodeID = 0; } else { /* * If bits is NULL, consider the packet to be lost (what could we do * anyway) */ if (bits == null) { DecodeLost(xout); return(0); } /* * Search for next narrowband block (handle requests, skip wideband * blocks) */ do { if (bits.BitsRemaining() < 5) { return(-1); } if (bits.Unpack(1) != 0) { /* * Skip wideband block (for * compatibility) */ // Wideband /* Get the sub-mode that was used */ m = bits.Unpack(NSpeex.SbCodec.SB_SUBMODE_BITS); int advance = NSpeex.SbCodec.SB_FRAME_SIZE[m]; if (advance < 0) { throw new InvalidFormatException( "Invalid sideband mode encountered (1st sideband): " + m); // return -2; } advance -= (NSpeex.SbCodec.SB_SUBMODE_BITS + 1); bits.Advance(advance); if (bits.Unpack(1) != 0) { /* * Skip ultra-wideband block * (for compatibility) */ /* Get the sub-mode that was used */ m = bits.Unpack(NSpeex.SbCodec.SB_SUBMODE_BITS); advance = NSpeex.SbCodec.SB_FRAME_SIZE[m]; if (advance < 0) { throw new InvalidFormatException( "Invalid sideband mode encountered. (2nd sideband): " + m); // return -2; } advance -= (NSpeex.SbCodec.SB_SUBMODE_BITS + 1); bits.Advance(advance); if (bits.Unpack(1) != 0) { /* Sanity check */ throw new InvalidFormatException( "More than two sideband layers found"); // return -2; } } // */ } if (bits.BitsRemaining() < 4) { return(1); } /* Get the sub-mode that was used */ m = bits.Unpack(NSpeex.NbCodec.NB_SUBMODE_BITS); if (m == 15) { /* We found a terminator */ return(1); } else if (m == 14) { /* Speex in-band request */ inband.SpeexInbandRequest(bits); } else if (m == 13) { /* User in-band request */ inband.UserInbandRequest(bits); } else if (m > 8) { /* Invalid mode */ throw new InvalidFormatException( "Invalid mode encountered: " + m); // return -2; } } while (m > 8); submodeID = m; } /* Shift all buffers by one frame */ System.Array.Copy(frmBuf, frameSize, frmBuf, 0, bufSize - frameSize); System.Array.Copy(excBuf, frameSize, excBuf, 0, bufSize - frameSize); /* If null mode (no transmission), just set a couple things to zero */ if (submodes[submodeID] == null) { NSpeex.Filters.Bw_lpc(.93f, interp_qlpc, lpc, 10); float innov_gain = 0; for (i = 0; i < frameSize; i++) { innov_gain += innov[i] * innov[i]; } innov_gain = (float)Math.Sqrt(innov_gain / frameSize); for (i = excIdx; i < excIdx + frameSize; i++) { excBuf[i] = (float)(3 * innov_gain * (random.NextDouble() - .5f)); } first = 1; /* Final signal synthesis from excitation */ NSpeex.Filters.Iir_mem2(excBuf, excIdx, lpc, frmBuf, frmIdx, frameSize, lpcSize, mem_sp); xout[0] = frmBuf[frmIdx] + preemph * pre_mem; for (i = 1; i < frameSize; i++) { xout[i] = frmBuf[frmIdx + i] + preemph * xout[i - 1]; } pre_mem = xout[frameSize - 1]; count_lost = 0; return(0); } /* Unquantize LSPs */ submodes[submodeID].LsqQuant.Unquant(qlsp, lpcSize, bits); /* Damp memory if a frame was lost and the LSP changed too much */ if (count_lost != 0) { float lsp_dist = 0, fact; for (i = 0; i < lpcSize; i++) { lsp_dist += Math.Abs(old_qlsp[i] - qlsp[i]); } fact = (float)(.6d * Math.Exp(-.2d * lsp_dist)); for (i = 0; i < 2 * lpcSize; i++) { mem_sp[i] *= fact; } } /* Handle first frame and lost-packet case */ if (first != 0 || count_lost != 0) { for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } } /* Get open-loop pitch estimation for low bit-rate pitch coding */ if (submodes[submodeID].LbrPitch != -1) { ol_pitch = min_pitch + bits.Unpack(7); } if (submodes[submodeID].ForcedPitchGain != 0) { int quant = bits.Unpack(4); ol_pitch_coef = 0.066667f * quant; } /* Get global excitation gain */ int qe = bits.Unpack(5); ol_gain = (float)Math.Exp(qe / 3.5d); /* unpacks unused dtx bits */ if (submodeID == 1) { int extra = bits.Unpack(4); if (extra == 15) { dtx_enabled = 1; } else { dtx_enabled = 0; } } if (submodeID > 1) { dtx_enabled = 0; } /* Loop on subframes */ for (sub = 0; sub < nbSubframes; sub++) { int offset, spIdx, extIdx; float tmp; /* Offset relative to start of frame */ offset = subframeSize * sub; /* Original signal */ spIdx = frmIdx + offset; /* Excitation */ extIdx = excIdx + offset; /* LSP interpolation (quantized and unquantized) */ tmp = (1.0f + sub) / nbSubframes; for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i]; } /* Make sure the LSP's are stable */ NSpeex.Lsp.Enforce_margin(interp_qlsp, lpcSize, .002f); /* Compute interpolated LPCs (unquantized) */ for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (float)System.Math.Cos(interp_qlsp[i]); } m_lsp.Lsp2lpc(interp_qlsp, interp_qlpc, lpcSize); /* Compute enhanced synthesis filter */ if (enhanced) { float r = .9f; float k1, k2, k3; k1 = submodes[submodeID].LpcEnhK1; k2 = submodes[submodeID].LpcEnhK2; k3 = (1 - (1 - r * k1) / (1 - r * k2)) / r; NSpeex.Filters.Bw_lpc(k1, interp_qlpc, awk1, lpcSize); NSpeex.Filters.Bw_lpc(k2, interp_qlpc, awk2, lpcSize); NSpeex.Filters.Bw_lpc(k3, interp_qlpc, awk3, lpcSize); } /* Compute analysis filter at w=pi */ tmp = 1; pi_gain[sub] = 0; for (i = 0; i <= lpcSize; i++) { pi_gain[sub] += tmp * interp_qlpc[i]; tmp = -tmp; } /* Reset excitation */ for (i = 0; i < subframeSize; i++) { excBuf[extIdx + i] = 0; } /* Adaptive codebook contribution */ int pit_min, pit_max; /* Handle pitch constraints if any */ if (submodes[submodeID].LbrPitch != -1) { int margin = submodes[submodeID].LbrPitch; if (margin != 0) { pit_min = ol_pitch - margin + 1; if (pit_min < min_pitch) { pit_min = min_pitch; } pit_max = ol_pitch + margin; if (pit_max > max_pitch) { pit_max = max_pitch; } } else { pit_min = pit_max = ol_pitch; } } else { pit_min = min_pitch; pit_max = max_pitch; } /* Pitch synthesis */ pitch = submodes[submodeID].Ltp.Unquant(excBuf, extIdx, pit_min, ol_pitch_coef, subframeSize, pitch_gain, bits, count_lost, offset, last_pitch_gain); /* If we had lost frames, check energy of last received frame */ if (count_lost != 0 && ol_gain < last_ol_gain) { float fact_0 = ol_gain / (last_ol_gain + 1); for (i = 0; i < subframeSize; i++) { excBuf[excIdx + i] *= fact_0; } } tmp = Math.Abs(pitch_gain[0] + pitch_gain[1] + pitch_gain[2]); tmp = Math.Abs(pitch_gain[1]); if (pitch_gain[0] > 0) { tmp += pitch_gain[0]; } else { tmp -= .5f * pitch_gain[0]; } if (pitch_gain[2] > 0) { tmp += pitch_gain[2]; } else { tmp -= .5f * pitch_gain[0]; } pitch_average += tmp; if (tmp > best_pitch_gain) { best_pitch = pitch; best_pitch_gain = tmp; } /* Unquantize the innovation */ int q_energy, ivi = sub * subframeSize; float ener; for (i = ivi; i < ivi + subframeSize; i++) { innov[i] = 0.0f; } /* Decode sub-frame gain correction */ if (submodes[submodeID].HaveSubframeGain == 3) { q_energy = bits.Unpack(3); ener = (float)(ol_gain * Math.Exp(NSpeex.NbCodec.exc_gain_quant_scal3[q_energy])); } else if (submodes[submodeID].HaveSubframeGain == 1) { q_energy = bits.Unpack(1); ener = (float)(ol_gain * Math.Exp(NSpeex.NbCodec.exc_gain_quant_scal1[q_energy])); } else { ener = ol_gain; } if (submodes[submodeID].Innovation != null) { /* Fixed codebook contribution */ submodes[submodeID].Innovation.Unquantify(innov, ivi, subframeSize, bits); } /* De-normalize innovation and update excitation */ for (i = ivi; i < ivi + subframeSize; i++) { innov[i] *= ener; } /* Vocoder mode */ if (submodeID == 1) { float g = ol_pitch_coef; for (i = 0; i < subframeSize; i++) { excBuf[extIdx + i] = 0; } while (voc_offset < subframeSize) { if (voc_offset >= 0) { excBuf[extIdx + voc_offset] = (float)Math.Sqrt(1.0f * ol_pitch); } voc_offset += ol_pitch; } voc_offset -= subframeSize; g = .5f + 2 * (g - .6f); if (g < 0) { g = 0; } if (g > 1) { g = 1; } for (i = 0; i < subframeSize; i++) { float itmp = excBuf[extIdx + i]; excBuf[extIdx + i] = .8f * g * excBuf[extIdx + i] * ol_gain + .6f * g * voc_m1 * ol_gain + .5f * g * innov[ivi + i] - .5f * g * voc_m2 + (1 - g) * innov[ivi + i]; voc_m1 = itmp; voc_m2 = innov[ivi + i]; voc_mean = .95f * voc_mean + .05f * excBuf[extIdx + i]; excBuf[extIdx + i] -= voc_mean; } } else { for (i = 0; i < subframeSize; i++) { excBuf[extIdx + i] += innov[ivi + i]; } } /* Decode second codebook (only for some modes) */ if (submodes[submodeID].DoubleCodebook != 0) { for (i = 0; i < subframeSize; i++) { innov2[i] = 0; } submodes[submodeID].Innovation.Unquantify(innov2, 0, subframeSize, bits); for (i = 0; i < subframeSize; i++) { innov2[i] *= ener * (1 / 2.2f); } for (i = 0; i < subframeSize; i++) { excBuf[extIdx + i] += innov2[i]; } } for (i = 0; i < subframeSize; i++) { frmBuf[spIdx + i] = excBuf[extIdx + i]; } /* Signal synthesis */ if (enhanced && submodes[submodeID].CombGain > 0) { filters.Comb_filter(excBuf, extIdx, frmBuf, spIdx, subframeSize, pitch, pitch_gain, submodes[submodeID].CombGain); } if (enhanced) { /* Use enhanced LPC filter */ NSpeex.Filters.Filter_mem2(frmBuf, spIdx, awk2, awk1, subframeSize, lpcSize, mem_sp, lpcSize); NSpeex.Filters.Filter_mem2(frmBuf, spIdx, awk3, interp_qlpc, subframeSize, lpcSize, mem_sp, 0); } else { /* Use regular filter */ for (i = 0; i < lpcSize; i++) { mem_sp[lpcSize + i] = 0; } NSpeex.Filters.Iir_mem2(frmBuf, spIdx, interp_qlpc, frmBuf, spIdx, subframeSize, lpcSize, mem_sp); } } /* Copy output signal */ xout[0] = frmBuf[frmIdx] + preemph * pre_mem; for (i = 1; i < frameSize; i++) { xout[i] = frmBuf[frmIdx + i] + preemph * xout[i - 1]; } pre_mem = xout[frameSize - 1]; /* Store the LSPs for interpolation in the next frame */ for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } /* The next frame will not be the first (Duh!) */ first = 0; count_lost = 0; last_pitch = best_pitch; last_pitch_gain = .25f * pitch_average; pitch_gain_buf[pitch_gain_buf_idx++] = last_pitch_gain; if (pitch_gain_buf_idx > 2) /* rollover */ { pitch_gain_buf_idx = 0; } last_ol_gain = ol_gain; return(0); }