void Calc_Exc_Rand(Word16 curGain, Word16 *PrevExc, Word16 *DataExc, Word16 *nRandom, LINEDEF *Line,eG723Mode mode) { int i, i_subfr, iblk; Word16 temp, temp2; Word16 j; Word16 TabPos[2*NbPulsBlk], TabSign[2*NbPulsBlk]; Word16 *ptr_TabPos, *ptr_TabSign; Word16 *ptr1, *curExc; Word16 sh1, x1, x2, inter_exc, delta, b0; Word32 L_acc, L_c, L_temp; Word16 tmp[SubFrLen/Sgrid]; Word16 offset[SubFrames]; Word16 tempExc[SubFrLenD]; /* * generate LTP codes */ Line->Olp[0] = random_number(21, nRandom) + (Word16)123; Line->Olp[1] = random_number(21, nRandom) + (Word16)123; for(i_subfr=0; i_subfr<SubFrames; i_subfr++) { /* in [1, NbFilt] */ Line->Sfs[i_subfr].AcGn = random_number(NbFilt, nRandom) + (Word16)1; } Line->Sfs[0].AcLg = 1; Line->Sfs[1].AcLg = 0; Line->Sfs[2].AcLg = 1; Line->Sfs[3].AcLg = 3; /* * Random innovation : * Selection of the grids, signs and pulse positions */ /* Signs and Grids */ ptr_TabSign = TabSign; ptr1 = offset; for(iblk=0; iblk<SubFrames/2; iblk++) { temp = random_number((1 << (NbPulsBlk+2)), nRandom); *ptr1++ = temp & (Word16)0x0001; temp = shr(temp, 1); *ptr1++ = add( (Word16) SubFrLen, (Word16) (temp & 0x0001) ); for(i=0; i<NbPulsBlk; i++) { *ptr_TabSign++= shl(sub((temp & (Word16)0x0002), 1), 14); temp = shr(temp, 1); } } /* Positions */ ptr_TabPos = TabPos; for(i_subfr=0; i_subfr<SubFrames; i_subfr++) { for(i=0; i<(SubFrLen/Sgrid); i++) tmp[i] = (Word16)i; temp = (SubFrLen/Sgrid); for(i=0; i<Nb_puls[i_subfr]; i++) { j = random_number(temp, nRandom); *ptr_TabPos++ = add(shl(tmp[(int)j],1), offset[i_subfr]); temp = sub(temp, 1); tmp[(int)j] = tmp[(int)temp]; } } /* * Compute fixed codebook gains */ ptr_TabPos = TabPos; ptr_TabSign = TabSign; curExc = DataExc; i_subfr = 0; for(iblk=0; iblk<SubFrames/2; iblk++) { /* decode LTP only */ Decod_Acbk(curExc, &PrevExc[0], Line->Olp[iblk], Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn,mode); Decod_Acbk(&curExc[SubFrLen], &PrevExc[SubFrLen], Line->Olp[iblk], Line->Sfs[i_subfr+1].AcLg, Line->Sfs[i_subfr+1].AcGn,mode); temp2 = 0; for(i=0; i<SubFrLenD; i++) { temp = abs_s(curExc[i]); #ifdef VC if(temp > temp2) temp2 = temp; #endif #ifdef CCS temp2=_max2(temp2,temp); #endif } if(temp2 == 0) sh1 = 0; else { sh1 = sub(4,norm_s(temp2)); /* 4 bits of margin */ if(sh1 < -2) sh1 = -2; } L_temp = 0L; for(i=0; i<SubFrLenD; i++) { temp = shr(curExc[i], sh1); /* left if sh1 < 0 */ L_temp = L_mac(L_temp, temp, temp); tempExc[i] = temp; } /* ener_ltp x 2**(-2sh1+1) */ L_acc = 0L; for(i=0; i<NbPulsBlk; i++) { L_acc = L_mac(L_acc, tempExc[(int)ptr_TabPos[i]], ptr_TabSign[i]); } inter_exc = extract_h(L_shl(L_acc, 1)); /* inter_exc x 2-sh1 */ /* compute SubFrLenD x curGain**2 x 2**(-2sh1+1) */ /* curGain input = 2**5 curGain */ L_acc = L_mult(curGain, SubFrLen); L_acc = L_shr(L_acc, 6); temp = extract_l(L_acc); /* SubFrLen x curGain : avoids overflows */ L_acc = L_mult(temp, curGain); temp = shl(sh1, 1); temp = add(temp, 4); L_acc = L_shr(L_acc, temp); /* SubFrLenD x curGain**2 x 2**(-2sh1+1) */ /* c = (ener_ltp - SubFrLenD x curGain**2)/nb_pulses_blk */ /* compute L_c = c >> 2sh1-1 */ L_acc = L_sub(L_temp, L_acc); /* x 1/nb_pulses_blk */ L_c = L_mls(L_acc, InvNbPulsBlk); /* * Solve EQ(X) = X**2 + 2 b0 X + c */ /* delta = b0 x b0 - c */ b0 = mult_r(inter_exc, InvNbPulsBlk); /* b0 >> sh1 */ L_acc = L_msu(L_c, b0, b0); /* (c - b0**2) >> 2sh1-1 */ L_acc = L_negate(L_acc); /* delta x 2**(-2sh1+1) */ /* Case delta <= 0 */ if(L_acc <= 0) { /* delta <= 0 */ x1 = negate(b0); /* sh1 */ } /* Case delta > 0 */ else { delta = Sqrt_lbc(L_acc); /* >> sh1 */ x1 = sub(delta, b0); /* x1 >> sh1 */ x2 = add(b0, delta); /* (-x2) >> sh1 */ if(abs_s(x2) < abs_s(x1)) { x1 = negate(x2); } } /* Update DataExc */ sh1 = add(sh1, 1); temp = shl(x1, sh1); #ifdef VC if(temp > (2*Gexc_Max)) temp = (2*Gexc_Max); if(temp < -(2*Gexc_Max)) temp = -(2*Gexc_Max); #endif #ifdef CCS temp=_min2(temp,(2*Gexc_Max)); temp=_max2(temp,-(2*Gexc_Max)); #endif for(i=0; i<NbPulsBlk; i++) { j = *ptr_TabPos++; curExc[(int)j] = add(curExc[(int)j], mult(temp, (*ptr_TabSign++)) ); } /* update PrevExc */ ptr1 = PrevExc; for(i=SubFrLenD; i<PitchMax; i++) *ptr1++ = PrevExc[i]; for(i=0; i<SubFrLenD; i++) *ptr1++ = curExc[i]; curExc += SubFrLenD; i_subfr += 2; } /* end of loop on LTP blocks */ return; }
void FilterSlot::set(int slot_nr, NRPixBlock *pb) { /* Unnamed slot is for saving filter primitive results, when parameter * 'result' is not set. Only the filter immediately after this one * can access unnamed results, so we don't have to worry about overwriting * previous results in filter chain. On the other hand, we may not * overwrite any other image with this one, because they might be * accessed later on. */ int index = ((slot_nr != NR_FILTER_SLOT_NOT_SET) ? _get_index(slot_nr) : _get_index(NR_FILTER_UNNAMED_SLOT)); assert(index >= 0); // Unnamed slot is only for Inkscape::Filters::FilterSlot internal use. assert(slot_nr != NR_FILTER_UNNAMED_SLOT); assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr); if (slot_nr == NR_FILTER_SOURCEGRAPHIC || slot_nr == NR_FILTER_BACKGROUNDIMAGE) { Geom::Matrix trans = units.get_matrix_display2pb(); if (fabs(trans[1]) > 1e-6 || fabs(trans[2]) > 1e-6) { NRPixBlock *trans_pb = new NRPixBlock; int x0 = pb->area.x0; int y0 = pb->area.y0; int x1 = pb->area.x1; int y1 = pb->area.y1; int min_x = _min4(trans[0] * x0 + trans[2] * y0 + trans[4], trans[0] * x0 + trans[2] * y1 + trans[4], trans[0] * x1 + trans[2] * y0 + trans[4], trans[0] * x1 + trans[2] * y1 + trans[4]); int max_x = _max4(trans[0] * x0 + trans[2] * y0 + trans[4], trans[0] * x0 + trans[2] * y1 + trans[4], trans[0] * x1 + trans[2] * y0 + trans[4], trans[0] * x1 + trans[2] * y1 + trans[4]); int min_y = _min4(trans[1] * x0 + trans[3] * y0 + trans[5], trans[1] * x0 + trans[3] * y1 + trans[5], trans[1] * x1 + trans[3] * y0 + trans[5], trans[1] * x1 + trans[3] * y1 + trans[5]); int max_y = _max4(trans[1] * x0 + trans[3] * y0 + trans[5], trans[1] * x0 + trans[3] * y1 + trans[5], trans[1] * x1 + trans[3] * y0 + trans[5], trans[1] * x1 + trans[3] * y1 + trans[5]); nr_pixblock_setup_fast(trans_pb, pb->mode, min_x, min_y, max_x, max_y, true); if (trans_pb->size != NR_PIXBLOCK_SIZE_TINY && trans_pb->data.px == NULL) { /* TODO: this gets hit occasionally. Worst case scenario: * images are exported in horizontal stripes. One stripe * is not too high, but can get thousands of pixels wide. * Rotate this 45 degrees -> _huge_ image */ g_warning("Memory allocation failed in Inkscape::Filters::FilterSlot::set (transform)"); return; } if (filterquality == FILTER_QUALITY_BEST) { NR::transform_bicubic(trans_pb, pb, trans); } else { NR::transform_nearest(trans_pb, pb, trans); } nr_pixblock_release(pb); delete pb; pb = trans_pb; } else if (fabs(trans[0] - 1) > 1e-6 || fabs(trans[3] - 1) > 1e-6) { NRPixBlock *trans_pb = new NRPixBlock; int x0 = pb->area.x0; int y0 = pb->area.y0; int x1 = pb->area.x1; int y1 = pb->area.y1; int min_x = _min2(trans[0] * x0 + trans[4], trans[0] * x1 + trans[4]); int max_x = _max2(trans[0] * x0 + trans[4], trans[0] * x1 + trans[4]); int min_y = _min2(trans[3] * y0 + trans[5], trans[3] * y1 + trans[5]); int max_y = _max2(trans[3] * y0 + trans[5], trans[3] * y1 + trans[5]); nr_pixblock_setup_fast(trans_pb, pb->mode, min_x, min_y, max_x, max_y, true); if (trans_pb->size != NR_PIXBLOCK_SIZE_TINY && trans_pb->data.px == NULL) { g_warning("Memory allocation failed in Inkscape::Filters::FilterSlot::set (scaling)"); return; } NR::scale_bicubic(trans_pb, pb); nr_pixblock_release(pb); delete pb; pb = trans_pb; } } if(_slot[index]) { nr_pixblock_release(_slot[index]); delete _slot[index]; } _slot[index] = pb; _last_out = index; }
/* ** ** Function: Qua_SidGain() ** ** Description: Quantization of Sid gain ** Pseudo-log quantizer in 3 segments ** 1st segment : length = 16, resolution = 2 ** 2nd segment : length = 16, resolution = 4 ** 3rd segment : length = 32, resolution = 8 ** quantizes a sum of energies ** ** Links to text: ** ** Arguments: ** ** Word16 *Ener table of the energies ** Word16 *shEner corresponding scaling factors ** Word16 nq if nq >= 1 : quantization of nq energies ** for SID gain calculation in function Cod_Cng() ** if nq = 0 : in function Comp_Info(), ** quantization of saved estimated excitation energy ** ** Outputs: None ** ** ** Return value: index of quantized energy ** */ Word16 Qua_SidGain(Word16 *Ener, Word16 *shEner, Word16 nq) { Word16 temp, iseg, iseg_p1; Word16 j, j2, k, exp; Word32 L_x, L_y; Word16 sh1; Word32 L_acc; int i; if(nq == 0) { /* Quantize energy saved for frame erasure case */ /* L_x = 2 x average_ener */ temp = shl(*shEner, 1); temp = sub(16, temp); L_acc = L_deposit_l(*Ener); L_acc = L_shl(L_acc, temp); /* may overflow, and >> if temp < 0 */ L_x = L_mls(L_acc, fact[0]); } else { /* * Compute weighted average of energies * Ener[i] = enerR[i] x 2**(shEner[i]-14) * L_x = k[nq] x SUM(i=0->nq-1) enerR[i] * with k[nq] = 2 x fact_mul x fact_mul / nq x Frame */ sh1 = shEner[0]; for(i=1; i<nq; i++) { #ifdef VC if(shEner[i] < sh1) sh1 = shEner[i]; #endif #ifdef CCS sh1=_min2(shEner[i],sh1); #endif } for(i=0, L_x=0L; i<nq; i++) { temp = sub(shEner[i], sh1); temp = shr(Ener[i], temp); temp = mult_r(fact[nq], temp); L_x = L_add(L_x, L_deposit_l(temp)); } temp = sub(15, sh1); L_x = L_shl(L_x, temp); } /* Quantize L_x */ if(L_x >= L_bseg[2]) return(63); /* Compute segment number iseg */ if(L_x >= L_bseg[1]) { iseg = 2; exp = 4; } else { exp = 3; if(L_x >= L_bseg[0]) iseg = 1; else iseg = 0; } iseg_p1 = add(iseg,1); j = shl(1, exp); k = shr(j,1); /* Binary search in segment iseg */ for(i=0; i<exp; i++) { temp = add(base[iseg], shl(j, iseg_p1)); L_y = L_mult(temp, temp); if(L_x >= L_y) j = add(j, k); else j = sub(j, k); k = shr(k, 1); } temp = add(base[iseg], shl(j, iseg_p1)); L_y = L_mult(temp, temp); L_y = L_sub(L_y, L_x); if(L_y <= 0L) { j2 = add(j, 1); temp = add(base[iseg], shl(j2, iseg_p1)); L_acc = L_mult(temp, temp); L_acc = L_sub(L_x, L_acc); if(L_y > L_acc) temp = add(shl(iseg,4), j); else temp = add(shl(iseg,4), j2); } else { j2 = sub(j, 1); temp = add(base[iseg], shl(j2, iseg_p1)); L_acc = L_mult(temp, temp); L_acc = L_sub(L_x, L_acc); if(L_y < L_acc) temp = add(shl(iseg,4), j); else temp = add(shl(iseg,4), j2); } return(temp); }