public sealed override int Quant(float[] target, float[] sw, int sws, float[] ak, float[] awk1, float[] awk2, float[] exc, int es, int start, int end, float pitch_coef, int p, int nsf, Bits bits, float[] exc2, int e2s, float[] r, int complexity) { int[] array = new int[1]; int num = 0; int data = 0; int num2 = 0; float num3 = -1f; int num4 = complexity; if (num4 > 10) { num4 = 10; } int[] array2 = new int[num4]; float[] array3 = new float[num4]; if (num4 == 0 || end < start) { bits.Pack(0, this.pitch_bits); bits.Pack(0, this.gain_bits); for (int i = 0; i < nsf; i++) { exc[es + i] = 0f; } return(start); } float[] array4 = new float[nsf]; if (num4 > end - start + 1) { num4 = end - start + 1; } Ltp.Open_loop_nbest_pitch(sw, sws, start, end, nsf, array2, array3, num4); for (int i = 0; i < num4; i++) { num = array2[i]; for (int j = 0; j < nsf; j++) { exc[es + j] = 0f; } float num5 = this.Pitch_gain_search_3tap(target, ak, awk1, awk2, exc, es, num, p, nsf, bits, exc2, e2s, r, array); if (num5 < num3 || num3 < 0f) { for (int j = 0; j < nsf; j++) { array4[j] = exc[es + j]; } num3 = num5; num2 = num; data = array[0]; } } bits.Pack(num2 - start, this.pitch_bits); bits.Pack(data, this.gain_bits); for (int i = 0; i < nsf; i++) { exc[es + i] = array4[i]; } return(num); }
/// <summary> /// Line Spectral Pair Quantification (Lbr). /// </summary> public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits) { int i; float tmp1, tmp2; int id; float[] quant_weight = new float[NSpeex.LspQuant.MAX_LSP_SIZE]; for (i = 0; i < order; i++) { qlsp[i] = lsp[i]; } quant_weight[0] = 1 / (qlsp[1] - qlsp[0]); quant_weight[order - 1] = 1 / (qlsp[order - 1] - qlsp[order - 2]); for (i = 1; i < order - 1; i++) { tmp1 = 1 / ((.15f + qlsp[i] - qlsp[i - 1]) * (.15f + qlsp[i] - qlsp[i - 1])); tmp2 = 1 / ((.15f + qlsp[i + 1] - qlsp[i]) * (.15f + qlsp[i + 1] - qlsp[i])); quant_weight[i] = (tmp1 > tmp2) ? tmp1 : tmp2; } for (i = 0; i < order; i++) { qlsp[i] -= ((Single?)(.25d * i + .25d)).Value; } for (i = 0; i < order; i++) { qlsp[i] *= 256; } id = NSpeex.LspQuant.Lsp_quant(qlsp, 0, NSpeex.Codebook_Constants.cdbk_nb, NSpeex.Codebook_Constants.NB_CDBK_SIZE, order); bits.Pack(id, 6); for (i = 0; i < order; i++) { qlsp[i] *= 2; } id = NSpeex.LspQuant.Lsp_weight_quant(qlsp, 0, quant_weight, 0, NSpeex.Codebook_Constants.cdbk_nb_low1, NSpeex.Codebook_Constants.NB_CDBK_SIZE_LOW1, 5); bits.Pack(id, 6); id = NSpeex.LspQuant.Lsp_weight_quant(qlsp, 5, quant_weight, 5, NSpeex.Codebook_Constants.cdbk_nb_high1, NSpeex.Codebook_Constants.NB_CDBK_SIZE_HIGH1, 5); bits.Pack(id, 6); for (i = 0; i < order; i++) { qlsp[i] *= ((Single?)0.0019531d).Value; } for (i = 0; i < order; i++) { qlsp[i] = lsp[i] - qlsp[i]; } }
public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits) { float[] array = new float[20]; for (int i = 0; i < order; i++) { qlsp[i] = lsp[i]; } array[0] = 1f / (qlsp[1] - qlsp[0]); array[order - 1] = 1f / (qlsp[order - 1] - qlsp[order - 2]); for (int i = 1; i < order - 1; i++) { float num = 1f / ((0.15f + qlsp[i] - qlsp[i - 1]) * (0.15f + qlsp[i] - qlsp[i - 1])); float num2 = 1f / ((0.15f + qlsp[i + 1] - qlsp[i]) * (0.15f + qlsp[i + 1] - qlsp[i])); array[i] = ((num <= num2) ? num2 : num); } for (int i = 0; i < order; i++) { qlsp[i] -= new float?((float)(0.25 * (double)i + 0.25)).Value; } for (int i = 0; i < order; i++) { qlsp[i] *= 256f; } int data = LspQuant.Lsp_quant(qlsp, 0, Codebook_Constants.cdbk_nb, 64, order); bits.Pack(data, 6); for (int i = 0; i < order; i++) { qlsp[i] *= 2f; } data = LspQuant.Lsp_weight_quant(qlsp, 0, array, 0, Codebook_Constants.cdbk_nb_low1, 64, 5); bits.Pack(data, 6); for (int i = 0; i < 5; i++) { qlsp[i] *= 2f; } data = LspQuant.Lsp_weight_quant(qlsp, 0, array, 0, Codebook_Constants.cdbk_nb_low2, 64, 5); bits.Pack(data, 6); data = LspQuant.Lsp_weight_quant(qlsp, 5, array, 5, Codebook_Constants.cdbk_nb_high1, 64, 5); bits.Pack(data, 6); for (int i = 5; i < 10; i++) { qlsp[i] *= 2f; } data = LspQuant.Lsp_weight_quant(qlsp, 5, array, 5, Codebook_Constants.cdbk_nb_high2, 64, 5); bits.Pack(data, 6); for (int i = 0; i < order; i++) { qlsp[i] *= new float?((float)0.00097656).Value; } for (int i = 0; i < order; i++) { qlsp[i] = lsp[i] - qlsp[i]; } }
/// <summary> /// Line Spectral Pair Quantification (high). /// </summary> public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits) { int i; int id; float[] quant_weight = new float[NSpeex.LspQuant.MAX_LSP_SIZE]; for (i = 0; i < order; i++) { qlsp[i] = lsp[i]; } quant_weight[0] = 1.0f / (qlsp[1] - qlsp[0]); quant_weight[order - 1] = 1.0f / (qlsp[order - 1] - qlsp[order - 2]); for (i = 1; i < order - 1; i++) { quant_weight[i] = Math.Max(1.0f / (qlsp[i] - qlsp[i - 1]), 1.0f / (qlsp[i + 1] - qlsp[i])); } for (i = 0; i < order; i++) { qlsp[i] -= .3125f * i + .75f; } for (i = 0; i < order; i++) { qlsp[i] *= 256; } id = NSpeex.LspQuant.Lsp_quant(qlsp, 0, NSpeex.Codebook_Constants.high_lsp_cdbk, 64, order); bits.Pack(id, 6); for (i = 0; i < order; i++) { qlsp[i] *= 2; } id = NSpeex.LspQuant.Lsp_weight_quant(qlsp, 0, quant_weight, 0, NSpeex.Codebook_Constants.high_lsp_cdbk2, 64, order); bits.Pack(id, 6); for (i = 0; i < order; i++) { qlsp[i] *= 0.0019531f; } for (i = 0; i < order; i++) { qlsp[i] = lsp[i] - qlsp[i]; } }
public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits) { float[] array = new float[20]; for (int i = 0; i < order; i++) { qlsp[i] = lsp[i]; } array[0] = 1f / (qlsp[1] - qlsp[0]); array[order - 1] = 1f / (qlsp[order - 1] - qlsp[order - 2]); for (int i = 1; i < order - 1; i++) { array[i] = Math.Max(1f / (qlsp[i] - qlsp[i - 1]), 1f / (qlsp[i + 1] - qlsp[i])); } for (int i = 0; i < order; i++) { qlsp[i] -= 0.3125f * (float)i + 0.75f; } for (int i = 0; i < order; i++) { qlsp[i] *= 256f; } int data = LspQuant.Lsp_quant(qlsp, 0, Codebook_Constants.high_lsp_cdbk, 64, order); bits.Pack(data, 6); for (int i = 0; i < order; i++) { qlsp[i] *= 2f; } data = LspQuant.Lsp_weight_quant(qlsp, 0, array, 0, Codebook_Constants.high_lsp_cdbk2, 64, order); bits.Pack(data, 6); for (int i = 0; i < order; i++) { qlsp[i] *= 0.0019531f; } for (int i = 0; i < order; i++) { qlsp[i] = lsp[i] - qlsp[i]; } }
/// <summary> /// Transforms a stereo frame into a mono frame and stores intensity stereo /// </summary> /// <param name="bits"></param> /// <param name="data"></param> /// <param name="frameSize"></param> public static void encode(Bits bits, float[] data, int frameSize) { int i, tmp; float e_left = 0, e_right = 0, e_tot = 0; float balance, e_ratio; for (i = 0; i < frameSize; i++) { e_left += data[2 * i] * data[2 * i]; e_right += data[2 * i + 1] * data[2 * i + 1]; data[i] = .5f * (data[2 * i] + data[2 * i + 1]); e_tot += data[i] * data[i]; } balance = (e_left + 1) / (e_right + 1); e_ratio = e_tot / (1 + e_left + e_right); /*Quantization*/ bits.Pack(14, 5); bits.Pack(SPEEX_INBAND_STEREO, 4); balance = (float)(4 * Math.Log(balance)); /*Pack balance*/ if (balance > 0) { bits.Pack(0, 1); } else { bits.Pack(1, 1); } balance = (float)Math.Floor(.5f + Math.Abs(balance)); if (balance > 30) { balance = 31; } bits.Pack((int)balance, 5); /*Quantize energy ratio*/ tmp = VQ.index(e_ratio, e_ratio_quant, 4); bits.Pack(tmp, 2); }
public static void Encode(Bits bits, float[] data, int frameSize) { float num = 0f; float num2 = 0f; float num3 = 0f; for (int i = 0; i < frameSize; i++) { num += data[2 * i] * data[2 * i]; num2 += data[2 * i + 1] * data[2 * i + 1]; data[i] = 0.5f * (data[2 * i] + data[2 * i + 1]); num3 += data[i] * data[i]; } float num4 = (num + 1f) / (num2 + 1f); float ins = num3 / (1f + num + num2); bits.Pack(14, 5); bits.Pack(9, 4); num4 = (float)(4.0 * Math.Log((double)num4)); if (num4 > 0f) { bits.Pack(0, 1); } else { bits.Pack(1, 1); } num4 = (float)Math.Floor((double)(0.5f + Math.Abs(num4))); if (num4 > 30f) { num4 = 31f; } bits.Pack((int)num4, 5); int data2 = VQ.Index(ins, Stereo.e_ratio_quant, 4); bits.Pack(data2, 2); }
/// <summary> /// Encode the given input signal. /// </summary> /// <returns>return 1 if successful.</returns> public virtual int Encode(Bits bits, float[] ins0) { int i; float[] res, target, mem; float[] syn_resp; float[] orig; /* Copy new data in input buffer */ System.Array.Copy(frmBuf, frameSize, frmBuf, 0, bufSize - frameSize); frmBuf[bufSize - frameSize] = ins0[0] - preemph * pre_mem; for (i = 1; i < frameSize; i++) { frmBuf[bufSize - frameSize + i] = ins0[i] - preemph * ins0[i - 1]; } pre_mem = ins0[frameSize - 1]; /* Move signals 1 frame towards the past */ System.Array.Copy(exc2Buf, frameSize, exc2Buf, 0, bufSize - frameSize); System.Array.Copy(excBuf, frameSize, excBuf, 0, bufSize - frameSize); System.Array.Copy(swBuf, frameSize, swBuf, 0, bufSize - frameSize); /* Window for analysis */ for (i = 0; i < windowSize; i++) { buf2[i] = frmBuf[i + frmIdx] * window[i]; } /* Compute auto-correlation */ NSpeex.Lpc.Autocorr(buf2, autocorr, lpcSize + 1, windowSize); autocorr[0] += 10; /* prevents NANs */ autocorr[0] *= lpc_floor; /* Noise floor in auto-correlation domain */ /* Lag windowing: equivalent to filtering in the power-spectrum domain */ for (i = 0; i < lpcSize + 1; i++) { autocorr[i] *= lagWindow[i]; } /* Levinson-Durbin */ NSpeex.Lpc.Wld(lpc, autocorr, rc, lpcSize); // tmperr System.Array.Copy(lpc, 0, lpc, 1, lpcSize); lpc[0] = 1; /* LPC to LSPs (x-domain) transform */ int roots = NSpeex.Lsp.Lpc2lsp(lpc, lpcSize, lsp, 15, 0.2f); /* Check if we found all the roots */ if (roots == lpcSize) { /* LSP x-domain to angle domain */ for (i = 0; i < lpcSize; i++) { lsp[i] = (float)System.Math.Acos(lsp[i]); } } else { /* Search again if we can afford it */ if (complexity > 1) { roots = NSpeex.Lsp.Lpc2lsp(lpc, lpcSize, lsp, 11, 0.05f); } if (roots == lpcSize) { /* LSP x-domain to angle domain */ for (i = 0; i < lpcSize; i++) { lsp[i] = (float)System.Math.Acos(lsp[i]); } } else { /* * If we can't find all LSP's, do some damage control and use * previous filter */ for (i = 0; i < lpcSize; i++) { lsp[i] = old_lsp[i]; } } } float lsp_dist = 0; for (i = 0; i < lpcSize; i++) { lsp_dist += (old_lsp[i] - lsp[i]) * (old_lsp[i] - lsp[i]); } /* * Whole frame analysis (open-loop estimation of pitch and excitation * gain) */ float ol_gain; int ol_pitch; float ol_pitch_coef; { if (first != 0) { for (i = 0; i < lpcSize; i++) { interp_lsp[i] = lsp[i]; } } else { for (i = 0; i < lpcSize; i++) { interp_lsp[i] = .375f * old_lsp[i] + .625f * lsp[i]; } } NSpeex.Lsp.Enforce_margin(interp_lsp, lpcSize, .002f); /* Compute interpolated LPCs (unquantized) for whole frame */ for (i = 0; i < lpcSize; i++) { interp_lsp[i] = (float)System.Math.Cos(interp_lsp[i]); } m_lsp.Lsp2lpc(interp_lsp, interp_lpc, lpcSize); /* Open-loop pitch */ if (submodes[submodeID] == null || vbr_enabled != 0 || vad_enabled != 0 || submodes[submodeID].ForcedPitchGain != 0 || submodes[submodeID].LbrPitch != -1) { int[] nol_pitch = new int[6]; float[] nol_pitch_coef = new float[6]; NSpeex.Filters.Bw_lpc(gamma1, interp_lpc, bw_lpc1, lpcSize); NSpeex.Filters.Bw_lpc(gamma2, interp_lpc, bw_lpc2, lpcSize); NSpeex.Filters.Filter_mem2(frmBuf, frmIdx, bw_lpc1, bw_lpc2, swBuf, swIdx, frameSize, lpcSize, mem_sw_whole, 0); NSpeex.Ltp.Open_loop_nbest_pitch(swBuf, swIdx, min_pitch, max_pitch, frameSize, nol_pitch, nol_pitch_coef, 6); ol_pitch = nol_pitch[0]; ol_pitch_coef = nol_pitch_coef[0]; /* Try to remove pitch multiples */ for (i = 1; i < 6; i++) { if ((nol_pitch_coef[i] > .85d * ol_pitch_coef) && (Math.Abs(nol_pitch[i] - ol_pitch / 2.0d) <= 1 || Math.Abs(nol_pitch[i] - ol_pitch / 3.0d) <= 1 || Math.Abs(nol_pitch[i] - ol_pitch / 4.0d) <= 1 || Math.Abs(nol_pitch[i] - ol_pitch / 5.0d) <= 1)) { /* ol_pitch_coef=nol_pitch_coef[i]; */ ol_pitch = nol_pitch[i]; } } /* * if (ol_pitch>50) ol_pitch/=2; */ /* ol_pitch_coef = sqrt(ol_pitch_coef); */ } else { ol_pitch = 0; ol_pitch_coef = 0; } /* Compute "real" excitation */ NSpeex.Filters.Fir_mem2(frmBuf, frmIdx, interp_lpc, excBuf, excIdx, frameSize, lpcSize, mem_exc); /* Compute open-loop excitation gain */ ol_gain = 0; for (i = 0; i < frameSize; i++) { ol_gain += excBuf[excIdx + i] * excBuf[excIdx + i]; } ol_gain = (float)Math.Sqrt(1 + ol_gain / frameSize); } /* VBR stuff */ if (vbr != null && (vbr_enabled != 0 || vad_enabled != 0)) { if (abr_enabled != 0) { float qual_change = 0; if (abr_drift2 * abr_drift > 0) { /* * Only adapt if long-term and short-term drift are the same * sign */ qual_change = -.00001f * abr_drift / (1 + abr_count); if (qual_change > .05f) { qual_change = .05f; } if (qual_change < -.05f) { qual_change = -.05f; } } vbr_quality += qual_change; if (vbr_quality > 10) { vbr_quality = 10; } if (vbr_quality < 0) { vbr_quality = 0; } } relative_quality = vbr.Analysis(ins0, frameSize, ol_pitch, ol_pitch_coef); /* if (delta_qual<0) */ /* delta_qual*=.1*(3+st->vbr_quality); */ if (vbr_enabled != 0) { int mode; int choice = 0; float min_diff = 100; mode = 8; while (mode > 0) { int v1; float thresh; v1 = (int)Math.Floor(vbr_quality); if (v1 == 10) { thresh = NSpeex.Vbr.nb_thresh[mode][v1]; } else { thresh = (vbr_quality - v1) * NSpeex.Vbr.nb_thresh[mode][v1 + 1] + (1 + v1 - vbr_quality) * NSpeex.Vbr.nb_thresh[mode][v1]; } if (relative_quality > thresh && relative_quality - thresh < min_diff) { choice = mode; min_diff = relative_quality - thresh; } mode--; } mode = choice; if (mode == 0) { if (dtx_count == 0 || lsp_dist > .05d || dtx_enabled == 0 || dtx_count > 20) { mode = 1; dtx_count = 1; } else { mode = 0; dtx_count++; } } else { dtx_count = 0; } Mode = mode; if (abr_enabled != 0) { int bitrate; bitrate = BitRate; abr_drift += (bitrate - abr_enabled); abr_drift2 = .95f * abr_drift2 + .05f * (bitrate - abr_enabled); abr_count += ((Single?)1.0d).Value; } } else { /* VAD only case */ int mode_0; if (relative_quality < 2) { if (dtx_count == 0 || lsp_dist > .05d || dtx_enabled == 0 || dtx_count > 20) { dtx_count = 1; mode_0 = 1; } else { mode_0 = 0; dtx_count++; } } else { dtx_count = 0; mode_0 = submodeSelect; } /* speex_encoder_ctl(state, SPEEX_SET_MODE, &mode); */ submodeID = mode_0; } } else { relative_quality = -1; } /* First, transmit a zero for narrowband */ bits.Pack(0, 1); /* Transmit the sub-mode we use for this frame */ bits.Pack(submodeID, NSpeex.NbCodec.NB_SUBMODE_BITS); /* If null mode (no transmission), just set a couple things to zero */ if (submodes[submodeID] == null) { for (i = 0; i < frameSize; i++) { excBuf[excIdx + i] = exc2Buf[exc2Idx + i] = swBuf[swIdx + i] = NSpeex.NbCodec.VERY_SMALL; } for (i = 0; i < lpcSize; i++) { mem_sw[i] = 0; } first = 1; bounded_pitch = 1; /* Final signal synthesis from excitation */ NSpeex.Filters.Iir_mem2(excBuf, excIdx, interp_qlpc, frmBuf, frmIdx, frameSize, lpcSize, mem_sp); ins0[0] = frmBuf[frmIdx] + preemph * pre_mem2; for (i = 1; i < frameSize; i++) { ins0[i] = frmBuf[frmIdx = i] + preemph * ins0[i - 1]; } pre_mem2 = ins0[frameSize - 1]; return(0); } /* LSP Quantization */ if (first != 0) { for (i = 0; i < lpcSize; i++) { old_lsp[i] = lsp[i]; } } /* Quantize LSPs */ // #if 1 /*0 for unquantized*/ submodes[submodeID].LsqQuant.Quant(lsp, qlsp, lpcSize, bits); // #else // for (i=0;i<lpcSize;i++) // qlsp[i]=lsp[i]; // #endif /* If we use low bit-rate pitch mode, transmit open-loop pitch */ if (submodes[submodeID].LbrPitch != -1) { bits.Pack(ol_pitch - min_pitch, 7); } if (submodes[submodeID].ForcedPitchGain != 0) { int quant; quant = (int)Math.Floor(.5d + 15 * ol_pitch_coef); if (quant > 15) { quant = 15; } if (quant < 0) { quant = 0; } bits.Pack(quant, 4); ol_pitch_coef = (float)0.066667d * quant; } /* Quantize and transmit open-loop excitation gain */ { int qe = (int)(Math.Floor(0.5d + 3.5d * Math.Log(ol_gain))); if (qe < 0) { qe = 0; } if (qe > 31) { qe = 31; } ol_gain = (float)Math.Exp(qe / 3.5d); bits.Pack(qe, 5); } /* Special case for first frame */ if (first != 0) { for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } } /* Filter response */ res = new float[subframeSize]; /* Target signal */ target = new float[subframeSize]; syn_resp = new float[subframeSize]; mem = new float[lpcSize]; orig = new float[frameSize]; for (i = 0; i < frameSize; i++) { orig[i] = frmBuf[frmIdx + i]; } /* Loop on sub-frames */ for (int sub = 0; sub < nbSubframes; sub++) { float tmp; int offset; int sp, sw, exc, exc2; int pitchval; /* Offset relative to start of frame */ offset = subframeSize * sub; /* Original signal */ sp = frmIdx + offset; /* Excitation */ exc = excIdx + offset; /* Weighted signal */ sw = swIdx + offset; exc2 = exc2Idx + offset; /* LSP interpolation (quantized and unquantized) */ tmp = (float)(1.0d + sub) / nbSubframes; for (i = 0; i < lpcSize; i++) { interp_lsp[i] = (1 - tmp) * old_lsp[i] + tmp * lsp[i]; } for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i]; } /* Make sure the filters are stable */ NSpeex.Lsp.Enforce_margin(interp_lsp, lpcSize, .002f); NSpeex.Lsp.Enforce_margin(interp_qlsp, lpcSize, .002f); /* Compute interpolated LPCs (quantized and unquantized) */ for (i = 0; i < lpcSize; i++) { interp_lsp[i] = (float)System.Math.Cos(interp_lsp[i]); } m_lsp.Lsp2lpc(interp_lsp, interp_lpc, lpcSize); 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 analysis filter gain at w=pi (for use in SB-CELP) */ tmp = 1; pi_gain[sub] = 0; for (i = 0; i <= lpcSize; i++) { pi_gain[sub] += tmp * interp_qlpc[i]; tmp = -tmp; } /* * Compute bandwidth-expanded (unquantized) LPCs for perceptual * weighting */ NSpeex.Filters.Bw_lpc(gamma1, interp_lpc, bw_lpc1, lpcSize); if (gamma2 >= 0) { NSpeex.Filters.Bw_lpc(gamma2, interp_lpc, bw_lpc2, lpcSize); } else { bw_lpc2[0] = 1; bw_lpc2[1] = -preemph; for (i = 2; i <= lpcSize; i++) { bw_lpc2[i] = 0; } } /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) ) */ for (i = 0; i < subframeSize; i++) { excBuf[exc + i] = 0; } excBuf[exc] = 1; NSpeex.Filters.Syn_percep_zero(excBuf, exc, interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, subframeSize, lpcSize); /* Reset excitation */ for (i = 0; i < subframeSize; i++) { excBuf[exc + i] = 0; } for (i = 0; i < subframeSize; i++) { exc2Buf[exc2 + i] = 0; } /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */ for (i = 0; i < lpcSize; i++) { mem[i] = mem_sp[i]; } NSpeex.Filters.Iir_mem2(excBuf, exc, interp_qlpc, excBuf, exc, subframeSize, lpcSize, mem); for (i = 0; i < lpcSize; i++) { mem[i] = mem_sw[i]; } NSpeex.Filters.Filter_mem2(excBuf, exc, bw_lpc1, bw_lpc2, res, 0, subframeSize, lpcSize, mem, 0); /* Compute weighted signal */ for (i = 0; i < lpcSize; i++) { mem[i] = mem_sw[i]; } NSpeex.Filters.Filter_mem2(frmBuf, sp, bw_lpc1, bw_lpc2, swBuf, sw, subframeSize, lpcSize, mem, 0); /* Compute target signal */ for (i = 0; i < subframeSize; i++) { target[i] = swBuf[sw + i] - res[i]; } for (i = 0; i < subframeSize; i++) { excBuf[exc + i] = exc2Buf[exc2 + i] = 0; } /* If we have a long-term predictor (otherwise, something's wrong) */ // if (submodes[submodeID].ltp.quant) // { int pit_min, pit_max; /* Long-term prediction */ if (submodes[submodeID].LbrPitch != -1) { /* Low bit-rate pitch handling */ int margin; margin = submodes[submodeID].LbrPitch; if (margin != 0) { if (ol_pitch < min_pitch + margin - 1) { ol_pitch = min_pitch + margin - 1; } if (ol_pitch > max_pitch - margin) { ol_pitch = max_pitch - margin; } pit_min = ol_pitch - margin + 1; pit_max = ol_pitch + margin; } else { pit_min = pit_max = ol_pitch; } } else { pit_min = min_pitch; pit_max = max_pitch; } /* Force pitch to use only the current frame if needed */ if (bounded_pitch != 0 && pit_max > offset) { pit_max = offset; } /* Perform pitch search */ pitchval = submodes[submodeID].Ltp.Quant(target, swBuf, sw, interp_qlpc, bw_lpc1, bw_lpc2, excBuf, exc, pit_min, pit_max, ol_pitch_coef, lpcSize, subframeSize, bits, exc2Buf, exc2, syn_resp, complexity); pitch[sub] = pitchval; // } else { // speex_error ("No pitch prediction, what's wrong"); // } /* Update target for adaptive codebook contribution */ NSpeex.Filters.Syn_percep_zero(excBuf, exc, interp_qlpc, bw_lpc1, bw_lpc2, res, subframeSize, lpcSize); for (i = 0; i < subframeSize; i++) { target[i] -= res[i]; } /* Quantization of innovation */ { int innovptr; float ener = 0, ener_1; innovptr = sub * subframeSize; for (i = 0; i < subframeSize; i++) { innov[innovptr + i] = 0; } NSpeex.Filters.Residue_percep_zero(target, 0, interp_qlpc, bw_lpc1, bw_lpc2, buf2, subframeSize, lpcSize); for (i = 0; i < subframeSize; i++) { ener += buf2[i] * buf2[i]; } ener = (float)Math.Sqrt(.1f + ener / subframeSize); /* * for (i=0;i<subframeSize;i++) System.out.print(buf2[i]/ener + * "\t"); */ ener /= ol_gain; /* Calculate gain correction for the sub-frame (if any) */ if (submodes[submodeID].HaveSubframeGain != 0) { int qe_1; ener = (float)Math.Log(ener); if (submodes[submodeID].HaveSubframeGain == 3) { qe_1 = NSpeex.VQ.Index(ener, NSpeex.NbCodec.exc_gain_quant_scal3, 8); bits.Pack(qe_1, 3); ener = NSpeex.NbCodec.exc_gain_quant_scal3[qe_1]; } else { qe_1 = NSpeex.VQ.Index(ener, NSpeex.NbCodec.exc_gain_quant_scal1, 2); bits.Pack(qe_1, 1); ener = NSpeex.NbCodec.exc_gain_quant_scal1[qe_1]; } ener = (float)Math.Exp(ener); } else { ener = 1; } ener *= ol_gain; /* System.out.println(ener + " " + ol_gain); */ ener_1 = 1 / ener; /* Normalize innovation */ for (i = 0; i < subframeSize; i++) { target[i] *= ener_1; } /* Quantize innovation */ // if (submodes[submodeID].innovation != null) // { /* Codebook search */ submodes[submodeID].Innovation.Quantify(target, interp_qlpc, bw_lpc1, bw_lpc2, lpcSize, subframeSize, innov, innovptr, syn_resp, bits, complexity); /* De-normalize innovation and update excitation */ for (i = 0; i < subframeSize; i++) { innov[innovptr + i] *= ener; } for (i = 0; i < subframeSize; i++) { excBuf[exc + i] += innov[innovptr + i]; } // } else { // speex_error("No fixed codebook"); // } /* * In some (rare) modes, we do a second search (more bits) to * reduce noise even more */ if (submodes[submodeID].DoubleCodebook != 0) { float[] innov2_2 = new float[subframeSize]; // for (i=0;i<subframeSize;i++) // innov2[i]=0; for (i = 0; i < subframeSize; i++) { target[i] *= 2.2f; } submodes[submodeID].Innovation.Quantify(target, interp_qlpc, bw_lpc1, bw_lpc2, lpcSize, subframeSize, innov2_2, 0, syn_resp, bits, complexity); for (i = 0; i < subframeSize; i++) { innov2_2[i] *= (float)(ener * (1 / 2.2d)); } for (i = 0; i < subframeSize; i++) { excBuf[exc + i] += innov2_2[i]; } } for (i = 0; i < subframeSize; i++) { target[i] *= ener; } } /* Keep the previous memory */ for (i = 0; i < lpcSize; i++) { mem[i] = mem_sp[i]; } /* Final signal synthesis from excitation */ NSpeex.Filters.Iir_mem2(excBuf, exc, interp_qlpc, frmBuf, sp, subframeSize, lpcSize, mem_sp); /* * Compute weighted signal again, from synthesized speech (not sure * it's the right thing) */ NSpeex.Filters.Filter_mem2(frmBuf, sp, bw_lpc1, bw_lpc2, swBuf, sw, subframeSize, lpcSize, mem_sw, 0); for (i = 0; i < subframeSize; i++) { exc2Buf[exc2 + i] = excBuf[exc + i]; } } /* Store the LSPs for interpolation in the next frame */ if (submodeID >= 1) { for (i = 0; i < lpcSize; i++) { old_lsp[i] = lsp[i]; } for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } } if (submodeID == 1) { if (dtx_count != 0) { bits.Pack(15, 4); } else { bits.Pack(0, 4); } } /* The next frame will not be the first (Duh!) */ first = 0; { float ener_3 = 0, err = 0; float snr; for (i = 0; i < frameSize; i++) { ener_3 += frmBuf[frmIdx + i] * frmBuf[frmIdx + i]; err += (frmBuf[frmIdx + i] - orig[i]) * (frmBuf[frmIdx + i] - orig[i]); } snr = (float)(10 * Math.Log((ener_3 + 1) / (err + 1))); /* * System.out.println("Frame result: SNR="+snr+" E="+ener+" * Err="+err+"\r\n"); */ } /* Replace input by synthesized speech */ ins0[0] = frmBuf[frmIdx] + preemph * pre_mem2; for (i = 1; i < frameSize; i++) { ins0[i] = frmBuf[frmIdx + i] + preemph * ins0[i - 1]; } pre_mem2 = ins0[frameSize - 1]; if (submodes[submodeID].Innovation is NoiseSearch || submodeID == 0) { bounded_pitch = 1; } else { bounded_pitch = 0; } return(1); }
/// <summary> /// Long Term Prediction Quantification (3Tap). /// </summary> /// <returns>pitch</returns> public sealed override int Quant( float[] target, float[] sw, int sws, float[] ak, float[] awk1, float[] awk2, float[] exc, int es, int start, int end, float pitch_coef, int p, int nsf, Bits bits, float[] exc2, int e2s, float[] r, int complexity) { int i, j; int[] cdbk_index = new int[1]; int pitch = 0, best_gain_index = 0; float[] best_exc; int best_pitch = 0; float err, best_err = -1; int N; int[] nbest; float[] gains; N = complexity; if (N > 10) { N = 10; } nbest = new int[N]; gains = new float[N]; if (N == 0 || end < start) { bits.Pack(0, pitch_bits); bits.Pack(0, gain_bits); for (i = 0; i < nsf; i++) { exc[es + i] = 0; } return(start); } best_exc = new float[nsf]; if (N > end - start + 1) { N = end - start + 1; } NSpeex.Ltp.Open_loop_nbest_pitch(sw, sws, start, end, nsf, nbest, gains, N); for (i = 0; i < N; i++) { pitch = nbest[i]; for (j = 0; j < nsf; j++) { exc[es + j] = 0; } err = Pitch_gain_search_3tap(target, ak, awk1, awk2, exc, es, pitch, p, nsf, bits, exc2, e2s, r, cdbk_index); if (err < best_err || best_err < 0) { for (j = 0; j < nsf; j++) { best_exc[j] = exc[es + j]; } best_err = err; best_pitch = pitch; best_gain_index = cdbk_index[0]; } } bits.Pack(best_pitch - start, pitch_bits); bits.Pack(best_gain_index, gain_bits); for (i = 0; i < nsf; i++) { exc[es + i] = best_exc[i]; } return(pitch); }
/// <summary> /// Encode the given input signal. /// </summary> /// <param name="bits">Speex bits buffer.</param> /// <param name="vin">the raw mono audio frame to encode</param> /// <returns>1 if successful.</returns> public int Encode(Bits bits, float[] vin) { int i; float[] mem, innov, syn_resp; float[] low_pi_gain, low_exc, low_innov; int dtx; /* Compute the two sub-bands by filtering with h0 and h1*/ Filters.qmf_decomp(vin, h0, x0d, x1d, fullFrameSize, QMF_ORDER, h0_mem); /* Encode the narrowband part*/ lowenc.Encode(bits, x0d); /* High-band buffering / sync with low band */ for (i = 0; i < windowSize - frameSize; i++) { high[i] = high[frameSize + i]; } for (i = 0; i < frameSize; i++) { high[windowSize - frameSize + i] = x1d[i]; } Array.Copy(excBuf, frameSize, excBuf, 0, bufSize - frameSize); low_pi_gain = lowenc.PitchGain; low_exc = lowenc.Excitation; low_innov = lowenc.Innovation; int low_mode = lowenc.Mode; if (low_mode == 0) { dtx = 1; } else { dtx = 0; } /* Start encoding the high-band */ for (i = 0; i < windowSize; i++) { buf[i] = high[i] * window[i]; } /* Compute auto-correlation */ Lpc.autocorr(buf, autocorr, lpcSize + 1, windowSize); autocorr[0] += 1; /* prevents NANs */ autocorr[0] *= lpc_floor; /* Noise floor in auto-correlation domain */ /* Lag windowing: equivalent to filtering in the power-spectrum domain */ for (i = 0; i < lpcSize + 1; i++) { autocorr[i] *= lagWindow[i]; } /* Levinson-Durbin */ Lpc.wld(lpc, autocorr, rc, lpcSize); // tmperr Array.Copy(lpc, 0, lpc, 1, lpcSize); lpc[0] = 1; /* LPC to LSPs (x-domain) transform */ int roots = Lsp.lpc2lsp(lpc, lpcSize, lsp, 15, 0.2f); if (roots != lpcSize) { roots = Lsp.lpc2lsp(lpc, lpcSize, lsp, 11, 0.02f); if (roots != lpcSize) { /*If we can't find all LSP's, do some damage control and use a flat filter*/ for (i = 0; i < lpcSize; i++) { lsp[i] = (float)Math.Cos(Math.PI * ((float)(i + 1)) / (lpcSize + 1)); } } } /* x-domain to angle domain*/ for (i = 0; i < lpcSize; i++) { lsp[i] = (float)Math.Acos(lsp[i]); } float lsp_dist = 0; for (i = 0; i < lpcSize; i++) { lsp_dist += (old_lsp[i] - lsp[i]) * (old_lsp[i] - lsp[i]); } /*VBR stuff*/ if ((vbr_enabled != 0 || vad_enabled != 0) && dtx == 0) { float e_low = 0, e_high = 0; float ratio; if (abr_enabled != 0) { float qual_change = 0; if (abr_drift2 * abr_drift > 0) { /* Only adapt if long-term and short-term drift are the same sign */ qual_change = -.00001f * abr_drift / (1 + abr_count); if (qual_change > .1f) { qual_change = .1f; } if (qual_change < -.1f) { qual_change = -.1f; } } vbr_quality += qual_change; if (vbr_quality > 10) { vbr_quality = 10; } if (vbr_quality < 0) { vbr_quality = 0; } } for (i = 0; i < frameSize; i++) { e_low += x0d[i] * x0d[i]; e_high += high[i] * high[i]; } ratio = (float)Math.Log((1 + e_high) / (1 + e_low)); relative_quality = lowenc.RelativeQuality; if (ratio < -4) { ratio = -4; } if (ratio > 2) { ratio = 2; } /*if (ratio>-2)*/ if (vbr_enabled != 0) { int modeid; modeid = nb_modes - 1; relative_quality += 1.0f * (ratio + 2f); if (relative_quality < -1) { relative_quality = -1; } while (modeid != 0) { int v1; float thresh; v1 = (int)Math.Floor(vbr_quality); if (v1 == 10) { thresh = NSpeex.Vbr.hb_thresh[modeid][v1]; } else { thresh = (vbr_quality - v1) * NSpeex.Vbr.hb_thresh[modeid][v1 + 1] + (1 + v1 - vbr_quality) * NSpeex.Vbr.hb_thresh[modeid][v1]; } if (relative_quality >= thresh) { break; } modeid--; } Mode = modeid; if (abr_enabled != 0) { int bitrate = BitRate; abr_drift += (bitrate - abr_enabled); abr_drift2 = .95f * abr_drift2 + .05f * (bitrate - abr_enabled); abr_count += 1.0f; } } else { /* VAD only */ int modeid; if (relative_quality < 2.0) { modeid = 1; } else { modeid = submodeSelect; } /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ submodeID = modeid; } } bits.Pack(1, 1); if (dtx != 0) { bits.Pack(0, SB_SUBMODE_BITS); } else { bits.Pack(submodeID, SB_SUBMODE_BITS); } /* If null mode (no transmission), just set a couple things to zero*/ if (dtx != 0 || submodes[submodeID] == null) { for (i = 0; i < frameSize; i++) { excBuf[excIdx + i] = swBuf[i] = VERY_SMALL; } for (i = 0; i < lpcSize; i++) { mem_sw[i] = 0; } first = 1; /* Final signal synthesis from excitation */ Filters.iir_mem2(excBuf, excIdx, interp_qlpc, high, 0, subframeSize, lpcSize, mem_sp); /* Reconstruct the original */ 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++) { vin[i] = 2 * (y0[i] - y1[i]); } if (dtx != 0) { return(0); } else { return(1); } } /* LSP quantization */ submodes[submodeID].lsqQuant.quant(lsp, qlsp, lpcSize, bits); if (first != 0) { for (i = 0; i < lpcSize; i++) { old_lsp[i] = lsp[i]; } for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } } mem = new float[lpcSize]; syn_resp = new float[subframeSize]; innov = new float[subframeSize]; for (int sub = 0; sub < nbSubframes; sub++) { float tmp, filter_ratio; int exc, sp, sw, resp; int offset; float rl, rh, eh = 0, el = 0; int fold; offset = subframeSize * sub; sp = offset; exc = excIdx + offset; resp = offset; sw = offset; /* LSP interpolation (quantized and unquantized) */ tmp = (1.0f + sub) / nbSubframes; for (i = 0; i < lpcSize; i++) { interp_lsp[i] = (1 - tmp) * old_lsp[i] + tmp * lsp[i]; } for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i]; } Lsp.enforce_margin(interp_lsp, lpcSize, .05f); Lsp.enforce_margin(interp_qlsp, lpcSize, .05f); /* Compute interpolated LPCs (quantized and unquantized) */ for (i = 0; i < lpcSize; i++) { interp_lsp[i] = (float)Math.Cos(interp_lsp[i]); } for (i = 0; i < lpcSize; i++) { interp_qlsp[i] = (float)Math.Cos(interp_qlsp[i]); } m_lsp.lsp2lpc(interp_lsp, interp_lpc, lpcSize); m_lsp.lsp2lpc(interp_qlsp, interp_qlpc, lpcSize); Filters.bw_lpc(gamma1, interp_lpc, bw_lpc1, lpcSize); Filters.bw_lpc(gamma2, interp_lpc, bw_lpc2, lpcSize); /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band * filters */ rl = rh = 0; 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); /* Compute ratio, will help predict the gain */ filter_ratio = Math.Abs(.01f + rh) / (.01f + Math.Abs(rl)); fold = filter_ratio < 5 ? 1 : 0; /*printf ("filter_ratio %f\n", filter_ratio);*/ fold = 0; /* Compute "real excitation" */ Filters.fir_mem2(high, sp, interp_qlpc, excBuf, exc, subframeSize, lpcSize, mem_sp2); /* Compute energy of low-band and high-band excitation */ for (i = 0; i < subframeSize; i++) { eh += excBuf[exc + i] * excBuf[exc + i]; } if (submodes[submodeID].innovation == null) { float g; /*speex_bits_pack(bits, 1, 1);*/ for (i = 0; i < subframeSize; i++) { el += low_innov[offset + i] * low_innov[offset + i]; } /* Gain to use if we want to use the low-band excitation for high-band */ g = eh / (.01f + el); g = (float)Math.Sqrt(g); g *= filter_ratio; int quant = (int)Math.Floor(.5 + 10 + 8.0 * Math.Log((g + .0001))); /*speex_warning_int("tata", quant);*/ if (quant < 0) { quant = 0; } if (quant > 31) { quant = 31; } bits.Pack(quant, 5); g = (float)(.1 * Math.Exp(quant / 9.4)); g /= filter_ratio; } else { float gc, scale, scale_1; for (i = 0; i < subframeSize; i++) { el += low_exc[offset + i] * low_exc[offset + i]; } gc = (float)(Math.Sqrt(1 + eh) * filter_ratio / Math.Sqrt((1 + el) * subframeSize)); { int qgc = (int)Math.Floor(.5 + 3.7 * (Math.Log(gc) + 2)); if (qgc < 0) { qgc = 0; } if (qgc > 15) { qgc = 15; } bits.Pack(qgc, 4); gc = (float)Math.Exp((1 / 3.7) * qgc - 2); } scale = gc * (float)Math.Sqrt(1 + el) / filter_ratio; scale_1 = 1 / scale; for (i = 0; i < subframeSize; i++) { excBuf[exc + i] = 0; } excBuf[exc] = 1; Filters.syn_percep_zero(excBuf, exc, interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, subframeSize, lpcSize); /* Reset excitation */ for (i = 0; i < subframeSize; i++) { excBuf[exc + i] = 0; } /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ for (i = 0; i < lpcSize; i++) { mem[i] = mem_sp[i]; } Filters.iir_mem2(excBuf, exc, interp_qlpc, excBuf, exc, subframeSize, lpcSize, mem); for (i = 0; i < lpcSize; i++) { mem[i] = mem_sw[i]; } Filters.filter_mem2(excBuf, exc, bw_lpc1, bw_lpc2, res, resp, subframeSize, lpcSize, mem, 0); /* Compute weighted signal */ for (i = 0; i < lpcSize; i++) { mem[i] = mem_sw[i]; } Filters.filter_mem2(high, sp, bw_lpc1, bw_lpc2, swBuf, sw, subframeSize, lpcSize, mem, 0); /* Compute target signal */ for (i = 0; i < subframeSize; i++) { target[i] = swBuf[sw + i] - res[resp + i]; } for (i = 0; i < subframeSize; i++) { excBuf[exc + i] = 0; } for (i = 0; i < subframeSize; i++) { target[i] *= scale_1; } /* Reset excitation */ for (i = 0; i < subframeSize; i++) { innov[i] = 0; } /*print_vec(target, st->subframeSize, "\ntarget");*/ submodes[submodeID].innovation.Quant(target, interp_qlpc, bw_lpc1, bw_lpc2, lpcSize, subframeSize, innov, 0, syn_resp, bits, (complexity + 1) >> 1); /*print_vec(target, st->subframeSize, "after");*/ for (i = 0; i < subframeSize; i++) { excBuf[exc + i] += innov[i] * scale; } if (submodes[submodeID].double_codebook != 0) { float[] innov2 = new float[subframeSize]; for (i = 0; i < subframeSize; i++) { innov2[i] = 0; } for (i = 0; i < subframeSize; i++) { target[i] *= 2.5f; } submodes[submodeID].innovation.Quant(target, interp_qlpc, bw_lpc1, bw_lpc2, lpcSize, subframeSize, innov2, 0, syn_resp, bits, (complexity + 1) >> 1); for (i = 0; i < subframeSize; i++) { innov2[i] *= scale * (1f / 2.5f); } for (i = 0; i < subframeSize; i++) { excBuf[exc + i] += innov2[i]; } } } /*Keep the previous memory*/ for (i = 0; i < lpcSize; i++) { mem[i] = mem_sp[i]; } /* Final signal synthesis from excitation */ Filters.iir_mem2(excBuf, exc, interp_qlpc, high, sp, subframeSize, lpcSize, mem_sp); /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ Filters.filter_mem2(high, sp, bw_lpc1, bw_lpc2, swBuf, sw, subframeSize, lpcSize, mem_sw, 0); } //#ifndef RELEASE /* Reconstruct the original */ 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++) { vin[i] = 2 * (y0[i] - y1[i]); } //#endif for (i = 0; i < lpcSize; i++) { old_lsp[i] = lsp[i]; } for (i = 0; i < lpcSize; i++) { old_qlsp[i] = qlsp[i]; } first = 0; return(1); }
/// <summary> /// Codebook Search Quantification (Split Shape). /// </summary> /// <param name="target">target vector</param> /// <param name="ak">LPCs for this subframe</param> /// <param name="awk1">Weighted LPCs for this subframe</param> /// <param name="awk2">Weighted LPCs for this subframe</param> /// <param name="p">number of LPC coeffs</param> /// <param name="nsf">number of samples in subframe</param> /// <param name="exc">excitation array.</param> /// <param name="es">position in excitation array.</param> /// <param name="r"></param> /// <param name="bits">Speex bits buffer.</param> /// <param name="complexity"></param> public sealed override void Quantify( SpeexWord16[] target, SpeexWord16[] ak, SpeexWord16[] awk1, SpeexWord16[] awk2, int p, int nsf, SpeexWord32[] exc, int es, SpeexWord16[] r, Bits bits, int complexity) { int i, j, k, m, n, q; SpeexWord16[] resp; SpeexWord32[] ndist, odist; int[] best_index; SpeexWord32[] best_dist; int[] best_nind; int[] best_ntarget; int N = complexity; if (N > 10) { N = 10; } resp = new SpeexWord16[shape_cb_size * subvect_size]; best_index = new int[N]; best_dist = new SpeexWord32[N]; ndist = new SpeexWord32[N]; odist = new SpeexWord32[N]; best_nind = new int[N]; best_ntarget = new int[N]; for (i = 0; i < N; i++) { for (j = 0; j < nb_subvect; j++) { nind[i, j] = oind[i, j] = -1; } } for (j = 0; j < N; j++) { for (i = 0; i < nsf; i++) { ot[j][i] = target[i]; } } // System.arraycopy(target, 0, t, 0, nsf); /* Pre-compute codewords response and energy */ for (i = 0; i < shape_cb_size; i++) { int res; int shape; res = i * subvect_size; shape = i * subvect_size; /* Compute codeword response using convolution with impulse response */ for (j = 0; j < subvect_size; j++) { resp[res + j] = 0; for (k = 0; k <= j; k++) #if FIXED_POINT { resp[res + j] += (short)((shape_cb[shape + k] * r[j - k]) >> 13); } #else { resp[res + j] += 0.03125f * shape_cb[shape + k] * r[j - k]; } #endif } /* Compute codeword energy */ E[i] = 0; for (j = 0; j < subvect_size; j++) { E[i] += resp[res + j] * resp[res + j]; } } for (j = 0; j < N; j++) { odist[j] = 0; } /* For all subvectors */ for (i = 0; i < nb_subvect; i++) { int offset = i * subvect_size; /* "erase" nbest list */ for (j = 0; j < N; j++) { ndist[j] = Int32.MaxValue; } /* This is not strictly necessary, but it provides an additonal safety * to prevent crashes in case something goes wrong in the previous * steps (e.g. NaNs) */ for (j = 0; j < N; j++) { best_nind[j] = best_ntarget[j] = 0; } /* For all n-bests of previous subvector */ for (j = 0; j < N; j++) { SpeexWord32 tener = 0; for (m = offset; m < offset + subvect_size; m++) { tener += ot[j][m] * ot[j][m]; } #if FIXED_POINT tener = tener >> 1; #else tener *= 0.5f; #endif /* Find new n-best based on previous n-best j */ if (have_sign != 0) { NSpeex.VQ.Nbest_sign( ot[j], offset, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist); } else { NSpeex.VQ.Nbest( ot[j], offset, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist); } /* For all new n-bests */ for (k = 0; k < N; k++) { /* Compute total distance (including previous sub-vectors */ SpeexWord32 err = odist[j] + best_dist[k] + tener; /* Update n-best list */ if (err < ndist[N - 1]) { for (m = 0; m < N; m++) { if (err < ndist[m]) { for (n = N - 1; n > m; n--) { ndist[n] = ndist[n - 1]; best_nind[n] = best_nind[n - 1]; best_ntarget[n] = best_ntarget[n - 1]; } /* n is equal to m here, so they're interchangeable */ ndist[m] = err; best_nind[n] = best_index[k]; best_ntarget[n] = j; break; } } } } if (i == 0) { break; } } for (j = 0; j < N; j++) { /*previous target (we don't care what happened before*/ for (m = (i + 1) * subvect_size; m < nsf; m++) { nt[j][m] = ot[best_ntarget[j]][m]; } /* New code: update the rest of the target only if it's worth it */ for (m = 0; m < subvect_size; m++) { SpeexWord16 g; int rind; SpeexWord16 sign = 1; rind = best_nind[j]; if (rind >= shape_cb_size) { sign = -1; rind -= shape_cb_size; } q = subvect_size - m; #if FIXED_POINT g = (short)(sign * shape_cb[rind * subvect_size + m]); #else g = sign * 0.03125f * shape_cb[rind * subvect_size + m]; #endif int ni; for (n = 0, ni = offset + subvect_size; n < nsf - subvect_size * (i + 1); n++, ni++) #if FIXED_POINT { nt[j][ni] -= (short)((g * r[n + q]) >> 13); } #else { nt[j][ni] -= (g * r[n + q]); } #endif } for (q = 0; q < nb_subvect; q++) { nind[j, q] = oind[best_ntarget[j], q]; } nind[j, i] = best_nind[j]; } /*update old-new data*/ /* just swap pointers instead of a long copy */ { SpeexWord16[][] tmp2; tmp2 = ot; ot = nt; nt = tmp2; } for (j = 0; j < N; j++) { for (m = 0; m < nb_subvect; m++) { oind[j, m] = nind[j, m]; } } for (j = 0; j < N; j++) { odist[j] = ndist[j]; } } /* save indices */ for (i = 0; i < nb_subvect; i++) { ind[i] = nind[0, i]; bits.Pack(ind[i], shape_bits + have_sign); } /* Put everything back together */ for (i = 0; i < nb_subvect; i++) { int rind_3; SpeexWord16 sign_4 = 1; rind_3 = ind[i]; if (rind_3 >= shape_cb_size) { sign_4 = -1; rind_3 -= shape_cb_size; } #if FIXED_POINT if (sign_4 == 1) { for (j = 0; j < subvect_size; j++) { e[subvect_size * i + j] = (int)(shape_cb[rind_3 * subvect_size + j]) >> (14 - 5); } } else { for (j = 0; j < subvect_size; j++) { e[subvect_size * i + j] = -((int)(shape_cb[rind_3 * subvect_size + j]) >> (14 - 5)); } } #else for (j = 0; j < subvect_size; j++) { e[subvect_size * i + j] = sign_4 * 0.03125f * shape_cb[rind_3 * subvect_size + j]; } #endif } /* Update excitation */ for (j = 0; j < nsf; j++) { exc[es + j] += e[j]; } /* Update target */ NSpeex.Filters.Syn_percep_zero(e, 0, ak, awk1, awk2, r2, nsf, p); for (j = 0; j < nsf; j++) { target[j] -= r2[j]; } }
public sealed override void Quantify(float[] target, float[] ak, float[] awk1, float[] awk2, int p, int nsf, float[] exc, int es, float[] r, Bits bits, int complexity) { int num = complexity; if (num > 10) { num = 10; } float[] array = new float[this.shape_cb_size * this.subvect_size]; int[] array2 = new int[num]; float[] array3 = new float[num]; float[] array4 = new float[num]; float[] array5 = new float[num]; int[] array6 = new int[num]; int[] array7 = new int[num]; for (int i = 0; i < num; i++) { for (int j = 0; j < this.nb_subvect; j++) { this.nind[i, j] = (this.oind[i, j] = -1); } } for (int j = 0; j < num; j++) { for (int i = 0; i < nsf; i++) { this.ot[j][i] = target[i]; } } for (int i = 0; i < this.shape_cb_size; i++) { int num2 = i * this.subvect_size; int num3 = i * this.subvect_size; for (int j = 0; j < this.subvect_size; j++) { array[num2 + j] = 0f; for (int k = 0; k <= j; k++) { array[num2 + j] += 0.03125f * (float)this.shape_cb[num3 + k] * r[j - k]; } } this.E[i] = 0f; for (int j = 0; j < this.subvect_size; j++) { this.E[i] += array[num2 + j] * array[num2 + j]; } } for (int j = 0; j < num; j++) { array5[j] = 0f; } for (int i = 0; i < this.nb_subvect; i++) { int num4 = i * this.subvect_size; for (int j = 0; j < num; j++) { array4[j] = 2.14748365E+09f; } for (int j = 0; j < num; j++) { array6[j] = (array7[j] = 0); } for (int j = 0; j < num; j++) { float num5 = 0f; for (int l = num4; l < num4 + this.subvect_size; l++) { num5 += this.ot[j][l] * this.ot[j][l]; } num5 *= 0.5f; if (this.have_sign != 0) { VQ.Nbest_sign(this.ot[j], num4, array, this.subvect_size, this.shape_cb_size, this.E, num, array2, array3); } else { VQ.Nbest(this.ot[j], num4, array, this.subvect_size, this.shape_cb_size, this.E, num, array2, array3); } for (int k = 0; k < num; k++) { float num6 = array5[j] + array3[k] + num5; if (num6 < array4[num - 1]) { for (int l = 0; l < num; l++) { if (num6 < array4[l]) { int m; for (m = num - 1; m > l; m--) { array4[m] = array4[m - 1]; array6[m] = array6[m - 1]; array7[m] = array7[m - 1]; } array4[l] = num6; array6[m] = array2[k]; array7[m] = j; break; } } } } if (i == 0) { break; } } for (int j = 0; j < num; j++) { for (int l = (i + 1) * this.subvect_size; l < nsf; l++) { this.nt[j][l] = this.ot[array7[j]][l]; } for (int l = 0; l < this.subvect_size; l++) { float num7 = 1f; int num8 = array6[j]; if (num8 >= this.shape_cb_size) { num7 = -1f; num8 -= this.shape_cb_size; } int n = this.subvect_size - l; float num9 = num7 * 0.03125f * (float)this.shape_cb[num8 * this.subvect_size + l]; int m = 0; int num10 = num4 + this.subvect_size; while (m < nsf - this.subvect_size * (i + 1)) { this.nt[j][num10] -= num9 * r[m + n]; m++; num10++; } } for (int n = 0; n < this.nb_subvect; n++) { this.nind[j, n] = this.oind[array7[j], n]; } this.nind[j, i] = array6[j]; } float[][] array8 = this.ot; this.ot = this.nt; this.nt = array8; for (int j = 0; j < num; j++) { for (int l = 0; l < this.nb_subvect; l++) { this.oind[j, l] = this.nind[j, l]; } } for (int j = 0; j < num; j++) { array5[j] = array4[j]; } } for (int i = 0; i < this.nb_subvect; i++) { this.ind[i] = this.nind[0, i]; bits.Pack(this.ind[i], this.shape_bits + this.have_sign); } for (int i = 0; i < this.nb_subvect; i++) { float num11 = 1f; int num12 = this.ind[i]; if (num12 >= this.shape_cb_size) { num11 = -1f; num12 -= this.shape_cb_size; } for (int j = 0; j < this.subvect_size; j++) { this.e[this.subvect_size * i + j] = num11 * 0.03125f * (float)this.shape_cb[num12 * this.subvect_size + j]; } } for (int j = 0; j < nsf; j++) { exc[es + j] += this.e[j]; } Filters.Syn_percep_zero(this.e, 0, ak, awk1, awk2, this.r2, nsf, p); for (int j = 0; j < nsf; j++) { target[j] -= this.r2[j]; } }
public virtual int Encode(Bits bits, float[] ins0) { Array.Copy(this.frmBuf, this.frameSize, this.frmBuf, 0, this.bufSize - this.frameSize); this.frmBuf[this.bufSize - this.frameSize] = ins0[0] - this.preemph * this.pre_mem; for (int i = 1; i < this.frameSize; i++) { this.frmBuf[this.bufSize - this.frameSize + i] = ins0[i] - this.preemph * ins0[i - 1]; } this.pre_mem = ins0[this.frameSize - 1]; Array.Copy(this.exc2Buf, this.frameSize, this.exc2Buf, 0, this.bufSize - this.frameSize); Array.Copy(this.excBuf, this.frameSize, this.excBuf, 0, this.bufSize - this.frameSize); Array.Copy(this.swBuf, this.frameSize, this.swBuf, 0, this.bufSize - this.frameSize); for (int i = 0; i < this.windowSize; i++) { this.buf2[i] = this.frmBuf[i + this.frmIdx] * this.window[i]; } Lpc.Autocorr(this.buf2, this.autocorr, this.lpcSize + 1, this.windowSize); this.autocorr[0] += 10f; this.autocorr[0] *= this.lpc_floor; for (int i = 0; i < this.lpcSize + 1; i++) { this.autocorr[i] *= this.lagWindow[i]; } Lpc.Wld(this.lpc, this.autocorr, this.rc, this.lpcSize); Array.Copy(this.lpc, 0, this.lpc, 1, this.lpcSize); this.lpc[0] = 1f; int num = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 15, 0.2f); if (num == this.lpcSize) { for (int i = 0; i < this.lpcSize; i++) { this.lsp[i] = (float)Math.Acos((double)this.lsp[i]); } } else { if (this.complexity > 1) { num = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 11, 0.05f); } if (num == this.lpcSize) { for (int i = 0; i < this.lpcSize; i++) { this.lsp[i] = (float)Math.Acos((double)this.lsp[i]); } } else { for (int i = 0; i < this.lpcSize; i++) { this.lsp[i] = this.old_lsp[i]; } } } float num2 = 0f; for (int i = 0; i < this.lpcSize; i++) { num2 += (this.old_lsp[i] - this.lsp[i]) * (this.old_lsp[i] - this.lsp[i]); } if (this.first != 0) { for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = this.lsp[i]; } } else { for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = 0.375f * this.old_lsp[i] + 0.625f * this.lsp[i]; } } Lsp.Enforce_margin(this.interp_lsp, this.lpcSize, 0.002f); for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = (float)Math.Cos((double)this.interp_lsp[i]); } this.m_lsp.Lsp2lpc(this.interp_lsp, this.interp_lpc, this.lpcSize); int num3; float num4; if (this.submodes[this.submodeID] == null || this.vbr_enabled != 0 || this.vad_enabled != 0 || this.submodes[this.submodeID].ForcedPitchGain != 0 || this.submodes[this.submodeID].LbrPitch != -1) { int[] array = new int[6]; float[] array2 = new float[6]; Filters.Bw_lpc(this.gamma1, this.interp_lpc, this.bw_lpc1, this.lpcSize); Filters.Bw_lpc(this.gamma2, this.interp_lpc, this.bw_lpc2, this.lpcSize); Filters.Filter_mem2(this.frmBuf, this.frmIdx, this.bw_lpc1, this.bw_lpc2, this.swBuf, this.swIdx, this.frameSize, this.lpcSize, this.mem_sw_whole, 0); Ltp.Open_loop_nbest_pitch(this.swBuf, this.swIdx, this.min_pitch, this.max_pitch, this.frameSize, array, array2, 6); num3 = array[0]; num4 = array2[0]; for (int i = 1; i < 6; i++) { if ((double)array2[i] > 0.85 * (double)num4 && (Math.Abs((double)array[i] - (double)num3 / 2.0) <= 1.0 || Math.Abs((double)array[i] - (double)num3 / 3.0) <= 1.0 || Math.Abs((double)array[i] - (double)num3 / 4.0) <= 1.0 || Math.Abs((double)array[i] - (double)num3 / 5.0) <= 1.0)) { num3 = array[i]; } } } else { num3 = 0; num4 = 0f; } Filters.Fir_mem2(this.frmBuf, this.frmIdx, this.interp_lpc, this.excBuf, this.excIdx, this.frameSize, this.lpcSize, this.mem_exc); float num5 = 0f; for (int i = 0; i < this.frameSize; i++) { num5 += this.excBuf[this.excIdx + i] * this.excBuf[this.excIdx + i]; } num5 = (float)Math.Sqrt((double)(1f + num5 / (float)this.frameSize)); if (this.vbr != null && (this.vbr_enabled != 0 || this.vad_enabled != 0)) { if (this.abr_enabled != 0) { float num6 = 0f; if (this.abr_drift2 * this.abr_drift > 0f) { num6 = -1E-05f * this.abr_drift / (1f + this.abr_count); if (num6 > 0.05f) { num6 = 0.05f; } if (num6 < -0.05f) { num6 = -0.05f; } } this.vbr_quality += num6; if (this.vbr_quality > 10f) { this.vbr_quality = 10f; } if (this.vbr_quality < 0f) { this.vbr_quality = 0f; } } this.relative_quality = this.vbr.Analysis(ins0, this.frameSize, num3, num4); if (this.vbr_enabled != 0) { int num7 = 0; float num8 = 100f; int j; for (j = 8; j > 0; j--) { int num9 = (int)Math.Floor((double)this.vbr_quality); float num10; if (num9 == 10) { num10 = NSpeex.Vbr.nb_thresh[j][num9]; } else { num10 = (this.vbr_quality - (float)num9) * NSpeex.Vbr.nb_thresh[j][num9 + 1] + ((float)(1 + num9) - this.vbr_quality) * NSpeex.Vbr.nb_thresh[j][num9]; } if (this.relative_quality > num10 && this.relative_quality - num10 < num8) { num7 = j; num8 = this.relative_quality - num10; } } j = num7; if (j == 0) { if (this.dtx_count == 0 || (double)num2 > 0.05 || this.dtx_enabled == 0 || this.dtx_count > 20) { j = 1; this.dtx_count = 1; } else { j = 0; this.dtx_count++; } } else { this.dtx_count = 0; } this.Mode = j; if (this.abr_enabled != 0) { int bitRate = this.BitRate; this.abr_drift += (float)(bitRate - this.abr_enabled); this.abr_drift2 = 0.95f * this.abr_drift2 + 0.05f * (float)(bitRate - this.abr_enabled); this.abr_count += new float?((float)1.0).Value; } } else { int submodeID; if (this.relative_quality < 2f) { if (this.dtx_count == 0 || (double)num2 > 0.05 || this.dtx_enabled == 0 || this.dtx_count > 20) { this.dtx_count = 1; submodeID = 1; } else { submodeID = 0; this.dtx_count++; } } else { this.dtx_count = 0; submodeID = this.submodeSelect; } this.submodeID = submodeID; } } else { this.relative_quality = -1f; } bits.Pack(0, 1); bits.Pack(this.submodeID, 4); if (this.submodes[this.submodeID] == null) { for (int i = 0; i < this.frameSize; i++) { this.excBuf[this.excIdx + i] = (this.exc2Buf[this.exc2Idx + i] = (this.swBuf[this.swIdx + i] = 0f)); } for (int i = 0; i < this.lpcSize; i++) { this.mem_sw[i] = 0f; } this.first = 1; this.bounded_pitch = 1; Filters.Iir_mem2(this.excBuf, this.excIdx, this.interp_qlpc, this.frmBuf, this.frmIdx, this.frameSize, this.lpcSize, this.mem_sp); ins0[0] = this.frmBuf[this.frmIdx] + this.preemph * this.pre_mem2; for (int i = 1; i < this.frameSize; i++) { ins0[i] = this.frmBuf[this.frmIdx = i] + this.preemph * ins0[i - 1]; } this.pre_mem2 = ins0[this.frameSize - 1]; return(0); } if (this.first != 0) { for (int i = 0; i < this.lpcSize; i++) { this.old_lsp[i] = this.lsp[i]; } } this.submodes[this.submodeID].LsqQuant.Quant(this.lsp, this.qlsp, this.lpcSize, bits); if (this.submodes[this.submodeID].LbrPitch != -1) { bits.Pack(num3 - this.min_pitch, 7); } if (this.submodes[this.submodeID].ForcedPitchGain != 0) { int num11 = (int)Math.Floor(0.5 + (double)(15f * num4)); if (num11 > 15) { num11 = 15; } if (num11 < 0) { num11 = 0; } bits.Pack(num11, 4); num4 = 0.066667f * (float)num11; } int num12 = (int)Math.Floor(0.5 + 3.5 * Math.Log((double)num5)); if (num12 < 0) { num12 = 0; } if (num12 > 31) { num12 = 31; } num5 = (float)Math.Exp((double)num12 / 3.5); bits.Pack(num12, 5); if (this.first != 0) { for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } } float[] array3 = new float[this.subframeSize]; float[] array4 = new float[this.subframeSize]; float[] array5 = new float[this.subframeSize]; float[] array6 = new float[this.lpcSize]; float[] array7 = new float[this.frameSize]; for (int i = 0; i < this.frameSize; i++) { array7[i] = this.frmBuf[this.frmIdx + i]; } for (int k = 0; k < this.nbSubframes; k++) { int num13 = this.subframeSize * k; int num14 = this.frmIdx + num13; int num15 = this.excIdx + num13; int num16 = this.swIdx + num13; int num17 = this.exc2Idx + num13; float num18 = (float)(1.0 + (double)k) / (float)this.nbSubframes; for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = (1f - num18) * this.old_lsp[i] + num18 * this.lsp[i]; } 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_lsp, this.lpcSize, 0.002f); Lsp.Enforce_margin(this.interp_qlsp, this.lpcSize, 0.002f); for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = (float)Math.Cos((double)this.interp_lsp[i]); } this.m_lsp.Lsp2lpc(this.interp_lsp, this.interp_lpc, this.lpcSize); 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); num18 = 1f; this.pi_gain[k] = 0f; for (int i = 0; i <= this.lpcSize; i++) { this.pi_gain[k] += num18 * this.interp_qlpc[i]; num18 = -num18; } Filters.Bw_lpc(this.gamma1, this.interp_lpc, this.bw_lpc1, this.lpcSize); if (this.gamma2 >= 0f) { Filters.Bw_lpc(this.gamma2, this.interp_lpc, this.bw_lpc2, this.lpcSize); } else { this.bw_lpc2[0] = 1f; this.bw_lpc2[1] = -this.preemph; for (int i = 2; i <= this.lpcSize; i++) { this.bw_lpc2[i] = 0f; } } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] = 0f; } this.excBuf[num15] = 1f; Filters.Syn_percep_zero(this.excBuf, num15, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, array5, this.subframeSize, this.lpcSize); for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] = 0f; } for (int i = 0; i < this.subframeSize; i++) { this.exc2Buf[num17 + i] = 0f; } for (int i = 0; i < this.lpcSize; i++) { array6[i] = this.mem_sp[i]; } Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.excBuf, num15, this.subframeSize, this.lpcSize, array6); for (int i = 0; i < this.lpcSize; i++) { array6[i] = this.mem_sw[i]; } Filters.Filter_mem2(this.excBuf, num15, this.bw_lpc1, this.bw_lpc2, array3, 0, this.subframeSize, this.lpcSize, array6, 0); for (int i = 0; i < this.lpcSize; i++) { array6[i] = this.mem_sw[i]; } Filters.Filter_mem2(this.frmBuf, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num16, this.subframeSize, this.lpcSize, array6, 0); for (int i = 0; i < this.subframeSize; i++) { array4[i] = this.swBuf[num16 + i] - array3[i]; } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] = (this.exc2Buf[num17 + i] = 0f); } int start; int num19; if (this.submodes[this.submodeID].LbrPitch != -1) { int lbrPitch = this.submodes[this.submodeID].LbrPitch; if (lbrPitch != 0) { if (num3 < this.min_pitch + lbrPitch - 1) { num3 = this.min_pitch + lbrPitch - 1; } if (num3 > this.max_pitch - lbrPitch) { num3 = this.max_pitch - lbrPitch; } start = num3 - lbrPitch + 1; num19 = num3 + lbrPitch; } else { num19 = (start = num3); } } else { start = this.min_pitch; num19 = this.max_pitch; } if (this.bounded_pitch != 0 && num19 > num13) { num19 = num13; } int num20 = this.submodes[this.submodeID].Ltp.Quant(array4, this.swBuf, num16, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.excBuf, num15, start, num19, num4, this.lpcSize, this.subframeSize, bits, this.exc2Buf, num17, array5, this.complexity); this.pitch[k] = num20; Filters.Syn_percep_zero(this.excBuf, num15, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, array3, this.subframeSize, this.lpcSize); for (int i = 0; i < this.subframeSize; i++) { array4[i] -= array3[i]; } float num21 = 0f; int num22 = k * this.subframeSize; for (int i = 0; i < this.subframeSize; i++) { this.innov[num22 + i] = 0f; } Filters.Residue_percep_zero(array4, 0, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.buf2, this.subframeSize, this.lpcSize); for (int i = 0; i < this.subframeSize; i++) { num21 += this.buf2[i] * this.buf2[i]; } num21 = (float)Math.Sqrt((double)(0.1f + num21 / (float)this.subframeSize)); num21 /= num5; if (this.submodes[this.submodeID].HaveSubframeGain != 0) { num21 = (float)Math.Log((double)num21); if (this.submodes[this.submodeID].HaveSubframeGain == 3) { int num23 = VQ.Index(num21, NbCodec.exc_gain_quant_scal3, 8); bits.Pack(num23, 3); num21 = NbCodec.exc_gain_quant_scal3[num23]; } else { int num23 = VQ.Index(num21, NbCodec.exc_gain_quant_scal1, 2); bits.Pack(num23, 1); num21 = NbCodec.exc_gain_quant_scal1[num23]; } num21 = (float)Math.Exp((double)num21); } else { num21 = 1f; } num21 *= num5; float num24 = 1f / num21; for (int i = 0; i < this.subframeSize; i++) { array4[i] *= num24; } this.submodes[this.submodeID].Innovation.Quantify(array4, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, this.innov, num22, array5, bits, this.complexity); for (int i = 0; i < this.subframeSize; i++) { this.innov[num22 + i] *= num21; } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] += this.innov[num22 + i]; } if (this.submodes[this.submodeID].DoubleCodebook != 0) { float[] array8 = new float[this.subframeSize]; for (int i = 0; i < this.subframeSize; i++) { array4[i] *= 2.2f; } this.submodes[this.submodeID].Innovation.Quantify(array4, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, array8, 0, array5, bits, this.complexity); for (int i = 0; i < this.subframeSize; i++) { array8[i] *= (float)((double)num21 * 0.45454545454545453); } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] += array8[i]; } } for (int i = 0; i < this.subframeSize; i++) { array4[i] *= num21; } for (int i = 0; i < this.lpcSize; i++) { array6[i] = this.mem_sp[i]; } Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.frmBuf, num14, this.subframeSize, this.lpcSize, this.mem_sp); Filters.Filter_mem2(this.frmBuf, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num16, this.subframeSize, this.lpcSize, this.mem_sw, 0); for (int i = 0; i < this.subframeSize; i++) { this.exc2Buf[num17 + i] = this.excBuf[num15 + i]; } } if (this.submodeID >= 1) { for (int i = 0; i < this.lpcSize; i++) { this.old_lsp[i] = this.lsp[i]; } for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } } if (this.submodeID == 1) { if (this.dtx_count != 0) { bits.Pack(15, 4); } else { bits.Pack(0, 4); } } this.first = 0; float num25 = 0f; float num26 = 0f; for (int i = 0; i < this.frameSize; i++) { num25 += this.frmBuf[this.frmIdx + i] * this.frmBuf[this.frmIdx + i]; num26 += (this.frmBuf[this.frmIdx + i] - array7[i]) * (this.frmBuf[this.frmIdx + i] - array7[i]); } ins0[0] = this.frmBuf[this.frmIdx] + this.preemph * this.pre_mem2; for (int i = 1; i < this.frameSize; i++) { ins0[i] = this.frmBuf[this.frmIdx + i] + this.preemph * ins0[i - 1]; } this.pre_mem2 = ins0[this.frameSize - 1]; if (this.submodes[this.submodeID].Innovation is NoiseSearch || this.submodeID == 0) { this.bounded_pitch = 1; } else { this.bounded_pitch = 0; } return(1); }
public virtual int Encode(Bits bits, float[] ins0) { Filters.Qmf_decomp(ins0, Codebook_Constants.h0, this.x0d, this.x1d, this.fullFrameSize, 64, this.h0_mem); this.lowenc.Encode(bits, this.x0d); for (int i = 0; i < this.windowSize - this.frameSize; i++) { this.high[i] = this.high[this.frameSize + i]; } for (int i = 0; i < this.frameSize; i++) { this.high[this.windowSize - this.frameSize + i] = this.x1d[i]; } Array.Copy(this.excBuf, this.frameSize, this.excBuf, 0, this.bufSize - this.frameSize); float[] piGain = this.lowenc.PiGain; float[] exc = this.lowenc.Exc; float[] innov = this.lowenc.Innov; int num; if (this.lowenc.Mode == 0) { num = 1; } else { num = 0; } for (int i = 0; i < this.windowSize; i++) { this.buf[i] = this.high[i] * this.window[i]; } Lpc.Autocorr(this.buf, this.autocorr, this.lpcSize + 1, this.windowSize); this.autocorr[0] += 1f; this.autocorr[0] *= this.lpc_floor; for (int i = 0; i < this.lpcSize + 1; i++) { this.autocorr[i] *= this.lagWindow[i]; } Lpc.Wld(this.lpc, this.autocorr, this.rc, this.lpcSize); Array.Copy(this.lpc, 0, this.lpc, 1, this.lpcSize); this.lpc[0] = 1f; int num2 = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 15, 0.2f); if (num2 != this.lpcSize) { num2 = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 11, 0.02f); if (num2 != this.lpcSize) { for (int i = 0; i < this.lpcSize; i++) { this.lsp[i] = (float)Math.Cos(3.1415926535897931 * (double)((float)(i + 1)) / (double)(this.lpcSize + 1)); } } } for (int i = 0; i < this.lpcSize; i++) { this.lsp[i] = (float)Math.Acos((double)this.lsp[i]); } float num3 = 0f; for (int i = 0; i < this.lpcSize; i++) { num3 += (this.old_lsp[i] - this.lsp[i]) * (this.old_lsp[i] - this.lsp[i]); } if ((this.vbr_enabled != 0 || this.vad_enabled != 0) && num == 0) { float num4 = 0f; float num5 = 0f; if (this.abr_enabled != 0) { float num6 = 0f; if (this.abr_drift2 * this.abr_drift > 0f) { num6 = -1E-05f * this.abr_drift / (1f + this.abr_count); if (num6 > 0.1f) { num6 = 0.1f; } if (num6 < -0.1f) { num6 = -0.1f; } } this.vbr_quality += num6; if (this.vbr_quality > 10f) { this.vbr_quality = 10f; } if (this.vbr_quality < 0f) { this.vbr_quality = 0f; } } for (int i = 0; i < this.frameSize; i++) { num4 += this.x0d[i] * this.x0d[i]; num5 += this.high[i] * this.high[i]; } float num7 = (float)Math.Log((double)((1f + num5) / (1f + num4))); this.relative_quality = this.lowenc.RelativeQuality; if (num7 < -4f) { num7 = -4f; } if (num7 > 2f) { num7 = 2f; } if (this.vbr_enabled != 0) { int num8 = this.nb_modes - 1; this.relative_quality += 1f * (num7 + 2f); if (this.relative_quality < -1f) { this.relative_quality = -1f; } while (num8 != 0) { int num9 = (int)Math.Floor((double)this.vbr_quality); float num10; if (num9 == 10) { num10 = NSpeex.Vbr.hb_thresh[num8][num9]; } else { num10 = (this.vbr_quality - (float)num9) * NSpeex.Vbr.hb_thresh[num8][num9 + 1] + ((float)(1 + num9) - this.vbr_quality) * NSpeex.Vbr.hb_thresh[num8][num9]; } if (this.relative_quality >= num10) { break; } num8--; } this.Mode = num8; if (this.abr_enabled != 0) { int bitRate = this.BitRate; this.abr_drift += (float)(bitRate - this.abr_enabled); this.abr_drift2 = 0.95f * this.abr_drift2 + 0.05f * (float)(bitRate - this.abr_enabled); this.abr_count += 1f; } } else { int submodeID; if ((double)this.relative_quality < 2.0) { submodeID = 1; } else { submodeID = this.submodeSelect; } this.submodeID = submodeID; } } bits.Pack(1, 1); if (num != 0) { bits.Pack(0, 3); } else { bits.Pack(this.submodeID, 3); } if (num == 0 && this.submodes[this.submodeID] != null) { this.submodes[this.submodeID].LsqQuant.Quant(this.lsp, this.qlsp, this.lpcSize, bits); if (this.first != 0) { for (int i = 0; i < this.lpcSize; i++) { this.old_lsp[i] = this.lsp[i]; } for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } } float[] array = new float[this.lpcSize]; float[] array2 = new float[this.subframeSize]; float[] array3 = new float[this.subframeSize]; for (int j = 0; j < this.nbSubframes; j++) { float num11 = 0f; float num12 = 0f; int num13 = this.subframeSize * j; int num14 = num13; int num15 = this.excIdx + num13; int num16 = num13; int num17 = num13; float num18 = (1f + (float)j) / (float)this.nbSubframes; for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = (1f - num18) * this.old_lsp[i] + num18 * this.lsp[i]; } 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_lsp, this.lpcSize, 0.05f); Lsp.Enforce_margin(this.interp_qlsp, this.lpcSize, 0.05f); for (int i = 0; i < this.lpcSize; i++) { this.interp_lsp[i] = (float)Math.Cos((double)this.interp_lsp[i]); } 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_lsp, this.interp_lpc, this.lpcSize); this.m_lsp.Lsp2lpc(this.interp_qlsp, this.interp_qlpc, this.lpcSize); Filters.Bw_lpc(this.gamma1, this.interp_lpc, this.bw_lpc1, this.lpcSize); Filters.Bw_lpc(this.gamma2, this.interp_lpc, this.bw_lpc2, this.lpcSize); float num19 = 0f; num18 = 1f; this.pi_gain[j] = 0f; for (int i = 0; i <= this.lpcSize; i++) { num19 += num18 * this.interp_qlpc[i]; num18 = -num18; this.pi_gain[j] += this.interp_qlpc[i]; } float value = piGain[j]; value = 1f / (Math.Abs(value) + 0.01f); num19 = 1f / (Math.Abs(num19) + 0.01f); float num20 = Math.Abs(0.01f + num19) / (0.01f + Math.Abs(value)); Filters.Fir_mem2(this.high, num14, this.interp_qlpc, this.excBuf, num15, this.subframeSize, this.lpcSize, this.mem_sp2); for (int i = 0; i < this.subframeSize; i++) { num11 += this.excBuf[num15 + i] * this.excBuf[num15 + i]; } if (this.submodes[this.submodeID].Innovation == null) { for (int i = 0; i < this.subframeSize; i++) { num12 += innov[num13 + i] * innov[num13 + i]; } float num21 = num11 / (0.01f + num12); num21 = (float)Math.Sqrt((double)num21); num21 *= num20; int num22 = (int)Math.Floor(10.5 + 8.0 * Math.Log((double)num21 + 0.0001)); if (num22 < 0) { num22 = 0; } if (num22 > 31) { num22 = 31; } bits.Pack(num22, 5); num21 = (float)(0.1 * Math.Exp((double)num22 / 9.4)); num21 /= num20; } else { for (int i = 0; i < this.subframeSize; i++) { num12 += exc[num13 + i] * exc[num13 + i]; } float num23 = (float)(Math.Sqrt((double)(1f + num11)) * (double)num20 / Math.Sqrt((double)((1f + num12) * (float)this.subframeSize))); int num24 = (int)Math.Floor(0.5 + 3.7 * (Math.Log((double)num23) + 2.0)); if (num24 < 0) { num24 = 0; } if (num24 > 15) { num24 = 15; } bits.Pack(num24, 4); num23 = (float)Math.Exp(0.27027027027027023 * (double)num24 - 2.0); float num25 = num23 * (float)Math.Sqrt((double)(1f + num12)) / num20; float num26 = 1f / num25; for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] = 0f; } this.excBuf[num15] = 1f; Filters.Syn_percep_zero(this.excBuf, num15, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, array2, this.subframeSize, this.lpcSize); for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] = 0f; } for (int i = 0; i < this.lpcSize; i++) { array[i] = this.mem_sp[i]; } Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.excBuf, num15, this.subframeSize, this.lpcSize, array); for (int i = 0; i < this.lpcSize; i++) { array[i] = this.mem_sw[i]; } Filters.Filter_mem2(this.excBuf, num15, this.bw_lpc1, this.bw_lpc2, this.res, num16, this.subframeSize, this.lpcSize, array, 0); for (int i = 0; i < this.lpcSize; i++) { array[i] = this.mem_sw[i]; } Filters.Filter_mem2(this.high, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num17, this.subframeSize, this.lpcSize, array, 0); for (int i = 0; i < this.subframeSize; i++) { this.target[i] = this.swBuf[num17 + i] - this.res[num16 + i]; } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] = 0f; } for (int i = 0; i < this.subframeSize; i++) { this.target[i] *= num26; } for (int i = 0; i < this.subframeSize; i++) { array3[i] = 0f; } this.submodes[this.submodeID].Innovation.Quantify(this.target, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, array3, 0, array2, bits, this.complexity + 1 >> 1); for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] += array3[i] * num25; } if (this.submodes[this.submodeID].DoubleCodebook != 0) { float[] array4 = new float[this.subframeSize]; for (int i = 0; i < this.subframeSize; i++) { array4[i] = 0f; } for (int i = 0; i < this.subframeSize; i++) { this.target[i] *= 2.5f; } this.submodes[this.submodeID].Innovation.Quantify(this.target, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, array4, 0, array2, bits, this.complexity + 1 >> 1); for (int i = 0; i < this.subframeSize; i++) { array4[i] *= (float)((double)num25 * 0.4); } for (int i = 0; i < this.subframeSize; i++) { this.excBuf[num15 + i] += array4[i]; } } } for (int i = 0; i < this.lpcSize; i++) { array[i] = this.mem_sp[i]; } Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.high, num14, this.subframeSize, this.lpcSize, this.mem_sp); Filters.Filter_mem2(this.high, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num17, this.subframeSize, this.lpcSize, this.mem_sw, 0); } 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++) { ins0[i] = 2f * (this.y0[i] - this.y1[i]); } for (int i = 0; i < this.lpcSize; i++) { this.old_lsp[i] = this.lsp[i]; } for (int i = 0; i < this.lpcSize; i++) { this.old_qlsp[i] = this.qlsp[i]; } this.first = 0; return(1); } for (int i = 0; i < this.frameSize; i++) { this.excBuf[this.excIdx + i] = (this.swBuf[i] = 0f); } for (int i = 0; i < this.lpcSize; i++) { this.mem_sw[i] = 0f; } this.first = 1; Filters.Iir_mem2(this.excBuf, this.excIdx, this.interp_qlpc, this.high, 0, 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++) { ins0[i] = 2f * (this.y0[i] - this.y1[i]); } if (num != 0) { return(0); } return(1); }
/// <summary> /// Transforms a stereo frame into a mono frame and stores intensity stereo /// info in 'bits'. /// </summary> public static void Encode(Bits bits, SpeexWord16[] data, int frameSize) { #if FIXED_POINT int i, tmp; SpeexWord32 e_left = 0, e_right = 0, e_tot = 0; SpeexWord32 balance, e_ratio; SpeexWord32 largest, smallest; int shift; int balance_id; /* In band marker */ bits.Pack(14, 5); /* Stereo marker */ bits.Pack(SPEEX_INBAND_STEREO, 4); for (i = 0; i < frameSize; i++) { e_left += (data[2 * i] * data[2 * i]) >> 8; e_right += (data[2 * i + 1] * data[2 * i + 1]) >> 8; data[i] = (SpeexWord16)((data[2 * i] >> 1) + (data[2 * i + 1] >> 1)); e_tot += (data[i] * data[i]) >> 8; } if (e_left > e_right) { bits.Pack(0, 1); largest = e_left; smallest = e_right; } else { bits.Pack(1, 1); largest = e_right; smallest = e_left; } /* Balance quantization */ // ??? shift = (int)Math.Log(smallest, 2) - 15; largest >>= shift; smallest >>= shift; balance = Math.Min(largest / (smallest + 1), 32767); balance_id = VQ.Index((short)balance, balance_bounds, balance_bounds.Length); bits.Pack((int)balance_id, 5); /* "coherence" quantisation */ shift = (int)Math.Log(e_tot, 2); e_tot >>= shift - 25; e_left >>= shift - 10; e_right >>= shift - 10; e_ratio = e_tot / (e_left + e_right + 1); tmp = NSpeex.VQ.Index((short)e_ratio, e_ratio_quant_bounds, 4); bits.Pack(tmp, 2); #else int i, tmp; float e_left = 0, e_right = 0, e_tot = 0; float balance_0, e_ratio_1; for (i = 0; i < frameSize; i++) { e_left += data[2 * i] * data[2 * i]; e_right += data[2 * i + 1] * data[2 * i + 1]; data[i] = .5f * (data[2 * i] + data[2 * i + 1]); e_tot += data[i] * data[i]; } balance_0 = (e_left + 1) / (e_right + 1); e_ratio_1 = e_tot / (1 + e_left + e_right); /* Quantization */ bits.Pack(14, 5); bits.Pack(SPEEX_INBAND_STEREO, 4); balance_0 = (float)(4 * Math.Log(balance_0)); /* Pack balance */ if (balance_0 > 0) { bits.Pack(0, 1); } else { bits.Pack(1, 1); } balance_0 = (float)Math.Floor(.5f + Math.Abs(balance_0)); if (balance_0 > 30) { balance_0 = 31; } bits.Pack((int)balance_0, 5); /* Quantize energy ratio */ tmp = NSpeex.VQ.Index(e_ratio_1, e_ratio_quant, 4); bits.Pack(tmp, 2); #endif }