static void build_code ( Word16 codvec[], /* (i) : position of pulses */ Word16 sign[], /* (i) : sign of d[n] */ Word16 cod[], /* (o) : innovative code vector */ Word16 h[], /* (i) : impulse response of weighted synthesis filter*/ Word16 y[], /* (o) : filtered innovative code */ Word16 indx[] /* (o) : index of 10 pulses (sign+position) */ ) { Word16 i, j, k, track, index, _sign[NB_PULSE]; Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9; Word32 s; Set_zero(cod, L_CODE); for (i = 0; i < NB_TRACK; i++) { indx[i] = -1; } for (k = 0; k < NB_PULSE; k++) { /* read pulse position */ i = codvec[k]; /* read sign */ j = sign[i]; index = mult (i, 6554); /* index = pos/5 */ /* track = pos%5 */ track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); if (j > 0) { cod[i] = cod[i] + 4096; _sign[k] = 8192; } else { cod[i] = cod[i] - 4096; _sign[k] = -8192; index += 8; } if (indx[track] < 0) { indx[track] = index; } else { if (((index ^ indx[track]) & 8) == 0) { /* sign of 1st pulse == sign of 2nd pulse */ if (indx[track] <= index) { indx[track + 5] = index; } else { indx[track + 5] = indx[track]; indx[track] = index; } } else { /* sign of 1st pulse != sign of 2nd pulse */ if ((indx[track] & 7) <= (index & 7)) { indx[track + 5] = indx[track]; indx[track] = index; } else { indx[track + 5] = index; } } } } p0 = h - codvec[0]; p1 = h - codvec[1]; p2 = h - codvec[2]; p3 = h - codvec[3]; p4 = h - codvec[4]; p5 = h - codvec[5]; p6 = h - codvec[6]; p7 = h - codvec[7]; p8 = h - codvec[8]; p9 = h - codvec[9]; for (i = 0; i < L_CODE; i++) { s = 0; s = L_mac (s, *p0++, _sign[0]); s = L_mac (s, *p1++, _sign[1]); s = L_mac (s, *p2++, _sign[2]); s = L_mac (s, *p3++, _sign[3]); s = L_mac (s, *p4++, _sign[4]); s = L_mac (s, *p5++, _sign[5]); s = L_mac (s, *p6++, _sign[6]); s = L_mac (s, *p7++, _sign[7]); s = L_mac (s, *p8++, _sign[8]); s = L_mac (s, *p9++, _sign[9]); y[i] = round (s); } }

/*inline*/ vertex3f vertex3f::operator-(const vertex3f &op) const { return sub(op); }

pulsesequence() { /* Internal variable declarations *************************/ int shapelist90,shapelist180; int table = 0; double tau1,tau2,tau3,te1_delay,te2_delay,te3_delay,tr_delay; double freq90[MAXNSLICE],freq180[MAXNSLICE]; double thk2fact,crush_step,neby2,crush_ind; int suppressSTE,*crushtab; char crushmod[MAXSTR]; int i; /* Real-time variables used in this sequence **************/ int vpe_steps = v1; // Number of PE steps int vpe_ctr = v2; // PE loop counter int vpe_mult = v3; // PE multiplier, ranges from -PE/2 to PE/2 int vpe_offset = v4; // PE/2 for non-table offset int vms_slices = v5; // Number of slices int vms_ctr = v6; // Slice loop counter int vne = v7; // Number of echoes int vne_ctr = v8; // Echo loop counter int vssc = v9; // Compressed steady-states int vtrimage = v10; // Counts down from nt, trimage delay when 0 int vacquire = v11; // Argument for setacqvar, to skip steady state acquires int vphase90 = v12; // Phase of 90 degree excitation pulse int vphase180 = v13; // Phase of 180 degree refocusing pulse int vphindex = v14; // Phase cycle index int vneindex = v15; // Echo index, odd or even int vcrush = v16; // Crusher modulation int vtrigblock = v17; // Number of slices per trigger block /* Initialize paramaters **********************************/ init_mri(); getstr("crushmod",crushmod); suppressSTE=getval("suppressSTE"); /* Load external PE table ********************************/ if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) { loadtable(petable); table = 1; } /* RF Power & Bandwidth Calculations **********************/ shape_rf(&p1_rf,"p1",p1pat,p1,flip1,rof1,rof2); shape_rf(&p2_rf,"p2",p2pat,p2,flip2,rof1,rof2); calc_rf(&p1_rf,"tpwr1","tpwr1f"); calc_rf(&p2_rf,"tpwr2","tpwr2f"); /* Calculate thk2fact to ensure gss=gss2 for the choice of p1 and p2 so that the sequence remains robust in the absence of correct balancing of slice select and slice refocus gradients */ thk2fact=p2_rf.bandwidth/p1_rf.bandwidth; putvalue("thk2fact",thk2fact); /* Initialize gradient structures *************************/ init_readout(&ro_grad,"ro",lro,np,sw); ro_grad.pad1=alfa; ro_grad.pad2=alfa; init_readout_refocus(&ror_grad,"ror"); init_phase(&pe_grad,"pe",lpe,nv); init_slice(&ss_grad,"ss",thk); init_slice(&ss2_grad,"ss2",thk*thk2fact); init_slice_refocus(&ssr_grad,"ssr"); init_generic(&crush_grad,"crush",gcrush,tcrush); /* Gradient calculations **********************************/ calc_readout(&ro_grad,WRITE,"gro","sw","at"); calc_readout_refocus(&ror_grad,&ro_grad,NOWRITE,"gror"); calc_phase(&pe_grad,WRITE,"gpe","tpe"); calc_slice(&ss_grad,&p1_rf,WRITE,"gss"); calc_slice(&ss2_grad,&p2_rf,WRITE,""); calc_slice_refocus(&ssr_grad,&ss_grad,NOWRITE,"gssr"); calc_generic(&crush_grad,WRITE,"",""); /* Equalize slice refocus and PE gradient durations *******/ calc_sim_gradient(&ror_grad,&null_grad,&ssr_grad,0.0,WRITE); /* Create optional prepulse events ************************/ if (sat[0] == 'y') create_satbands(); if (fsat[0] == 'y') create_fatsat(); if (mt[0] == 'y') create_mtc(); if (ir[0] == 'y') create_inversion_recovery(); sgl_error_check(sglerror); /* Set up frequency offset pulse shape list ********/ offsetlist(pss,ss_grad.amp,0,freq90,ns,seqcon[1]); offsetlist(pss,ss2_grad.ssamp,0,freq180,ns,seqcon[1]); shapelist90 = shapelist(p1_rf.pulseName,ss_grad.rfDuration,freq90,ns,ss_grad.rfFraction,seqcon[1]); shapelist180 = shapelist(p2_rf.pulseName,ss2_grad.rfDuration,freq180,ns,ss2_grad.rfFraction,seqcon[1]); /* To ensure proper overlap spin and stimulated echoes ensure that the middle of the refocusing RF pulse is the centre of the pulse and that echoes are formed in the centre of the acquisition window */ if (ss2_grad.rfFraction != 0.5) abort_message("ERROR %s: Refocusing RF pulse must be symmetric (RF fraction = %.2f)", seqfil,ss2_grad.rfFraction); if (ro_grad.echoFraction != 1) abort_message("ERROR %s: Echo Fraction must be 1",seqfil); /* Find sum of all events in each half-echo period ********/ tau1 = ss_grad.rfCenterBack + ssr_grad.duration + crush_grad.duration + ss2_grad.rfCenterFront; tau2 = ss2_grad.rfCenterBack + pe_grad.duration + crush_grad.duration + ro_grad.timeToEcho; tau3 = ro_grad.timeFromEcho + pe_grad.duration + crush_grad.duration + ss2_grad.rfCenterFront; espmin = 2*MAX(MAX(tau1,tau2),tau3); // Minimum echo spacing espmin += 2*GRADIENT_RES; // Ensure that each delay is at least GRADIENT_RES te = granularity(te,2*GRADIENT_RES); if (minesp[0] == 'y') { te = espmin; putvalue("te",te); } if (FP_LT(te,espmin)) { abort_message("ERROR %s: Echo time too small, minimum is %.3fms\n",seqfil,espmin*1000); } te1_delay = te/2.0 - tau1; // Intra-esp delays te2_delay = te/2.0 - tau2; te3_delay = te/2.0 - tau3; /* Now set the TE processing array accordingly */ putCmd("TE = 0"); /* Re-initialize TE */ for (i=0;i<ne;i++) putCmd("TE[%d] = %f",i+1,te*1000*(i+1)); /* Check nsblock, the number of slices blocked together (used for triggering and/or inversion recovery) */ check_nsblock(); /* Minimum TR **************************************/ trmin = ss_grad.rfCenterFront + ne*te + ro_grad.timeFromEcho + pe_grad.duration + te3_delay + 2*GRADIENT_RES; /* Increase TR if any options are selected *********/ if (sat[0] == 'y') trmin += satTime; if (fsat[0] == 'y') trmin += fsatTime; if (mt[0] == 'y') trmin += mtTime; if (ticks > 0) trmin += GRADIENT_RES; /* Adjust for all slices ***************************/ trmin *= ns; /* Inversion recovery *********************************/ if (ir[0] == 'y') { /* tauti is the additional time beyond IR component to be included in ti */ /* satTime, fsatTime and mtTime all included as those modules will be after IR */ tauti = satTime + fsatTime + mtTime + GRADIENT_RES + ss_grad.rfCenterFront; /* calc_irTime checks ti and returns the time of all IR components */ trmin += calc_irTime(tauti,trmin,mintr[0],tr,&trtype); } if (mintr[0] == 'y') { tr = trmin; putvalue("tr",tr); } if (FP_LT(tr,trmin)) { abort_message("ERROR %s: TR too short, minimum TR is %.3fms\n",seqfil,trmin*1000); } /* Calculate tr delay */ tr_delay = granularity((tr-trmin)/ns,GRADIENT_RES); /* Set pe_steps for profile or full image **********/ pe_steps = prep_profile(profile[0],nv,&pe_grad,&per_grad); F_initval(pe_steps/2.0,vpe_offset); /* Shift DDR for pro ************************************/ roff = -poffset(pro,ro_grad.roamp); /* Adjust experiment time for VnmrJ *********************/ if (ssc<0) { if (seqcon[2] == 'c') g_setExpTime(trmean*(ntmean*pe_steps*arraydim - ssc*arraydim)); else g_setExpTime(trmean*(ntmean*pe_steps*arraydim - ssc*pe_steps*arraydim)); } else g_setExpTime(trmean*ntmean*pe_steps*arraydim + tr*ssc); /* Set phase cycle tables */ if (suppressSTE) { if ((int)nt%2 == 1) abort_message("STE suppression requires a 2 step phase cycle. Set nt as a multiple of 2\n"); settable(t2,4,phref1s); settable(t3,4,phref2s); settable(t4,4,phrec1s); settable(t5,4,phrec2s); } else { settable(t2,4,phref1); settable(t3,4,phref2); settable(t4,4,phrec1); settable(t5,4,phrec2); } /* Set crusher table */ crushtab=malloc((int)ne*sizeof(int)); neby2=ceil(ne/2.0 - US); // US to handle precision errors crush_step=gcrush/neby2; for (i=0; i<ne; i++) { crush_ind = (1.0-2.0*(i%2))*(neby2-floor(i/2)); crushtab[i] = (int)(crush_ind); } settable(t6,(int)ne,crushtab); /* PULSE SEQUENCE ***************************************/ status(A); rotate(); triggerSelect(trigger); // Select trigger input 1/2/3 obsoffset(resto); delay(GRADIENT_RES); initval(fabs(ssc),vssc); // Compressed steady-state counter if (seqcon[2]=='s') assign(zero,vssc); // Zero for standard peloop assign(one,vacquire); // real-time acquire flag setacqvar(vacquire); // Turn on acquire when vacquire is zero /* Phase for excitation pulse */ assign(zero,vphase90); /* trigger */ if (ticks > 0) F_initval((double)nsblock,vtrigblock); /* Begin phase-encode loop ****************************/ peloop(seqcon[2],pe_steps,vpe_steps,vpe_ctr); if (trtype) delay(ns*tr_delay); // relaxation delay /* Compressed steady-states: 1st array & transient, all arrays if ssc is negative */ if ((ix > 1) && (ssc > 0)) assign(zero,vssc); sub(vpe_ctr,vssc,vpe_ctr); // vpe_ctr counts up from -ssc assign(zero,vssc); if (seqcon[2] == 's') assign(zero,vacquire); // Always acquire for non-compressed loop else { ifzero(vpe_ctr); assign(zero,vacquire); // Start acquiring when vpe_ctr reaches zero endif(vpe_ctr); } /* Read external kspace table if set ******************/ if (table) getelem(t1,vpe_ctr,vpe_mult); else { ifzero(vacquire); sub(vpe_ctr,vpe_offset,vpe_mult); elsenz(vacquire); sub(zero,vpe_offset,vpe_mult); // Hold PE mult at initial value for steady states endif(vacquire); } msloop(seqcon[1],ns,vms_slices,vms_ctr); if (!trtype) delay(tr_delay); // Relaxation delay if (ticks > 0) { modn(vms_ctr,vtrigblock,vtest); ifzero(vtest); // if the beginning of an trigger block xgate(ticks); grad_advance(gpropdelay); delay(GRADIENT_RES); elsenz(vtest); delay(GRADIENT_RES); endif(vtest); } sp1on(); delay(GRADIENT_RES); sp1off(); // Scope trigger /* Prepulse options ***********************************/ if (ir[0] == 'y') inversion_recovery(); if (sat[0] == 'y') satbands(); if (fsat[0] == 'y') fatsat(); if (mt[0] == 'y') mtc(); /* 90 degree pulse ************************************/ obspower(p1_rf.powerCoarse); obspwrf(p1_rf.powerFine); delay(GRADIENT_RES); obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT); delay(ss_grad.rfDelayFront); shapedpulselist(shapelist90,ss_grad.rfDuration,vphase90,rof1,rof2,seqcon[1],vms_ctr); delay(ss_grad.rfDelayBack); /* Slice refocus **************************************/ obl_shapedgradient(ssr_grad.name,ssr_grad.duration,ror_grad.amp,0.0,-ssr_grad.amp,WAIT); /* First half-TE delay ********************************/ obspower(p2_rf.powerCoarse); obspwrf(p2_rf.powerFine); delay(te1_delay); F_initval(ne,vne); loop(vne,vne_ctr); /* Phase cycle for refocusing pulse and receiver */ mod4(ct,vphindex); mod2(vne_ctr,vneindex); ifzero(vneindex); getelem(t2,vphindex,vphase180); getelem(t4,vphindex,oph); elsenz(vneindex); getelem(t3,vphindex,vphase180); getelem(t5,vphindex,oph); endif(vneindex); /* Crusher gradient modulation */ assign(one,vcrush); if (crushmod[0] == 'y') { assign(zero,vcrush); ifzero(vneindex); add(vcrush,one,vcrush); elsenz(vneindex); sub(vcrush,one,vcrush); endif(vneindex); } if (crushmod[0] == 'p') { getelem(t6,vne_ctr,vcrush); crush_grad.amp=crush_step; } /* 180 degree pulse *******************************/ if (crushmod[0] == 'y' || crushmod[0] == 'p') var3_shapedgradient(crush_grad.name,crush_grad.duration,0.0,0.0,0.0,0.0,0.0,crush_grad.amp,zero,zero,vcrush,WAIT); else obl_shapedgradient(crush_grad.name,crush_grad.duration,crush_grad.amp,0,crush_grad.amp,WAIT); obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0,0,ss2_grad.amp,NOWAIT); delay(ss2_grad.rfDelayFront); shapedpulselist(shapelist180,ss2_grad.rfDuration,vphase180,rof1,rof2,seqcon[1],vms_ctr); delay(ss2_grad.rfDelayBack); if (crushmod[0] == 'y' || crushmod[0] == 'p') var3_shapedgradient(crush_grad.name,crush_grad.duration,0.0,0.0,0.0,0.0,0.0,crush_grad.amp,zero,zero,vcrush,WAIT); else obl_shapedgradient(crush_grad.name,crush_grad.duration,crush_grad.amp,0,crush_grad.amp,WAIT); /* Second half-TE period ******************************/ delay(te2_delay); /* Phase-encode gradient ******************************/ pe_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,-pe_grad.increment,vpe_mult,WAIT); /* Readout gradient ************************************/ obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.roamp,0,0,NOWAIT); delay(ro_grad.atDelayFront-alfa); /* Acquire data ****************************************/ startacq(alfa); acquire(np,1.0/sw); endacq(); delay(ro_grad.atDelayBack); /* Rewinding phase-encode gradient ********************/ pe_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,pe_grad.increment,vpe_mult,WAIT); /* Second half-TE delay *******************************/ delay(te3_delay); endloop(vne_ctr); endmsloop(seqcon[1],vms_ctr); endpeloop(seqcon[2],vpe_ctr); /* Inter-image delay **********************************/ sub(ntrt,ct,vtrimage); decr(vtrimage); ifzero(vtrimage); delay(trimage); endif(vtrimage); }

static Word16 MR795_gain_code_quant_mod( /* o : index of quantization. */ Word16 gain_pit, /* i : pitch gain, Q14 */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ Word16 frac_en[], /* i : energy coefficients (4), fraction part, Q15 */ Word16 exp_en[], /* i : energy coefficients (4), eponent part, Q0 */ Word16 alpha, /* i : gain adaptor factor (>0), Q15 */ Word16 gain_cod_unq, /* i : Code gain (unquantized) */ /* (scaling: Q10 - exp_gcode0) */ Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener, /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr */ Flag *pOverflow /* o : overflow indicator */ ) { const Word16 *p; Word16 i; Word16 index; Word16 tmp; Word16 one_alpha; Word16 exp; Word16 e_max; Word16 g2_pitch; Word16 g_code; Word16 g2_code_h; Word16 g2_code_l; Word16 d2_code_h; Word16 d2_code_l; Word16 coeff[5]; Word16 coeff_lo[5]; Word16 exp_coeff[5]; Word32 L_tmp; Word32 L_t0; Word32 L_t1; Word32 dist_min; Word16 gain_code; /* Steps in calculation of the error criterion (dist): --------------------------------------------------- underlined = constant; alp = FLP value of alpha, alpha = FIP ---------- ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn; ------------ ------ -- ----- aExEn= alp * ExEn = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2 -------------- ------------- --------- = t[1] + t[2] + t[3] dist = d1 + d2; d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4] ------------------- --- d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn); --- ----- --- ----- = alp * (sqrt(ExEn) - sqrt(ResEn))^2 --- ----------- = (sqrt(aExEn) - sqrt(alp*ResEn))^2 --------------- = (sqrt(aExEn) - t[0] )^2 ---- */ /* * calculate scalings of the constant terms */ gain_code = shl(*gain_cod, (10 - exp_gcode0), pOverflow); /* Q1 -> Q11 (-ec0) */ g2_pitch = mult(gain_pit, gain_pit, pOverflow); /* Q14 -> Q13 */ /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */ one_alpha = add_16((32767 - alpha), 1, pOverflow); /* 32768 - alpha */ /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ L_t1 = L_mult(alpha, frac_en[1], pOverflow); L_t1 = L_shl(L_t1, 1, pOverflow); tmp = (Word16)(L_t1 >> 16); /* directly store in 32 bit variable because no further mult. required */ L_t1 = L_mult(tmp, g2_pitch, pOverflow); exp_coeff[1] = exp_en[1] - 15; tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16); coeff[2] = mult(tmp, gain_pit, pOverflow); exp = exp_gcode0 - 10; exp_coeff[2] = add_16(exp_en[2], exp, pOverflow); /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16); exp = shl(exp_gcode0, 1, pOverflow) - 7; exp_coeff[3] = add_16(exp_en[3], exp, pOverflow); coeff[4] = mult(one_alpha, frac_en[3], pOverflow); exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow); L_tmp = L_mult(alpha, frac_en[0], pOverflow); /* sqrt_l returns normalized value and 2*exponent -> result = val >> (exp/2) exp_coeff holds 2*exponent for c[0] */ /* directly store in 32 bit variable because no further mult. required */ L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow); /* normalization included in sqrt_l_exp */ exp += 47; exp_coeff[0] = exp_en[0] - exp; /* * Determine the maximum exponent occuring in the distance calculation * and adjust all fractions accordingly (including a safety margin) * */ /* find max(e[1..4],e[0]+31) */ e_max = exp_coeff[0] + 31; for (i = 1; i <= 4; i++) { if (exp_coeff[i] > e_max) { e_max = exp_coeff[i]; } } /* scale c[1] (requires no further multiplication) */ tmp = e_max - exp_coeff[1]; L_t1 = L_shr(L_t1, tmp, pOverflow); /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */ for (i = 2; i <= 4; i++) { tmp = e_max - exp_coeff[i]; L_tmp = ((Word32)coeff[i] << 16); L_tmp = L_shr(L_tmp, tmp, pOverflow); L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); } /* scale c[0] (requires no further multiplication) */ exp = e_max - 31; /* new exponent */ tmp = exp - exp_coeff[0]; L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow); /* perform correction by 1/sqrt(2) if exponent difference is odd */ if ((tmp & 0x1) != 0) { L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow); L_t0 = Mpy_32_16(coeff[0], coeff_lo[0], 23170, pOverflow); /* 23170 Q15 = 1/sqrt(2)*/ } /* search the quantizer table for the lowest value of the search criterion */ dist_min = MAX_32; index = 0; p = &qua_gain_code_ptr[0]; for (i = 0; i < NB_QUA_CODE; i++) { g_code = *p++; /* this is g_fac (Q11) */ p++; /* skip log2(g_fac) */ p++; /* skip 20*log10(g_fac) */ g_code = mult(g_code, gcode0, pOverflow); /* only continue if gc[i] < 2.0*gc which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */ if (g_code >= gain_code) { break; } L_tmp = L_mult(g_code, g_code, pOverflow); L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); tmp = sub(g_code, gain_cod_unq, pOverflow); L_tmp = L_mult(tmp, tmp, pOverflow); L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow); /* t2, t3, t4 */ L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow); L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow); L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow); L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow); /* d2 */ tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow); L_tmp = L_mult(tmp, tmp, pOverflow); /* dist */ L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow); /* store table index if distance measure for this index is lower than the minimum seen so far */ if (L_tmp < dist_min) { dist_min = L_tmp; index = i; } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &qua_gain_code_ptr[(index<<2) - index]; g_code = *p++; *qua_ener_MR122 = *p++; *qua_ener = *p; /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow); *gain_cod = (Word16)(L_tmp >> 16); return index; }

pulsesequence() { char sspul[MAXSTR]; double pwClvl=getval("pwClvl"); /* LOAD VARIABLES AND CHECK CONDITIONS */ getstr("sspul", sspul); /* STEADY-STATE PHASECYCLING */ /* This section determines if the phase calculations trigger off of (SS - SSCTR) or off of CT */ ifzero(ssctr); hlv(ct, v4); mod4(ct, v3); elsenz(ssctr); sub(ssval, ssctr, v12); /* v12 = 0,...,ss-1 */ hlv(v12, v4); mod4(v12, v3); endif(ssctr); /* CALCULATE PHASECYCLE */ /* The phasecycle first performs a 4-step cycle on the third pulse in order to select for DQC. Second, the 2-step QIS cycle is added in. Third, a 2-step cycle for axial peak suppression is performed on the second pulse. Fourth, a 2-step cycle for axial peak suppression is performed on the first pulse. If P-type peaks only are being selected, the 2-step cycle for P-type peak selection is performed on the first pulse immediately after the 4-step cycle on the third pulse. */ hlv(v4, v4); if (phase1 == 0) { assign(v4, v6); hlv(v4, v4); mod2(v6, v6); /* v6 = P-type peak selection in w1 */ } hlv(v4, v2); mod4(v4, v4); /* v4 = quadrature image suppression */ hlv(v2, v1); mod2(v1, v1); dbl(v1, v1); mod2(v2, v2); dbl(v2, v2); dbl(v3, v5); add(v3, v5, v5); add(v1, v5, v5); add(v2, v5, v5); add(v4, v5, v5); add(v4, v1, v1); add(v4, v2, v2); add(v4, v3, v3); if (phase1 == 0) { add(v6, v1, v1); add(v6, v5, v5); } if (phase1 == 2) incr(v1); if (phase1 == 3) add(id2, v1, v1); /* adds TPPI increment to the phase of the * first pulse */ assign(v5, oph); /* FOR HYPERCOMPLEX, USE STATES-TPPI TO MOVE AXIALS TO EDGE */ if ((phase1==2)||(phase1==1)) { initval(2.0*(double)(d2_index%2),v9); /* moves axials */ add(v1,v9,v1); add(oph,v9,oph); } /* BEGIN ACTUAL PULSE SEQUENCE CODE */ status(A); if (sspul[0] == 'y') { obspower(pwClvl-12); rgpulse(200*pw, one, 10.0e-6, 0.0e-6); rgpulse(200*pw, zero, 0.0e-6, 1.0e-6); obspower(pwClvl); } delay(d1); status(B); rgpulse(pw, v1, rof1, 1.0e-6); if (d2>0.0) delay(d2 - rof1 - 1.0e-6 -(4*pw)/3.1416); rgpulse(pw, v2, rof1, 0.0); rgpulse(pw, v3, 1.0e-6, rof2); add(v3,one,v8); delay(d3); rgpulse(2.0*pw,v8,rof1,rof1); delay(d3); status(C); }

void build_code_8i40_31bits ( Word16 codvec[], /* i : position of pulses */ Word16 sign[], /* i : sign of d[n] */ Word16 cod[], /* o : innovative code vector */ Word16 h[], /* i : impulse response of weighted synthesis filter*/ Word16 y[], /* o : filtered innovative code */ Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */ Word16 pos_indx[] /* o : position index of 8 pulses(position only) */ ) { Word16 i, j, k, track, sign_index, pos_index, _sign[NB_PULSE8]; Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7; Word32 s; for (i = 0; i < L_CODE; i++) { cod[i] = 0; } for (i = 0; i < NB_TRACK_MR102; i++) { pos_indx[i] = -1; sign_indx[i] = -1; } for (k = 0; k < NB_PULSE8; k++) { /* read pulse position */ i = codvec[k]; /* read sign */ j = sign[i]; pos_index = i >> 2; /* index = pos/4 */ track = i & 3; /* track = pos%4 */ if (j > 0) { cod[i] = cod[i] + POS_CODE; _sign[k] = POS_SIGN; sign_index = 0; /* bit=0 -> positive pulse */ } else { cod[i] = cod[i] - NEG_CODE; _sign[k] = NEG_SIGN; sign_index = 1; /* bit=1 => negative pulse */ /* index = add (index, 8); 1 = negative old code */ } if (pos_indx[track] < 0) { /* first set first NB_TRACK pulses */ pos_indx[track] = pos_index; sign_indx[track] = sign_index; } else { /* 2nd row of pulses , test if positions needs to be switched */ if (((sign_index ^ sign_indx[track]) & 1) == 0) { /* sign of 1st pulse == sign of 2nd pulse */ if (sub (pos_indx[track], pos_index) <= 0) { /* no swap */ pos_indx[track + NB_TRACK_MR102] = pos_index; } else { /* swap*/ pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; pos_indx[track] = pos_index; sign_indx[track] = sign_index; } } else { /* sign of 1st pulse != sign of 2nd pulse */ if (pos_indx[track] <= pos_index) { /*swap*/ pos_indx[track + NB_TRACK_MR102] = pos_indx[track]; pos_indx[track] = pos_index; sign_indx[track] = sign_index; } else { /*no swap */ pos_indx[track + NB_TRACK_MR102] = pos_index; } } } } p0 = h - codvec[0]; p1 = h - codvec[1]; p2 = h - codvec[2]; p3 = h - codvec[3]; p4 = h - codvec[4]; p5 = h - codvec[5]; p6 = h - codvec[6]; p7 = h - codvec[7]; for (i = 0; i < L_CODE; i++) { s = 0; s = L_mac (s, *p0++, _sign[0]); s = L_mac (s, *p1++, _sign[1]); s = L_mac (s, *p2++, _sign[2]); s = L_mac (s, *p3++, _sign[3]); s = L_mac (s, *p4++, _sign[4]); s = L_mac (s, *p5++, _sign[5]); s = L_mac (s, *p6++, _sign[6]); s = L_mac (s, *p7++, _sign[7]); y[i] = round (s); } }

// Actually this is not correct. Need to use schoof's to make the group prime first! BigNum pollard(Node P, Node Q, BigNum a, BigNum b, BigNum p, BigNum P_order){ //P's order <= p BigNum ret; initBigNum(&ret); // generate random X_0 = ap*P + bp*Q BigNum _0 = int2BigNum(0, P_order); BigNum ap = rdm2(_0, P_order); BigNum bp = rdm2(_0, P_order); BigNum _1 = int2BigNum(1, p); BigNum _2 = int2BigNum(2, p); Node a_P = eccMul(ap, P, a, b, p); Node b_P = eccMul(bp, Q, a, b, p); Node X_0 = eccAdd(a_P, b_P, a, b, p); BigNum k = copyBigNum(_0); // insert X_0 and start the random walk addNodeHT(X_0, ap, bp); // add the first Node unsigned int num_X; Node X_i = copyNode(X_0); num_X = HASH_COUNT(ht); while(true){ k = add(k, _1, p); // split into 3 sets by x mod 3 int t = rand_range(0, 2); // this is not the same as the paper... if(t == 0){ // add P X_i = eccAdd(X_i, P, a, b, p); ap = add(ap, _1, P_order); } else if(t == 1){ // 2X_i X_i = eccMul( _2, X_i, a, b, p); ap = mul(ap, _2, P_order); bp = mul(bp, _2, P_order); } else if(t == 2){ // add Q X_i = eccAdd(X_i, Q, a, b, p); bp = add(bp, _1, P_order); } if(X_i.inf){ printf("X_i hits infinity!\n"); BigNum b2_b1 = sub(P_order, bp, P_order); BigNum inv_b2_b1 = invFermat(b2_b1, P_order); BigNum a1_a2 = copyBigNum(ap); ret = mul(a1_a2, inv_b2_b1, P_order); break; } NodeHT *r = findNodeHT(X_i); if(r){ // found a collision! if(compareBigNum(r->bp, bp) != 0){ // b1 != b2 // d = (a1 - a2) / (b2 - b1); a1 is r->ap BigNum b2_b1 = sub(bp, r->bp, P_order); BigNum inv_b2_b1 = invFermat(b2_b1, P_order); BigNum a1_a2 = sub(r->ap, ap, P_order); ret = mul(a1_a2, inv_b2_b1, P_order); break; } } else addNodeHT(X_i, ap, bp); num_X = HASH_COUNT(ht); } printf("Pollard Rounds:\n"); printBigNum(k); return ret; }

void encoder(Word16 number_of_available_bits, Word16 number_of_regions, Word16 *mlt_coefs, Word16 mag_shift, Word16 *out_words) { Word16 num_categorization_control_bits; Word16 num_categorization_control_possibilities; Word16 number_of_bits_per_frame; Word16 number_of_envelope_bits; Word16 categorization_control; Word16 region; Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS]; Word16 power_categories[MAX_NUMBER_OF_REGIONS]; Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1]; Word16 drp_num_bits[MAX_NUMBER_OF_REGIONS+1]; UWord16 drp_code_bits[MAX_NUMBER_OF_REGIONS+1]; Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS]; UWord32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS]; Word16 mag_shift_offset; Word16 temp; /* initialize variables */ test(); if (number_of_regions == NUMBER_OF_REGIONS) { num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS; move16(); num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES; move16(); } else { num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS; move16(); num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES; move16(); } number_of_bits_per_frame = number_of_available_bits; move16(); for (region=0; region<number_of_regions; region++) { region_mlt_bit_counts[region] = 0; move16(); } /* Estimate power envelope. */ number_of_envelope_bits = compute_region_powers(mlt_coefs, mag_shift, drp_num_bits, drp_code_bits, absolute_region_power_index, number_of_regions); /* Adjust number of available bits based on power envelope estimate */ temp = sub(number_of_available_bits,number_of_envelope_bits); number_of_available_bits = sub(temp,num_categorization_control_bits); /* get categorizations */ categorize(number_of_available_bits, number_of_regions, num_categorization_control_possibilities, absolute_region_power_index, power_categories, category_balances); /* Adjust absolute_region_category_index[] for mag_shift. This assumes that REGION_POWER_STEPSIZE_DB is defined to be exactly 3.010299957 or 20.0 times log base 10 of square root of 2. */ temp = shl(mag_shift,1); mag_shift_offset = add(temp,REGION_POWER_TABLE_NUM_NEGATIVES); for (region=0; region<number_of_regions; region++) { absolute_region_power_index[region] = add(absolute_region_power_index[region],mag_shift_offset); move16(); } /* adjust the absolute power region index based on the mlt coefs */ adjust_abs_region_power_index(absolute_region_power_index,mlt_coefs,number_of_regions); /* quantize and code the mlt coefficients based on categorizations */ vector_quantize_mlts(number_of_available_bits, number_of_regions, num_categorization_control_possibilities, mlt_coefs, absolute_region_power_index, power_categories, category_balances, &categorization_control, region_mlt_bit_counts, region_mlt_bits); /* stuff bits into words */ bits_to_words(region_mlt_bits, region_mlt_bit_counts, drp_num_bits, drp_code_bits, out_words, categorization_control, number_of_regions, num_categorization_control_bits, number_of_bits_per_frame); }

void vector_quantize_mlts(Word16 number_of_available_bits, Word16 number_of_regions, Word16 num_categorization_control_possibilities, Word16 *mlt_coefs, Word16 *absolute_region_power_index, Word16 *power_categories, Word16 *category_balances, Word16 *p_categorization_control, Word16 *region_mlt_bit_counts, UWord32 *region_mlt_bits) { Word16 *raw_mlt_ptr; Word16 region; Word16 category; Word16 total_mlt_bits = 0; Word16 temp; Word16 temp1; Word16 temp2; /* Start in the middle of the categorization control range. */ temp = shr(num_categorization_control_possibilities,1); temp = sub(temp,1); for (*p_categorization_control = 0; *p_categorization_control < temp; (*p_categorization_control)++) { region = category_balances[*p_categorization_control]; move16(); power_categories[region] = add(power_categories[region],1); move16(); } for (region=0; region<number_of_regions; region++) { category = power_categories[region]; move16(); temp = extract_l(L_mult0(region,REGION_SIZE)); raw_mlt_ptr = &mlt_coefs[temp]; move16(); temp = sub(category,(NUM_CATEGORIES-1)); test(); if (temp < 0) { region_mlt_bit_counts[region] = vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr, ®ion_mlt_bits[shl(region,2)]); } else { region_mlt_bit_counts[region] = 0; move16(); } total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]); } /* If too few bits... */ temp = sub(total_mlt_bits,number_of_available_bits); test(); test(); logic16(); while ((temp < 0) && (*p_categorization_control > 0)) { test(); test(); logic16(); (*p_categorization_control)--; region = category_balances[*p_categorization_control]; move16(); power_categories[region] = sub(power_categories[region],1); move16(); total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]); category = power_categories[region]; move16(); raw_mlt_ptr = &mlt_coefs[region*REGION_SIZE]; move16(); temp = sub(category,(NUM_CATEGORIES-1)); test(); if (temp < 0) { region_mlt_bit_counts[region] = vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr, ®ion_mlt_bits[shl(region,2)]); } else { region_mlt_bit_counts[region] = 0; move16(); } total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]); temp = sub(total_mlt_bits,number_of_available_bits); } /* If too many bits... */ /* Set up for while loop test */ temp1 = sub(total_mlt_bits,number_of_available_bits); temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1)); test(); test(); logic16(); while ((temp1 > 0) && (temp2 < 0)) { /* operations for while contitions */ test(); test(); logic16(); region = category_balances[*p_categorization_control]; move16(); power_categories[region] = add(power_categories[region],1); move16(); total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]); category = power_categories[region]; move16(); temp = extract_l(L_mult0(region,REGION_SIZE)); raw_mlt_ptr = &mlt_coefs[temp]; move16(); temp = sub(category,(NUM_CATEGORIES-1)); test(); if (temp < 0) { region_mlt_bit_counts[region] = vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr, ®ion_mlt_bits[shl(region,2)]); } else { region_mlt_bit_counts[region] = 0; move16(); } total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]); (*p_categorization_control)++; temp1 = sub(total_mlt_bits,number_of_available_bits); temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1)); } }

/*************************************************************************** Function: bits_to_words Syntax: bits_to_words(UWord32 *region_mlt_bits, Word16 *region_mlt_bit_counts, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *out_words, Word16 categorization_control, Word16 number_of_regions, Word16 num_categorization_control_bits, Word16 number_of_bits_per_frame) Description: Stuffs the bits into words for output WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.09 | 0.12 -------|--------------|---------------- MAX | 0.10 | 0.13 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.12 | 0.15 | 0.19 -------|--------------|----------------|---------------- MAX | 0.14 | 0.17 | 0.21 -------|--------------|----------------|---------------- ***************************************************************************/ void bits_to_words(UWord32 *region_mlt_bits, Word16 *region_mlt_bit_counts, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *out_words, Word16 categorization_control, Word16 number_of_regions, Word16 num_categorization_control_bits, Word16 number_of_bits_per_frame) { Word16 out_word_index = 0; Word16 j; Word16 region; Word16 out_word; Word16 region_bit_count; Word16 current_word_bits_left; UWord16 slice; Word16 out_word_bits_free = 16; UWord32 *in_word_ptr; UWord32 current_word; Word32 acca; Word32 accb; Word16 temp; /* First set up the categorization control bits to look like one more set of region power bits. */ out_word = 0; move16(); drp_num_bits[number_of_regions] = num_categorization_control_bits; move16(); drp_code_bits[number_of_regions] = (UWord16)categorization_control; move16(); /* These code bits are right justified. */ for (region=0; region <= number_of_regions; region++) { current_word_bits_left = drp_num_bits[region]; move16(); current_word = (UWord32)drp_code_bits[region]; move16(); j = sub(current_word_bits_left,out_word_bits_free); test(); if (j >= 0) { temp = extract_l(L_shr(current_word,j)); out_word = add(out_word,temp); out_words[out_word_index++] = out_word; move16(); out_word_bits_free = 16; move16(); out_word_bits_free = sub(out_word_bits_free,j); acca = (current_word << out_word_bits_free); out_word = extract_l(acca); } else { j = negate(j); acca = (current_word << j); accb = L_deposit_l(out_word); acca = L_add(accb,acca); out_word = extract_l(acca); out_word_bits_free = sub(out_word_bits_free,current_word_bits_left); } } /* These code bits are left justified. */ for (region=0;region<number_of_regions; region++) { accb = L_deposit_l(out_word_index); accb = L_shl(accb,4); accb = L_sub(accb,number_of_bits_per_frame); test(); if(accb < 0) { temp = shl(region,2); in_word_ptr = ®ion_mlt_bits[temp]; region_bit_count = region_mlt_bit_counts[region]; move16(); temp = sub(32,region_bit_count); test(); if(temp > 0) current_word_bits_left = region_bit_count; else current_word_bits_left = 32; current_word = *in_word_ptr++; acca = L_deposit_l(out_word_index); acca = L_shl(acca,4); acca = L_sub(acca,number_of_bits_per_frame); /* from while loop */ test(); test(); logic16(); while ((region_bit_count > 0) && (acca < 0)) { /* from while loop */ test(); test(); logic16(); temp = sub(current_word_bits_left,out_word_bits_free); test(); if (temp >= 0) { temp = sub(32,out_word_bits_free); accb = LU_shr(current_word,temp); slice = (UWord16)extract_l(accb); out_word = add(out_word,slice); test(); current_word <<= out_word_bits_free; current_word_bits_left = sub(current_word_bits_left,out_word_bits_free); out_words[out_word_index++] = extract_l(out_word); move16(); out_word = 0; move16(); out_word_bits_free = 16; move16(); } else { temp = sub(32,current_word_bits_left); accb = LU_shr(current_word,temp); slice = (UWord16)extract_l(accb); temp = sub(out_word_bits_free,current_word_bits_left); test(); accb = slice << temp; acca = L_deposit_l(out_word); acca = L_add(acca,accb); out_word = extract_l(acca); out_word_bits_free = sub(out_word_bits_free,current_word_bits_left); current_word_bits_left = 0; move16(); } test(); if (current_word_bits_left == 0) { current_word = *in_word_ptr++; region_bit_count = sub(region_bit_count,32); /* current_word_bits_left = MIN(32,region_bit_count); */ temp = sub(32,region_bit_count); test(); if(temp > 0) current_word_bits_left = region_bit_count; else current_word_bits_left = 32; } acca = L_deposit_l(out_word_index); acca = L_shl(acca,4); acca = L_sub(acca,number_of_bits_per_frame); } accb = L_deposit_l(out_word_index); accb = L_shl(accb,4); accb = L_sub(accb,number_of_bits_per_frame); } } /* Fill out with 1's. */ test(); while (acca < 0) { test(); current_word = 0x0000ffff; move32(); temp = sub(16,out_word_bits_free); acca = LU_shr(current_word,temp); slice = (UWord16)extract_l(acca); out_word = add(out_word,slice); out_words[out_word_index++] = out_word; move16(); out_word = 0; move16(); out_word_bits_free = 16; move16(); acca = L_deposit_l(out_word_index); acca = L_shl(acca,4); acca = L_sub(acca,number_of_bits_per_frame); } }

Word16 compute_region_powers(Word16 *mlt_coefs, Word16 mag_shift, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *absolute_region_power_index, Word16 number_of_regions) { Word16 *input_ptr; Word32 long_accumulator; Word16 itemp1; Word16 power_shift; Word16 region; Word16 j; Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS]; Word16 number_of_bits; Word32 acca; Word16 temp; Word16 temp1; Word16 temp2; input_ptr = mlt_coefs; for (region=0; region<number_of_regions; region++) { long_accumulator = L_deposit_l(0); for (j=0; j<REGION_SIZE; j++) { itemp1 = *input_ptr++; move16(); long_accumulator = L_mac0(long_accumulator,itemp1,itemp1); } power_shift = 0; move16(); acca = (long_accumulator & 0x7fff0000L); logic32(); test(); while (acca > 0) { test(); long_accumulator = L_shr(long_accumulator,1); acca = (long_accumulator & 0x7fff0000L); logic32(); power_shift = add(power_shift,1); } acca = L_sub(long_accumulator,32767); temp = add(power_shift,15); test(); test(); logic16(); while ((acca <= 0) && (temp >= 0)) { test(); test(); logic16(); long_accumulator = L_shl(long_accumulator,1); acca = L_sub(long_accumulator,32767); power_shift--; temp = add(power_shift,15); } long_accumulator = L_shr(long_accumulator,1); /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */ acca = L_sub(long_accumulator,28963); test(); if (acca >= 0) power_shift = add(power_shift,1); acca = L_deposit_l(mag_shift); acca = L_shl(acca,1); acca = L_sub(power_shift,acca); acca = L_add(35,acca); acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES); absolute_region_power_index[region] = extract_l(acca); } /* Before we differentially encode the quantized region powers, adjust upward the valleys to make sure all the peaks can be accurately represented. */ temp = sub(number_of_regions,2); for (region = temp; region >= 0; region--) { temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX); temp2 = sub(absolute_region_power_index[region],temp1); test(); if (temp2 < 0) { absolute_region_power_index[region] = temp1; move16(); } } /* The MLT is currently scaled too low by the factor ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160). This is the ninth power of 1 over the square root of 2. So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9) to drp_code_bits[0]. */ /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */ temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX); temp2 = sub(absolute_region_power_index[0],temp1); test(); if (temp2 < 0) { absolute_region_power_index[0] = temp1; move16(); } temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX); /* * The next line was corrected in Release 1.2 */ temp2 = sub(absolute_region_power_index[0], temp1); test(); if (temp2 > 0) { absolute_region_power_index[0] = temp1; move16(); } differential_region_power_index[0] = absolute_region_power_index[0]; move16(); number_of_bits = 5; move16(); drp_num_bits[0] = 5; move16(); drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX); move16(); /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes may be mathematically impossible anyway.*/ for (region=1; region<number_of_regions; region++) { temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX); temp2 = sub(absolute_region_power_index[region],temp1); test(); if (temp2 < 0) { absolute_region_power_index[region] = temp1; move16(); } temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX); temp2 = sub(absolute_region_power_index[region],temp1); test(); if (temp2 > 0) { absolute_region_power_index[region] = temp1; move16(); } } for (region=1; region<number_of_regions; region++) { j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]); temp = sub(j,DRP_DIFF_MIN); test(); if (temp < 0) { j = DRP_DIFF_MIN; } j = sub(j,DRP_DIFF_MIN); move16(); differential_region_power_index[region] = j; move16(); temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]); temp = add(temp,DRP_DIFF_MIN); absolute_region_power_index[region] = temp; move16(); number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]); drp_num_bits[region] = differential_region_power_bits[region][j]; move16(); drp_code_bits[region] = differential_region_power_codes[region][j]; move16(); } return (number_of_bits); }

void ShapesDialog::onSubscribeButtonClicked() { dds::topic::qos::TopicQos topicQos = dp_.default_topic_qos() << dds::core::policy::Durability::Persistent() << dds::core::policy::DurabilityService( dds::core::Duration(3600,0), dds::core::policy::HistoryKind::KEEP_LAST, 100, 8192, 4196, 8192); dds::sub::qos::SubscriberQos SQos = dp_.default_subscriber_qos() << gQos_; dds::sub::Subscriber sub(dp_, SQos); int d = mainWidget.sizeSlider->value(); QRect rect(0, 0, d, d); QRect constr(0, 0, IS_WIDTH, IS_HEIGHT); int x = static_cast<int>(constr.width() * ((float)rand() / RAND_MAX)*0.9F); int y = static_cast<int>(constr.height() * ((float)rand() / RAND_MAX)*0.9F); int sIdx = mainWidget.rShapeList->currentIndex(); QColor gray = QColor(0x99, 0x99, 0x99); QBrush brush(gray, Qt::SolidPattern); QPen pen(QColor(0xff,0xff,0xff), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); std::vector<std::string> empty; filterParams_ = empty; std::string filterS; if (filterDialog_->isEnabled()) { QRect rect = filterDialog_->getFilterBounds(); std::string x0 = lexicalCast(rect.x()); std::string x1 = lexicalCast(rect.x() + rect.width() -d); std::string y0 = lexicalCast(rect.y()); std::string y1 = lexicalCast(rect.y() + rect.height() -d); filterParams_.push_back(x0); filterParams_.push_back(x1); filterParams_.push_back(y0); filterParams_.push_back(y1); filterS = "(x BETWEEN " + filterParams_[0] + " AND " + filterParams_[1] + ") AND (y BETWEEN " + filterParams_[2] + " AND " + filterParams_[3] + ")"; if (filterDialog_->filterOutside() == false) { filterS = "(x < " + filterParams_[0] + " ) OR ( x > " + filterParams_[1] + " ) OR (y < " + filterParams_[2] + ") OR ( y > " + filterParams_[3] + ")"; } } switch (sIdx) { case CIRCLE: { dds::topic::Topic<ShapeType> circle_(dp_, circleTopicName, topicQos); dds::topic::ContentFilteredTopic<ShapeType> cfcircle_(dds::core::null); dds::sub::DataReader<ShapeType> dr(sub, circle_, readerQos_.get_qos()); if (filterDialog_->isEnabled()) { std::string tname = "CFCircle"; const dds::topic::Filter filter(filterS); std::cout << filterS << std::endl; dds::topic::ContentFilteredTopic<ShapeType> cfcircle_(circle_, "CFCircle", filter); dds::sub::DataReader<ShapeType> dr2(sub, cfcircle_, readerQos_.get_qos()); dr = dr2; } for (int i = 0; i < CN; ++i) { std::string colorStr(colorString_[i]); DDSShapeDynamics::ref_type dynamics(new DDSShapeDynamics(x, y, dr, colorStr, i)); Shape::ref_type circle(new Circle(rect, dynamics, pen, brush, true)); dynamics->setShape(circle); shapesWidget->addShape(circle); } break; } case SQUARE: { dds::topic::Topic<ShapeType> square_(dp_, squareTopicName, topicQos); dds::sub::LoanedSamples<ShapeType>::iterator si; dds::topic::ContentFilteredTopic<ShapeType> cfsquare_(dds::core::null); dds::sub::DataReader<ShapeType> dr(sub, square_, readerQos_.get_qos()); if (filterDialog_->isEnabled()) { std::string tname = "CFSquare"; const dds::topic::Filter filter(filterS); std::cout << filterS << std::endl; dds::topic::ContentFilteredTopic<ShapeType> cfsquare_(square_, "CFSquare", filter); dds::sub::DataReader<ShapeType> dr2(sub, cfsquare_, readerQos_.get_qos()); dr = dr2; } for (int i = 0; i < CN; ++i) { std::string colorStr(colorString_[i]); DDSShapeDynamics::ref_type dynamics(new DDSShapeDynamics(x, y, dr, colorStr, i)); Shape::ref_type square(new Square(rect, dynamics, pen, brush, true)); dynamics->setShape(square); shapesWidget->addShape(square); } break; } case TRIANGLE: { dds::topic::Topic<ShapeType> triangle_(dp_, triangleTopicName, topicQos); dds::sub::LoanedSamples<ShapeType>::iterator si; dds::topic::ContentFilteredTopic<ShapeType> cftriangle_(dds::core::null); dds::sub::DataReader<ShapeType> dr(sub, triangle_, readerQos_.get_qos()); if (filterDialog_->isEnabled()) { std::string tname = "CFTriangle"; const dds::topic::Filter filter(filterS); std::cout << filterS << std::endl; dds::topic::ContentFilteredTopic<ShapeType> cftriangle_(triangle_, "CFTriangle", filter); dds::sub::DataReader<ShapeType> dr2(sub, cftriangle_, readerQos_.get_qos()); dr = dr2; } for (int i = 0; i < CN; ++i) { std::string colorStr(colorString_[i]); DDSShapeDynamics::ref_type dynamics(new DDSShapeDynamics(x, y, dr, colorStr, i)); Shape::ref_type triangle(new Triangle(rect, dynamics, pen, brush, true)); dynamics->setShape(triangle); shapesWidget->addShape(triangle); } break; } default: break; } }

int sub2 (void) { return sub (0x7fffffff); }

T& root_node(treetree::tree<T>& tr) { treetree::subtree<T> sub(tr); return root_node(sub); }

vec3 normal_vector(vec3 *a, vec3 *b, vec3 *c) { return normalize(cross(sub(*b, *a), sub(*c, *a))); }

/*************************************************************************** Function: vector_huffman Syntax: Word16 vector_huffman(Word16 category, Word16 power_index, Word16 *raw_mlt_ptr, UWord32 *word_ptr) inputs: Word16 category Word16 power_index Word16 *raw_mlt_ptr outputs: number_of_region_bits *word_ptr Description: Huffman encoding for each region based on category and power_index WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.03 | 0.03 -------|--------------|---------------- MAX | 0.04 | 0.04 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.03 | 0.03 | 0.03 -------|--------------|----------------|---------------- MAX | 0.04 | 0.04 | 0.04 -------|--------------|----------------|---------------- ***************************************************************************/ Word16 vector_huffman(Word16 category, Word16 power_index, Word16 *raw_mlt_ptr, UWord32 *word_ptr) { Word16 inv_of_step_size_times_std_dev; Word16 j,n; Word16 k; Word16 number_of_region_bits; Word16 number_of_non_zero; Word16 vec_dim; Word16 num_vecs; Word16 kmax, kmax_plus_one; Word16 index,signs_index; Word16 *bitcount_table_ptr; UWord16 *code_table_ptr; Word32 code_bits; Word16 number_of_code_bits; UWord32 current_word; Word16 current_word_bits_free; Word32 acca; Word32 accb; Word16 temp; Word16 mytemp; /* new variable in Release 1.2 */ Word16 myacca; /* new variable in Release 1.2 */ /* initialize variables */ vec_dim = vector_dimension[category]; move16(); num_vecs = number_of_vectors[category]; move16(); kmax = max_bin[category]; move16(); kmax_plus_one = add(kmax,1); move16(); current_word = 0L; move16(); current_word_bits_free = 32; move16(); number_of_region_bits = 0; move16(); /* set up table pointers */ bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category]; code_table_ptr = (UWord16 *) table_of_code_tables[category]; /* compute inverse of step size * standard deviation */ acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]); acca = L_shr(acca,1); acca = L_add(acca,4096); acca = L_shr(acca,13); /* * The next two lines are new to Release 1.2 */ mytemp = acca & 0x3; acca = L_shr(acca,2); inv_of_step_size_times_std_dev = extract_l(acca); for (n=0; n<num_vecs; n++) { index = 0; move16(); signs_index = 0; move16(); number_of_non_zero = 0; move16(); for (j=0; j<vec_dim; j++) { k = abs_s(*raw_mlt_ptr); acca = L_mult(k,inv_of_step_size_times_std_dev); acca = L_shr(acca,1); /* * The next four lines are new to Release 1.2 */ myacca = (Word16)L_mult(k,mytemp); myacca = (Word16)L_shr(myacca,1); myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]); myacca = (Word16)L_shr(myacca,2); acca = L_add(acca,int_dead_zone[category]); /* * The next two lines are new to Release 1.2 */ acca = L_add(acca,myacca); acca = L_shr(acca,13); k = extract_l(acca); test(); if (k != 0) { number_of_non_zero = add(number_of_non_zero,1); signs_index = shl(signs_index,1); test(); if (*raw_mlt_ptr > 0) { signs_index = add(signs_index,1); } temp = sub(k,kmax); test(); if (temp > 0) { k = kmax; move16(); } } acca = L_shr(L_mult(index,(kmax_plus_one)),1); index = extract_l(acca); index = add(index,k); raw_mlt_ptr++; } code_bits = *(code_table_ptr+index); number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero); number_of_region_bits = add(number_of_region_bits,number_of_code_bits); acca = code_bits << number_of_non_zero; accb = L_deposit_l(signs_index); acca = L_add(acca,accb); code_bits = acca; move32(); /* msb of codebits is transmitted first. */ j = sub(current_word_bits_free,number_of_code_bits); test(); if (j >= 0) { test(); acca = code_bits << j; current_word = L_add(current_word,acca); current_word_bits_free = j; move16(); } else { j = negate(j); acca = L_shr(code_bits,j); current_word = L_add(current_word,acca); *word_ptr++ = current_word; move16(); current_word_bits_free = sub(32,j); test(); current_word = code_bits << current_word_bits_free; } } *word_ptr++ = current_word; move16(); return (number_of_region_bits); }

double vec3_distance(vec3 a, vec3 b) { return norm_vec3(sub(a, b)); }

static Word16 D4i40_17( /* (o) : Index of pulses positions. */ Word16 Dn[], /* (i) : Correlations between h[] and Xn[]. */ Word16 rr[], /* (i) : Correlations of impulse response h[]. */ Word16 h[], /* (i) Q12: Impulse response of filters. */ Word16 cod[], /* (o) Q13: Selected algebraic codeword. */ Word16 y[], /* (o) Q12: Filtered algebraic codeword. */ Word16 *sign, /* (o) : Signs of 4 pulses. */ Word16 i_subfr /* (i) : subframe flag */ ) { Word16 i0, i1, i2, i3, ip0, ip1, ip2, ip3; Word16 i, j, time; Word16 ps0, ps1, ps2, ps3, alp, alp0; Word32 alp1, alp2, alp3, L32; Word16 ps3c, psc, alpha; Word16 average, max0, max1, max2, thres; Word32 L_temp; Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; Word16 *rri1i2, *rri1i3, *rri1i4; Word16 *rri2i3, *rri2i4; Word16 *ptr_ri0i0, *ptr_ri1i1, *ptr_ri2i2, *ptr_ri3i3, *ptr_ri4i4; Word16 *ptr_ri0i1, *ptr_ri0i2, *ptr_ri0i3, *ptr_ri0i4; Word16 *ptr_ri1i2, *ptr_ri1i3, *ptr_ri1i4; Word16 *ptr_ri2i3, *ptr_ri2i4; Word16 p_sign[L_SUBFR]; /* Init pointers */ rri0i0 = rr; rri1i1 = rri0i0 + NB_POS; rri2i2 = rri1i1 + NB_POS; rri3i3 = rri2i2 + NB_POS; rri4i4 = rri3i3 + NB_POS; rri0i1 = rri4i4 + NB_POS; rri0i2 = rri0i1 + MSIZE; rri0i3 = rri0i2 + MSIZE; rri0i4 = rri0i3 + MSIZE; rri1i2 = rri0i4 + MSIZE; rri1i3 = rri1i2 + MSIZE; rri1i4 = rri1i3 + MSIZE; rri2i3 = rri1i4 + MSIZE; rri2i4 = rri2i3 + MSIZE; /*-----------------------------------------------------------------------* * Reset max_time for 1st subframe. * *-----------------------------------------------------------------------*/ if (i_subfr == 0){ extra = 30; } /*-----------------------------------------------------------------------* * Chose the sign of the impulse. * *-----------------------------------------------------------------------*/ for (i=0; i<L_SUBFR; i++) { if( Dn[i] >= 0) { p_sign[i] = 0x7fff; } else { p_sign[i] = (Word16)0x8000; Dn[i] = negate(Dn[i]); } } /*-------------------------------------------------------------------* * - Compute the search threshold after three pulses * *-------------------------------------------------------------------*/ /* Find maximum of Dn[i0]+Dn[i1]+Dn[i2] */ max0 = Dn[0]; max1 = Dn[1]; max2 = Dn[2]; for (i = 5; i < L_SUBFR; i+=STEP) { if (sub(Dn[i] , max0) > 0){ max0 = Dn[i]; } if (sub(Dn[i+1], max1) > 0){ max1 = Dn[i+1]; } if (sub(Dn[i+2], max2) > 0){ max2 = Dn[i+2]; } } max0 = add(max0, max1); max0 = add(max0, max2); /* Find average of Dn[i0]+Dn[i1]+Dn[i2] */ L32 = 0; for (i = 0; i < L_SUBFR; i+=STEP) { L32 = L_mac(L32, Dn[i], 1); L32 = L_mac(L32, Dn[i+1], 1); L32 = L_mac(L32, Dn[i+2], 1); } average =extract_l( L_shr(L32, 4)); /* 1/8 of sum */ /* thres = average + (max0-average)*THRESHFCB; */ thres = sub(max0, average); thres = mult(thres, THRESHFCB); thres = add(thres, average); /*-------------------------------------------------------------------* * Modification of rrixiy[] to take signs into account. * *-------------------------------------------------------------------*/ ptr_ri0i1 = rri0i1; ptr_ri0i2 = rri0i2; ptr_ri0i3 = rri0i3; ptr_ri0i4 = rri0i4; for(i0=0; i0<L_SUBFR; i0+=STEP) { for(i1=1; i1<L_SUBFR; i1+=STEP) { *ptr_ri0i1 = mult(*ptr_ri0i1, mult(p_sign[i0], p_sign[i1])); ptr_ri0i1++; *ptr_ri0i2 = mult(*ptr_ri0i2, mult(p_sign[i0], p_sign[i1+1])); ptr_ri0i2++; *ptr_ri0i3 = mult(*ptr_ri0i3, mult(p_sign[i0], p_sign[i1+2])); ptr_ri0i3++; *ptr_ri0i4 = mult(*ptr_ri0i4, mult(p_sign[i0], p_sign[i1+3])); ptr_ri0i4++; } } ptr_ri1i2 = rri1i2; ptr_ri1i3 = rri1i3; ptr_ri1i4 = rri1i4; for(i1=1; i1<L_SUBFR; i1+=STEP) { for(i2=2; i2<L_SUBFR; i2+=STEP) { *ptr_ri1i2 = mult(*ptr_ri1i2, mult(p_sign[i1], p_sign[i2])); ptr_ri1i2++; *ptr_ri1i3 = mult(*ptr_ri1i3, mult(p_sign[i1], p_sign[i2+1])); ptr_ri1i3++; *ptr_ri1i4 = mult(*ptr_ri1i4, mult(p_sign[i1], p_sign[i2+2])); ptr_ri1i4++; } } ptr_ri2i3 = rri2i3; ptr_ri2i4 = rri2i4; for(i2=2; i2<L_SUBFR; i2+=STEP) { for(i3=3; i3<L_SUBFR; i3+=STEP) { *ptr_ri2i3 = mult(*ptr_ri2i3, mult(p_sign[i2], p_sign[i3])); ptr_ri2i3++; *ptr_ri2i4 = mult(*ptr_ri2i4, mult(p_sign[i2], p_sign[i3+1])); ptr_ri2i4++; } } /*-------------------------------------------------------------------* * Search the optimum positions of the four pulses which maximize * * square(correlation) / energy * * The search is performed in four nested loops. At each loop, one * * pulse contribution is added to the correlation and energy. * * * * The fourth loop is entered only if the correlation due to the * * contribution of the first three pulses exceeds the preset * * threshold. * *-------------------------------------------------------------------*/ /* Default values */ ip0 = 0; ip1 = 1; ip2 = 2; ip3 = 3; psc = 0; alpha = MAX_16; time = add(MAX_TIME, extra); /* Four loops to search innovation code. */ ptr_ri0i0 = rri0i0; /* Init. pointers that depend on first loop */ ptr_ri0i1 = rri0i1; ptr_ri0i2 = rri0i2; ptr_ri0i3 = rri0i3; ptr_ri0i4 = rri0i4; for (i0 = 0; i0 < L_SUBFR; i0 += STEP) /* first pulse loop */ { ps0 = Dn[i0]; alp0 = *ptr_ri0i0++; ptr_ri1i1 = rri1i1; /* Init. pointers that depend on second loop */ ptr_ri1i2 = rri1i2; ptr_ri1i3 = rri1i3; ptr_ri1i4 = rri1i4; for (i1 = 1; i1 < L_SUBFR; i1 += STEP) /* second pulse loop */ { ps1 = add(ps0, Dn[i1]); /* alp1 = alp0 + *ptr_ri1i1++ + 2.0 * ( *ptr_ri0i1++); */ alp1 = L_mult(alp0, 1); alp1 = L_mac(alp1, *ptr_ri1i1++, 1); alp1 = L_mac(alp1, *ptr_ri0i1++, 2); ptr_ri2i2 = rri2i2; /* Init. pointers that depend on third loop */ ptr_ri2i3 = rri2i3; ptr_ri2i4 = rri2i4; for (i2 = 2; i2 < L_SUBFR; i2 += STEP) /* third pulse loop */ { ps2 = add(ps1, Dn[i2]); /* alp2 = alp1 + *ptr_ri2i2++ + 2.0 * (*ptr_ri0i2++ + *ptr_ri1i2++); */ alp2 = L_mac(alp1, *ptr_ri2i2++, 1); alp2 = L_mac(alp2, *ptr_ri0i2++, 2); alp2 = L_mac(alp2, *ptr_ri1i2++, 2); /* Test threshold */ if ( sub(ps2, thres) > 0) { ptr_ri3i3 = rri3i3; /* Init. pointers that depend on 4th loop */ for (i3 = 3; i3 < L_SUBFR; i3 += STEP) /* 4th pulse loop */ { ps3 = add(ps2, Dn[i3]); /* alp3 = alp2 + *ptr_ri3i3++ */ /* + 2.0*( *ptr_ri0i3++ + *ptr_ri1i3++ + *ptr_ri2i3++); */ alp3 = L_mac(alp2, *ptr_ri3i3++, 1); alp3 = L_mac(alp3, *ptr_ri0i3++, 2); alp3 = L_mac(alp3, *ptr_ri1i3++, 2); alp3 = L_mac(alp3, *ptr_ri2i3++, 2); alp = extract_l(L_shr(alp3, 5)); ps3c = mult(ps3, ps3); L_temp = L_mult(ps3c, alpha); L_temp = L_msu(L_temp, psc, alp); if( L_temp > 0L ) { psc = ps3c; alpha = alp; ip0 = i0; ip1 = i1; ip2 = i2; ip3 = i3; } } /* end of for i3 = */ ptr_ri0i3 -= NB_POS; ptr_ri1i3 -= NB_POS; ptr_ri4i4 = rri4i4; /* Init. pointers that depend on 4th loop */ for (i3 = 4; i3 < L_SUBFR; i3 += STEP) /* 4th pulse loop */ { ps3 = add(ps2, Dn[i3]); /* alp3 = alp2 + *ptr_ri4i4++ */ /* + 2.0*( *ptr_ri0i4++ + *ptr_ri1i4++ + *ptr_ri2i4++); */ alp3 = L_mac(alp2, *ptr_ri4i4++, 1); alp3 = L_mac(alp3, *ptr_ri0i4++, 2); alp3 = L_mac(alp3, *ptr_ri1i4++, 2); alp3 = L_mac(alp3, *ptr_ri2i4++, 2); alp = extract_l(L_shr(alp3, 5)); ps3c = mult(ps3, ps3); L_temp = L_mult(ps3c, alpha); L_temp = L_msu(L_temp, psc, alp); if( L_temp > 0L ) { psc = ps3c; alpha = alp; ip0 = i0; ip1 = i1; ip2 = i2; ip3 = i3; } } /* end of for i3 = */ ptr_ri0i4 -= NB_POS; ptr_ri1i4 -= NB_POS; time = sub(time, 1); if(time <= 0 ) goto end_search; /* Maximum time finish */ } /* end of if >thres */ else { ptr_ri2i3 += NB_POS; ptr_ri2i4 += NB_POS; } } /* end of for i2 = */ ptr_ri0i2 -= NB_POS; ptr_ri1i3 += NB_POS; ptr_ri1i4 += NB_POS; } /* end of for i1 = */ ptr_ri0i2 += NB_POS; ptr_ri0i3 += NB_POS; ptr_ri0i4 += NB_POS; } /* end of for i0 = */ end_search: extra = time; /* Set the sign of impulses */ i0 = p_sign[ip0]; i1 = p_sign[ip1]; i2 = p_sign[ip2]; i3 = p_sign[ip3]; /* Find the codeword corresponding to the selected positions */ for(i=0; i<L_SUBFR; i++) {cod[i] = 0; } cod[ip0] = shr(i0, 2); /* From Q15 to Q13 */ cod[ip1] = shr(i1, 2); cod[ip2] = shr(i2, 2); cod[ip3] = shr(i3, 2); /* find the filtered codeword */ for (i = 0; i < L_SUBFR; i++) {y[i] = 0; } if(i0 > 0) for(i=ip0, j=0; i<L_SUBFR; i++, j++) { y[i] = add(y[i], h[j]); } else for(i=ip0, j=0; i<L_SUBFR; i++, j++) { y[i] = sub(y[i], h[j]); } if(i1 > 0) for(i=ip1, j=0; i<L_SUBFR; i++, j++) { y[i] = add(y[i], h[j]); } else for(i=ip1, j=0; i<L_SUBFR; i++, j++) { y[i] = sub(y[i], h[j]); } if(i2 > 0) for(i=ip2, j=0; i<L_SUBFR; i++, j++) { y[i] = add(y[i], h[j]); } else for(i=ip2, j=0; i<L_SUBFR; i++, j++) { y[i] = sub(y[i], h[j]); } if(i3 > 0) for(i=ip3, j=0; i<L_SUBFR; i++, j++) { y[i] = add(y[i], h[j]); } else for(i=ip3, j=0; i<L_SUBFR; i++, j++) { y[i] = sub(y[i], h[j]); } /* find codebook index; 17-bit address */ i = 0; if(i0 > 0) i = add(i, 1); if(i1 > 0) i = add(i, 2); if(i2 > 0) i = add(i, 4); if(i3 > 0) i = add(i, 8); *sign = i; ip0 = mult(ip0, 6554); /* ip0/5 */ ip1 = mult(ip1, 6554); /* ip1/5 */ ip2 = mult(ip2, 6554); /* ip2/5 */ i = mult(ip3, 6554); /* ip3/5 */ j = add(i, shl(i, 2)); /* j = i*5 */ j = sub(ip3, add(j, 3)); /* j= ip3%5 -3 */ ip3 = add(shl(i, 1), j); i = add(ip0, shl(ip1, 3)); i = add(i , shl(ip2, 6)); i = add(i , shl(ip3, 9)); return i; }

/************************************************************************* * * Function: gain_adapt() * Purpose: calculate pitch/codebook gain adaptation factor alpha * (and update the adaptor state) * ************************************************************************** */ void gain_adapt( GainAdaptState *st, /* i : state struct */ Word16 ltpg, /* i : ltp coding gain (log2()), Q13 */ Word16 gain_cod, /* i : code gain, Q1 */ Word16 *alpha /* o : gain adaptation factor, Q15 */ ) { Word16 adapt; /* adaptdation status; 0, 1, or 2 */ Word16 result; /* alpha factor, Q13 */ Word16 filt; /* median-filtered LTP coding gain, Q13 */ Word16 tmp, i; /* basic adaptation */ test (); if (sub (ltpg, LTP_GAIN_THR1) <= 0) { adapt = 0; move16 (); } else { test (); if (sub (ltpg, LTP_GAIN_THR2) <= 0) { adapt = 1; move16 (); } else { adapt = 2; move16 (); } } /* * // onset indicator * if ((cbGain > onFact * cbGainMem[0]) && (cbGain > 100.0)) * onset = 8; * else * if (onset) * onset--; */ /* tmp = cbGain / onFact; onFact = 2.0; 200 Q1 = 100.0 */ tmp = shr_r (gain_cod, 1); test (); test (); if ((sub (tmp, st->prev_gc) > 0) && sub(gain_cod, 200) > 0) { st->onset = 8; move16 (); } else { test (); if (st->onset != 0) { st->onset = sub (st->onset, 1); move16 (); } } /* * // if onset, increase adaptor state * if (onset && (gainAdapt < 2)) gainAdapt++; */ test(); test (); if ((st->onset != 0) && (sub (adapt, 2) < 0)) { adapt = add (adapt, 1); } st->ltpg_mem[0] = ltpg; move16 (); filt = gmed_n (st->ltpg_mem, 5); move16 (); /* function result */ test (); if (adapt == 0) { test (); if (sub (filt, 5443) > 0) /* 5443 Q13 = 0.66443... */ { result = 0; move16 (); } else { test (); if (filt < 0) { result = 16384; move16 (); /* 16384 Q15 = 0.5 */ } else { /* result = 0.5 - 0.75257499*filt */ /* result (Q15) = 16384 - 24660 * (filt << 2) */ filt = shl (filt, 2); /* Q15 */ result = sub (16384, mult (24660, filt)); } } } else { result = 0; move16 (); } /* * if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha); */ test (); if (st->prev_alpha == 0) { result = shr (result, 1); } /* store the result */ *alpha = result; move16 (); /* update adapter state memory */ st->prev_alpha = result; move16 (); st->prev_gc = gain_cod; move16 (); for (i = LTPG_MEM_SIZE-1; i > 0; i--) { st->ltpg_mem[i] = st->ltpg_mem[i-1]; move16 (); } /* mem[0] is just present for convenience in calling the gmed_n[5] * function above. The memory depth is really LTPG_MEM_SIZE-1. */ }

static Word16 D2i40_11( /* (o) : Index of pulses positions. */ Word16 Dn[], /* (i) : Correlations between h[] and Xn[]. */ Word16 rr[], /* (i) : Correlations of impulse response h[]. */ Word16 h[], /* (i) : Impulse response of filters. */ Word16 code[], /* (o) : Selected algebraic codeword. */ Word16 y[], /* (o) : Filtered algebraic codeword. */ Word16 *sign /* (o) : Signs of 4 pulses. */ ) { Word16 i0, i1, ip0, ip1, p0, p1; Word16 i, j, index, tmp, swap; Word16 ps0, ps1, alp, alp0; Word32 alp1; Word16 ps1c, psc, alpha; Word32 L_temp; Word16 posIndex[2], signIndex[2]; Word16 m0_bestPos, m1_bestPos; Word16 p_sign[L_SUBFR]; Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; Word16 *rri0i1, *RRi1i1, *rri0i3, *RRi3i4; Word16 *rri1i2, *rri1i3, *rri1i4; Word16 *rri2i3; Word16 *ptr_ri0i0, *ptr_ri1i1; Word16 *ptr_ri0i1, *ptr_Ri0i2, *ptr_ri0i3, *ptr_Ri3i4; Word16 *ptr_ri1i2, *ptr_ri1i3, *ptr_ri1i4; Word16 *ptr_ri2i3; Word16 *outPtr_ri1i1; /* Outside loop pointer */ /* Init pointers */ rri0i0 = rr; rri1i1 = rri0i0 + NB_POS; rri2i2 = rri1i1 + NB_POS; rri3i3 = rri2i2 + NB_POS; rri4i4 = rri3i3 + NB_POS; rri0i1 = rri4i4 + NB_POS; RRi1i1 = rri0i1 + MSIZE; /* Special for 6.4 kbps */ rri0i3 = RRi1i1 + MSIZE; RRi3i4 = rri0i3 + MSIZE; /* Special for 6.4 kbps */ rri1i2 = RRi3i4 + MSIZE; rri1i3 = rri1i2 + MSIZE; rri1i4 = rri1i3 + MSIZE; rri2i3 = rri1i4 + MSIZE; /*-----------------------------------------------------------------------* * Chose the sign of the impulse. * *-----------------------------------------------------------------------*/ for (i=0; i<L_SUBFR; i++) { if( Dn[i] >= 0) { p_sign[i] = 0x7fff; } else { p_sign[i] = (Word16)0x8000; Dn[i] = negate(Dn[i]); } } /*-------------------------------------------------------------------* * Modification of rrixiy[] to take signs into account. * *-------------------------------------------------------------------*/ ptr_ri0i1 = rri0i1; ptr_ri0i3 = rri0i3; for(i0=0; i0<L_SUBFR; i0+=STEP) { for(i1=1; i1<L_SUBFR; i1+=STEP) { *ptr_ri0i1 = mult(*ptr_ri0i1, mult(p_sign[i0], p_sign[i1])); ptr_ri0i1++; *ptr_ri0i3 = mult(*ptr_ri0i3, mult(p_sign[i0], p_sign[i1+2])); ptr_ri0i3++; } } ptr_ri1i2 = rri1i2; ptr_ri1i3 = rri1i3; ptr_ri1i4 = rri1i4; for(i0=1; i0<L_SUBFR; i0+=STEP) { for(i1=2; i1<L_SUBFR; i1+=STEP) { *ptr_ri1i2 = mult(*ptr_ri1i2, mult(p_sign[i0], p_sign[i1])); ptr_ri1i2++; *ptr_ri1i3 = mult(*ptr_ri1i3, mult(p_sign[i0], p_sign[i1+1])); ptr_ri1i3++; *ptr_ri1i4 = mult(*ptr_ri1i4, mult(p_sign[i0], p_sign[i1+2])); ptr_ri1i4++; } } ptr_ri2i3 = rri2i3; ptr_Ri3i4 = RRi3i4; for(i0=2; i0<L_SUBFR; i0+=STEP) { for(i1=3; i1<L_SUBFR; i1+=STEP) { *ptr_ri2i3 = mult(*ptr_ri2i3, mult(p_sign[i0], p_sign[i1])); ptr_ri2i3++; *ptr_Ri3i4 = mult(*ptr_Ri3i4, mult(p_sign[i0+1], p_sign[i1+1])); ptr_Ri3i4++; } } ptr_Ri0i2 = RRi1i1; for(i0=1; i0<L_SUBFR; i0+=STEP) { for(i1=1; i1<L_SUBFR; i1+=STEP) { *ptr_Ri0i2 = mult(*ptr_Ri0i2, mult(p_sign[i0], p_sign[i1])); ptr_Ri0i2++; } } /*-------------------------------------------------------------------* * The actual search. * *-------------------------------------------------------------------*/ ip0 = 1; /* Set to any valid pulse position */ ip1 = 0; /* Set to any valid pulse position */ psc = 0; alpha = MAX_16; ptr_ri0i1 = rri0i1; outPtr_ri1i1 = rri1i1; /* Initial values for tripple loop below */ p0=0; /* Search i0,sub0 vs. i1,sub0 */ p1=1; ptr_ri0i0 = rri0i0; for (i = 0; i<9; i++) { if (i == 4) i++; /* To get right exchange sequence */ swap = i & 1; if (i == 1) p0=1; /* Search i0,sub1 vs. i1,sub0 */ else if (i == 2) { /* Search i0,sub0 vs. i1,sub1 */ outPtr_ri1i1 = rri3i3; p0=0; p1=3; ptr_ri0i0 = rri0i0; } else if (i == 3) { /* Search i0,sub3 vs. i1,sub1 */ outPtr_ri1i1 = rri4i4; p0=3; p1=4; ptr_ri0i0 = rri3i3; } else if (i == 5) { /* Search i0,sub2 vs. i1,sub0 */ outPtr_ri1i1 = rri2i2; p0=1; p1=2; ptr_ri0i0 = rri1i1; } else if (i == 6) { /* Search i0,sub1 vs. i1,sub1 */ outPtr_ri1i1 = rri3i3; p1=3; ptr_ri0i0 = rri1i1; } else if (i == 7) { /* Search i0,sub3 vs. i1,sub0 */ outPtr_ri1i1 = rri4i4; p1=4; ptr_ri0i0 = rri1i1; } else if (i == 8) { /* Search i0,sub2 vs. i1,sub1 */ outPtr_ri1i1 = rri3i3; p0=2; p1=3; } for (i0 = p0; i0<40; i0+=STEP) { ptr_ri1i1 = outPtr_ri1i1; ps0 = Dn[i0]; alp0 = *ptr_ri0i0++; for (i1 = p1; i1<40; i1+=STEP) { ps1 = add(ps0, Dn[i1]); alp1 = L_mult(alp0, 1); alp1 = L_mac(alp1, *ptr_ri1i1++, 1); alp1 = L_mac(alp1, *ptr_ri0i1++, 2); alp = extract_l(L_shr(alp1, 5)); ps1c = mult(ps1, ps1); L_temp = L_mult(ps1c, alpha); L_temp = L_msu(L_temp, psc, alp); if (L_temp > 0L) { psc = ps1c; alpha = alp; ip0 = i1; ip1 = i0; if ( swap ) { ip0 = i0; ip1 = i1; } } } } } /* convert from position to table entry index */ for (i0=0; i0<16; i0++) if (ip0 == trackTable0[i0]) break; ip0=i0; for (i1=0; i1<32; i1++) if (ip1 == trackTable1[i1]) break; ip1=i1; m0_bestPos = trackTable0[ip0]; m1_bestPos = trackTable1[ip1]; posIndex[0] = grayEncode[ip0]; posIndex[1] = grayEncode[ip1]; if (p_sign[m0_bestPos] > 0) signIndex[0] = 1; else signIndex[0] = 0; if (p_sign[m1_bestPos] > 0) signIndex[1] = 1; else signIndex[1] = 0; /* build innovation vector */ for (i = 0; i < L_SUBFR; i++) code[i] = 0; code[m0_bestPos] = shr(p_sign[m0_bestPos], 2); code[m1_bestPos] = add( code[m1_bestPos], shr(p_sign[m1_bestPos], 2)); *sign = add(signIndex[1], signIndex[1]); *sign = add(*sign, signIndex[0]); tmp = shl(posIndex[1], 4); index = add(posIndex[0], tmp); /* compute filtered cbInnovation */ for (i = 0; i < L_SUBFR; i++) y[i] = 0; if(signIndex[0] == 0) for(i=m0_bestPos, j=0; i<L_SUBFR; i++, j++) y[i] = negate(h[j]); else for(i=m0_bestPos, j=0; i<L_SUBFR; i++, j++) y[i] = h[j]; if(signIndex[1] == 0) for(i=m1_bestPos, j=0; i<L_SUBFR; i++, j++) y[i] = sub(y[i], h[j]); else for(i=m1_bestPos, j=0; i<L_SUBFR; i++, j++) y[i] = add(y[i], h[j]); return index; }

vec_RR operator-(const vec_RR& a, const vec_RR& b) { vec_RR res; sub(res, a, b); NTL_OPT_RETURN(vec_RR, res); }

static void Cor_h_X( Word16 h[], /* (i) Q12 :Impulse response of filters */ Word16 X[], /* (i) :Target vector */ Word16 D[] /* (o) :Correlations between h[] and D[] */ /* Normalized to 13 bits */ ) { Word16 i, j; Word32 s, max, L_temp; Word32 y32[L_SUBFR]; /* first keep the result on 32 bits and find absolute maximum */ max = 0; for (i = 0; i < L_SUBFR; i++) { s = 0; for (j = i; j < L_SUBFR; j++) s = L_mac(s, X[j], h[j-i]); y32[i] = s; s = L_abs(s); L_temp =L_sub(s,max); if(L_temp>0L) { max = s; } } /* Find the number of right shifts to do on y32[] */ /* so that maximum is on 13 bits */ j = norm_l(max); if( sub(j,16) > 0) { j = 16; } j = sub(18, j); for(i=0; i<L_SUBFR; i++) { D[i] = extract_l( L_shr(y32[i], j) ); } return; }

void MR795_gain_quant( GainAdaptState *adapt_st, /* i/o: gain adapter state structure */ Word16 res[], /* i : LP residual, Q0 */ Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ Word16 code[], /* i : CB innovation (unfiltered), Q13 */ Word16 frac_coeff[], /* i : coefficients (5), Q15 */ Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ /* coefficients from calc_filt_ener() */ Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */ Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ Word16 L_subfr, /* i : Subframe length */ Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */ Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */ Word16 gp_limit, /* i : pitch gain limit */ Word16 *gain_pit, /* i/o: Pitch gain, Q14 */ Word16 *gain_cod, /* o : Code gain, Q1 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener, /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ Word16 **anap, /* o : Index of quantization */ /* (first gain pitch, then code pitch)*/ CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */ Flag *pOverflow /* o : overflow indicator */ ) { Word16 frac_en[4]; Word16 exp_en[4]; Word16 ltpg, alpha, gcode0; Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */ Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */ Word16 gain_pit_index; Word16 gain_cod_index; Word16 exp; Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */ /* get list of candidate quantized pitch gain values * and corresponding quantization indices */ gain_pit_index = q_gain_pitch(MR795, gp_limit, gain_pit, g_pitch_cand, g_pitch_cind, common_amr_tbls->qua_gain_pitch_ptr, pOverflow); /*-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * * * * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * *-------------------------------------------------------------------*/ gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /* Q14 */ /* pre-quantization of codebook gain * (using three pitch gain candidates); * result: best guess of pitch gain and code gain */ MR795_gain_code_quant3( exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind, frac_coeff, exp_coeff, gain_pit, &gain_pit_index, gain_cod, &gain_cod_index, qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr, pOverflow); /* calculation of energy coefficients and LTP coding gain */ calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr, frac_en, exp_en, <pg, pOverflow); /* run gain adaptor, calculate alpha factor to balance LTP/CB gain * (this includes the gain adaptor update) * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case */ gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow); /* if this is a very low energy signal (threshold: see * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer */ if (frac_en[0] != 0 && alpha > 0) { /* innovation energy <cod cod> was already computed in gc_pred() */ /* (this overwrites the LtpResEn which is no longer needed) */ frac_en[3] = frac_code_en; exp_en[3] = exp_code_en; /* store optimum codebook gain in Q(10-exp_gcode0) */ exp = sub(cod_gain_exp, exp_gcode0, pOverflow) + 10; gain_cod_unq = shl(cod_gain_frac, exp, pOverflow); /* run quantization with modified criterion */ gain_cod_index = MR795_gain_code_quant_mod( *gain_pit, exp_gcode0, gcode0, frac_en, exp_en, alpha, gain_cod_unq, gain_cod, qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr, pOverflow); /* function result */ } *(*anap)++ = gain_pit_index; *(*anap)++ = gain_cod_index; }

static void Cor_h_D( Word16 *H, /* (i) Q12 :Impulse response of filters */ Word16 *rr /* (o) :Correlations of H[] */ ) { Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3, *rri4i4; Word16 *rri0i1, *rri0i2, *rri0i3, *rri0i4; Word16 *rri1i2, *rri1i3, *rri1i4; Word16 *rri2i3, *rri2i4; Word16 *p0, *p1, *p2, *p3, *p4; Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2; Word32 cor; Word16 i, k, ldec, l_fin_sup, l_fin_inf; Word16 h[L_SUBFR]; Word32 L_tmp; Word16 lsym; /* Scaling h[] for maximum precision */ cor = 0; for(i=0; i<L_SUBFR; i++) cor = L_mac(cor, H[i], H[i]); L_tmp = L_sub(extract_h(cor),32000); if(L_tmp>0L ) { for(i=0; i<L_SUBFR; i++) { h[i] = shr(H[i], 1);} } else { k = norm_l(cor); k = shr(k, 1); for(i=0; i<L_SUBFR; i++) { h[i] = shl(H[i], k); } } /*-----------------------------------------------------------------* * In case of G729 mode, nine cross correlations has to be * * calculated, namely the following: * * * * rri0i1[], * * rri0i2[], rri1i2[], * * rri0i3[], rri1i3[], rri2i3[], * * rri0i4[], rri1i4[], rri2i4[], * * * * In case of G729 on 6.4 kbps mode, three of the above nine cross * * correlations are not needed for the codebook search, namely * * rri0i2[], rri0i4[] and rri2i4[]. Two of these three 64-element * * positions are instead used by two cross correlations needed * * only by the 6.4 kbps mode (see D2i40_11() for details). * *-----------------------------------------------------------------*/ /* Init pointers */ rri0i0 = rr; rri1i1 = rri0i0 + NB_POS; rri2i2 = rri1i1 + NB_POS; rri3i3 = rri2i2 + NB_POS; rri4i4 = rri3i3 + NB_POS; rri0i1 = rri4i4 + NB_POS; rri0i2 = rri0i1 + MSIZE; /* Holds RRi1i1[] in 6.4 kbps mode */ rri0i3 = rri0i2 + MSIZE; rri0i4 = rri0i3 + MSIZE; /* Holds RRi3i4[] in 6.4 kbps mode */ rri1i2 = rri0i4 + MSIZE; rri1i3 = rri1i2 + MSIZE; rri1i4 = rri1i3 + MSIZE; rri2i3 = rri1i4 + MSIZE; rri2i4 = rri2i3 + MSIZE; /* Not used in 6.4 kbps mode */ /*------------------------------------------------------------* * Compute rri0i0[], rri1i1[], rri2i2[], rri3i3 and rri4i4[] * *------------------------------------------------------------*/ p0 = rri0i0 + NB_POS-1; /* Init pointers to last position of rrixix[] */ p1 = rri1i1 + NB_POS-1; p2 = rri2i2 + NB_POS-1; p3 = rri3i3 + NB_POS-1; p4 = rri4i4 + NB_POS-1; ptr_h1 = h; cor = 0; for(i=0; i<NB_POS; i++) { cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++; *p4-- = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++; *p3-- = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++; *p2-- = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++; *p1-- = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++; *p0-- = extract_h(cor); } /*-----------------------------------------------------------------* * Compute elements of: rri2i3[], rri1i2[], rri0i1[] and rri0i4[] * *-----------------------------------------------------------------*/ l_fin_sup = MSIZE-1; l_fin_inf = l_fin_sup-(Word16)1; ldec = NB_POS+1; ptr_hd = h; ptr_hf = ptr_hd + 1; for(k=0; k<NB_POS; k++) { p4 = rri0i4 + l_fin_sup; p3 = rri2i3 + l_fin_sup; p2 = rri1i2 + l_fin_sup; p1 = rri0i1 + l_fin_sup; p0 = rri0i4 + l_fin_inf; cor = 0; ptr_h1 = ptr_hd; ptr_h2 = ptr_hf; for(i=k+(Word16)1; i<NB_POS; i++ ) { cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; if (sub(CODEC_MODE, 1) == 0) *p4 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p2 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p1 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; if (sub(CODEC_MODE, 2) == 0) *p0 = extract_h(cor); p4 -= ldec; p3 -= ldec; p2 -= ldec; p1 -= ldec; p0 -= ldec; } cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; if (sub(CODEC_MODE, 1) == 0) *p4 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p2 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p1 = extract_h(cor); l_fin_sup -= NB_POS; l_fin_inf--; ptr_hf += STEP; } /*---------------------------------------------------------------------* * Compute elements of: rri2i4[], rri1i3[], rri0i2[], rri1i4[], rri0i3 * *---------------------------------------------------------------------*/ ptr_hd = h; ptr_hf = ptr_hd + 2; l_fin_sup = MSIZE-1; l_fin_inf = l_fin_sup-(Word16)1; for(k=0; k<NB_POS; k++) { p4 = rri2i4 + l_fin_sup; p3 = rri1i3 + l_fin_sup; p2 = rri0i2 + l_fin_sup; p1 = rri1i4 + l_fin_inf; p0 = rri0i3 + l_fin_inf; cor = 0; ptr_h1 = ptr_hd; ptr_h2 = ptr_hf; for(i=k+(Word16)1; i<NB_POS; i++ ) { cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p4 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p2 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p1 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p0 = extract_h(cor); p4 -= ldec; p3 -= ldec; p2 -= ldec; p1 -= ldec; p0 -= ldec; } cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p4 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p2 = extract_h(cor); l_fin_sup -= NB_POS; l_fin_inf--; ptr_hf += STEP; } /*----------------------------------------------------------------------* * Compute elements of: rri1i4[], rri0i3[], rri2i4[], rri1i3[], rri0i2 * *----------------------------------------------------------------------*/ ptr_hd = h; ptr_hf = ptr_hd + 3; l_fin_sup = MSIZE-1; l_fin_inf = l_fin_sup-(Word16)1; for(k=0; k<NB_POS; k++) { p4 = rri1i4 + l_fin_sup; p3 = rri0i3 + l_fin_sup; p2 = rri2i4 + l_fin_inf; p1 = rri1i3 + l_fin_inf; p0 = rri0i2 + l_fin_inf; ptr_h1 = ptr_hd; ptr_h2 = ptr_hf; cor = 0; for(i=k+(Word16)1; i<NB_POS; i++ ) { cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p4 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p2 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p1 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p0 = extract_h(cor); p4 -= ldec; p3 -= ldec; p2 -= ldec; p1 -= ldec; p0 -= ldec; } cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p4 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p3 = extract_h(cor); l_fin_sup -= NB_POS; l_fin_inf--; ptr_hf += STEP; } /*----------------------------------------------------------------------* * Compute elements of: rri0i4[], rri2i3[], rri1i2[], rri0i1[] * *----------------------------------------------------------------------*/ ptr_hd = h; ptr_hf = ptr_hd + 4; l_fin_sup = MSIZE-1; l_fin_inf = l_fin_sup-(Word16)1; for(k=0; k<NB_POS; k++) { if (sub(CODEC_MODE, 2) == 0) p3 = rri0i4 + l_fin_sup; if (sub(CODEC_MODE, 1) == 0) p3 = rri0i4 + l_fin_inf; p2 = rri2i3 + l_fin_inf; p1 = rri1i2 + l_fin_inf; p0 = rri0i1 + l_fin_inf; ptr_h1 = ptr_hd; ptr_h2 = ptr_hf; cor = 0; for(i=k+(Word16)1; i<NB_POS; i++ ) { cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; if (sub(CODEC_MODE, 2) == 0) *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; if (sub(CODEC_MODE, 1) == 0) *p3 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p2 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p1 = extract_h(cor); cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p0 = extract_h(cor); p3 -= ldec; p2 -= ldec; p1 -= ldec; p0 -= ldec; } cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; if (sub(CODEC_MODE, 2) == 0) *p3 = extract_h(cor); l_fin_sup -= NB_POS; l_fin_inf--; ptr_hf += STEP; } if (sub(CODEC_MODE, 1) == 0) { /*-----------------------------------------------------------------* * Compute elements of RRi1i1[] * *-----------------------------------------------------------------*/ p0 = rri0i2; for (k=0; k<NB_POS; k++) { *p0 = *rri1i1; rri1i1++; p0 += ldec; } ptr_hd = h; ptr_hf = ptr_hd + 5; l_fin_sup = MSIZE-1; l_fin_inf = l_fin_sup-NB_POS; lsym = NB_POS - (Word16)1; for(k=(Word16)1; k<NB_POS; k++) { p0 = rri0i2 + l_fin_inf; ptr_h1 = ptr_hd; ptr_h2 = ptr_hf; cor = 0; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p0 = extract_h(cor); *(p0+lsym) = extract_h(cor); p0 -= ldec; for(i=k+(Word16)1; i<NB_POS; i++ ) { cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++; *p0 = extract_h(cor); *(p0+lsym) = extract_h(cor); p0 -= ldec; } l_fin_inf -= NB_POS; ptr_hf += STEP; lsym += NB_POS - (Word16)1; } } return; }

/* * Decompose CWallet transaction to model transaction records. */ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) { QList<TransactionRecord> parts; int64_t nTime = wtx.GetTxTime(); CAmount nCredit = wtx.GetCredit(ISMINE_ALL); CAmount nDebit = wtx.GetDebit(ISMINE_ALL); CAmount nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); std::map<std::string, std::string> mapValue = wtx.mapValue; if (nNet > 0 || wtx.IsCoinBase()) { // // Credit // for(unsigned int i = 0; i < wtx.tx->vout.size(); i++) { const CTxOut& txout = wtx.tx->vout[i]; isminetype mine = wallet->IsMine(txout); if(mine) { TransactionRecord sub(hash, nTime); CTxDestination address; sub.idx = i; // vout index sub.credit = txout.nValue; sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { // Received by Bitcoin Address sub.type = TransactionRecord::RecvWithAddress; sub.address = CBitcoinAddress(address).ToString(); } else { // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction sub.type = TransactionRecord::RecvFromOther; sub.address = mapValue["from"]; } if (wtx.IsCoinBase()) { // Generated sub.type = TransactionRecord::Generated; } parts.append(sub); } } } else { bool involvesWatchAddress = false; isminetype fAllFromMe = ISMINE_SPENDABLE; for (const CTxIn& txin : wtx.tx->vin) { isminetype mine = wallet->IsMine(txin); if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllFromMe > mine) fAllFromMe = mine; } isminetype fAllToMe = ISMINE_SPENDABLE; for (const CTxOut& txout : wtx.tx->vout) { isminetype mine = wallet->IsMine(txout); if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllToMe > mine) fAllToMe = mine; } if (fAllFromMe && fAllToMe) { // Payment to self CAmount nChange = wtx.GetChange(); parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", -(nDebit - nChange), nCredit - nChange)); parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument } else if (fAllFromMe) { // // Debit // CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) { const CTxOut& txout = wtx.tx->vout[nOut]; TransactionRecord sub(hash, nTime); sub.idx = nOut; sub.involvesWatchAddress = involvesWatchAddress; if(wallet->IsMine(txout)) { // Ignore parts sent to self, as this is usually the change // from a transaction sent back to our own address. continue; } CTxDestination address; if (ExtractDestination(txout.scriptPubKey, address)) { // Sent to Bitcoin Address sub.type = TransactionRecord::SendToAddress; sub.address = CBitcoinAddress(address).ToString(); } else { // Sent to IP, or other non-address transaction like OP_EVAL sub.type = TransactionRecord::SendToOther; sub.address = mapValue["to"]; } CAmount nValue = txout.nValue; /* Add fee to first output */ if (nTxFee > 0) { nValue += nTxFee; nTxFee = 0; } sub.debit = -nValue; parts.append(sub); } } else { // // Mixed debit transaction, can't break down payees // parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); parts.last().involvesWatchAddress = involvesWatchAddress; } } return parts; }

Word16 ACELP_CodebookD( /* (o) :index of pulses positions */ Word16 x[], /* (i) :Target vector */ Word16 h[], /* (i) Q12 :Impulse response of filters */ Word16 T0, /* (i) :Pitch lag */ Word16 pitch_sharp, /* (i) Q14 :Last quantized pitch gain */ Word16 i_subfr, /* (i) :Indicator of 1st subframe, */ Word16 code[], /* (o) Q13 :Innovative codebook */ Word16 y[], /* (o) Q12 :Filtered innovative codebook */ Word16 *sign /* (o) :Signs of 4 pulses */ ) { Word16 i, index, sharp; Word16 Dn[L_SUBFR]; Word16 rr[DIM_RR]; /*-----------------------------------------------------------------* * Include fixed-gain pitch contribution into impulse resp. h[] * * Find correlations of h[] needed for the codebook search. * *-----------------------------------------------------------------*/ sharp = shl(pitch_sharp, 1); /* From Q14 to Q15 */ if (sub(T0, L_SUBFR)<0) for (i = T0; i < L_SUBFR; i++){ /* h[i] += pitch_sharp*h[i-T0] */ h[i] = add(h[i], mult(h[i-T0], sharp)); } Cor_h_D(h, rr); /*-----------------------------------------------------------------* * Compute correlation of target vector with impulse response. * *-----------------------------------------------------------------*/ Cor_h_X(h, x, Dn); /*-----------------------------------------------------------------* * Find innovative codebook. * *-----------------------------------------------------------------*/ if (sub(CODEC_MODE, 2) == 0) index = D4i40_17(Dn, rr, h, code, y, sign, i_subfr); else if (sub(CODEC_MODE, 1) == 0) index = D2i40_11(Dn, rr, h, code, y, sign); else { fprintf(stderr, "CODEC mode invalid\n"); exit(-1); } /*-----------------------------------------------------------------* * Compute innovation vector gain. * * Include fixed-gain pitch contribution into code[]. * *-----------------------------------------------------------------*/ if(sub(T0 ,L_SUBFR) <0) for (i = T0; i < L_SUBFR; i++) { /* code[i] += pitch_sharp*code[i-T0] */ code[i] = add(code[i], mult(code[i-T0], sharp)); } return index; }

int divide(struct NUMBER *a,struct NUMBER *b,struct NUMBER *c,struct NUMBER *d) { int k,res = 0; struct NUMBER tmp_a,n,m,l,abs_a,abs_b; copyNumber(a,&tmp_a);//aが破壊されないようにtmp_aにコピー if(isZero(b) == 0)//isZeroは0か-1が返るので return(-1); clearByZero(c); clearByZero(d);//c,dを0でクリア clearByZero(&n); clearByZero(&m); clearByZero(&l);//作業用変数n,m,lを0でクリア setInt(&n,1);//適当な変数に1を突っ込む if(numComp(b,&n) == 0)//除数が1ならば { copyNumber(a,c);//c = a; return(0); } getAbs(a,&abs_a); getAbs(b,&abs_b);//a,bの絶対値をとる if((getSign(a) == 1) && (getSign(b) == 1)) { while(1)//xから何回yを引けるか調べる { if(numComp(&tmp_a,b) == -1)//a < bならば break; copyNumber(b,&n);//bを作業用変数nに代入 setInt(&m,1);//作業用変数mに1を代入 while(1) { copyNumber(&n,&l); mulBy10(&l,&n); copyNumber(&m,&l); mulBy10(&l,&m);//mとnを10倍 if(numComp(&tmp_a,&n) == -1)//a < nならば { copyNumber(&n,&l); divBy10(&l,&n); copyNumber(&m,&l); divBy10(&l,&m);//10倍しちゃったので10で割る。いい方法を模索中、一時的に保存する? break; } } while(1) { copyNumber(&tmp_a,&l);//lに現在のaを代入 sub(&l,&n,&tmp_a);//a = l -n; すなわち a -= n; copyNumber(c,&l);//lにcを代入 add(&l,&m,c);//c = l + m;すわなち c += m; if(numComp(&tmp_a,&n) == -1) break; } } copyNumber(&tmp_a,d);//残ったtmp_aがすなわち剰余 } if((getSign(a) == 1) && (getSign(b) == -1)) { res = divide(a,&abs_b,c,d); setSign(c,-1);//+ / -は解が負であるため } if((getSign(a) == -1) && (getSign(b) == 1)) { res = divide(&abs_a,b,c,d); setSign(c,-1);//- / +は解が負であるため setSign(d,-1);//- / +は剰余が負であるため } if((getSign(a) == -1)&& (getSign(b) == -1)) { res = divide(&abs_a,&abs_b,c,d);//-x / -yは解が正であるためなにもしない setSign(d,-1);//- / -は剰余が負であるため } return(res); }

static void RowTransform(vec_ZZ& A, vec_ZZ& B, const ZZ& MU1) // x = x - y*MU { NTL_ZZRegister(T); NTL_ZZRegister(MU); long k; long n = A.length(); long i; MU = MU1; if (MU == 1) { for (i = 1; i <= n; i++) sub(A(i), A(i), B(i)); return; } if (MU == -1) { for (i = 1; i <= n; i++) add(A(i), A(i), B(i)); return; } if (MU == 0) return; if (NumTwos(MU) >= NTL_ZZ_NBITS) k = MakeOdd(MU); else k = 0; if (MU.WideSinglePrecision()) { long mu1; conv(mu1, MU); if (k > 0) { for (i = 1; i <= n; i++) { mul(T, B(i), mu1); LeftShift(T, T, k); sub(A(i), A(i), T); } } else { for (i = 1; i <= n; i++) { MulSubFrom(A(i), B(i), mu1); } } } else { for (i = 1; i <= n; i++) { mul(T, B(i), MU); if (k > 0) LeftShift(T, T, k); sub(A(i), A(i), T); } } }

void GPUDrawScanlineCodeGenerator::Init() { mov(eax, dword[esp + _top]); // uint16* fb = (uint16*)m_global.vm + (top << (10 + sel.scalex)) + left; mov(edi, eax); shl(edi, 10 + m_sel.scalex); add(edi, edx); lea(edi, ptr[edi * 2 + (size_t)m_local.gd->vm]); // int steps = pixels - 8; sub(ecx, 8); if(m_sel.dtd) { // dither = GSVector4i::load<false>(&m_dither[top & 3][left & 3]); and(eax, 3); shl(eax, 5); and(edx, 3); shl(edx, 1); movdqu(xmm0, ptr[eax + edx + (size_t)m_dither]); movdqa(ptr[&m_local.temp.dither], xmm0); } mov(edx, dword[esp + _v]); if(m_sel.tme) { mov(esi, dword[&m_local.gd->tex]); // GSVector4i vt = GSVector4i(v.t).xxzzl(); cvttps2dq(xmm4, ptr[edx + offsetof(GSVertexSW, t)]); pshuflw(xmm4, xmm4, _MM_SHUFFLE(2, 2, 0, 0)); // s = vt.xxxx().add16(m_local.d.s); // t = vt.yyyy().add16(m_local.d.t); pshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1)); paddw(xmm2, ptr[&m_local.d.s]); if(!m_sel.sprite) { paddw(xmm3, ptr[&m_local.d.t]); } else { if(m_sel.ltf) { movdqa(xmm0, xmm3); psllw(xmm0, 8); psrlw(xmm0, 1); movdqa(ptr[&m_local.temp.vf], xmm0); } } movdqa(ptr[&m_local.temp.s], xmm2); movdqa(ptr[&m_local.temp.t], xmm3); } if(m_sel.tfx != 3) // != decal { // GSVector4i vc = GSVector4i(v.c).xxzzlh(); cvttps2dq(xmm6, ptr[edx + offsetof(GSVertexSW, c)]); pshuflw(xmm6, xmm6, _MM_SHUFFLE(2, 2, 0, 0)); pshufhw(xmm6, xmm6, _MM_SHUFFLE(2, 2, 0, 0)); // r = vc.xxxx(); // g = vc.yyyy(); // b = vc.zzzz(); pshufd(xmm4, xmm6, _MM_SHUFFLE(0, 0, 0, 0)); pshufd(xmm5, xmm6, _MM_SHUFFLE(1, 1, 1, 1)); pshufd(xmm6, xmm6, _MM_SHUFFLE(2, 2, 2, 2)); if(m_sel.iip) { // r = r.add16(m_local.d.r); // g = g.add16(m_local.d.g); // b = b.add16(m_local.d.b); paddw(xmm4, ptr[&m_local.d.r]); paddw(xmm5, ptr[&m_local.d.g]); paddw(xmm6, ptr[&m_local.d.b]); } movdqa(ptr[&m_local.temp.r], xmm4); movdqa(ptr[&m_local.temp.g], xmm5); movdqa(ptr[&m_local.temp.b], xmm6); } }

double runtest(char* start, size_t length, int write) { volatile char x; struct timeval s1, e1; struct timeval s2, e2; unsigned int numPages = length/PAGE_SIZE; group *g = &groups[0]; while (g->key && g->key!=numPages) { ++g; } unsigned int startPage= 1; unsigned int curr =startPage; unsigned int page = 0; numPages = g->z - 1; long fCount[4]; if (write) { fCount[0] = faultCount(); gettimeofday(&s1, NULL); while (page++ < numPages) { barrier(); start[curr*PAGE_SIZE] = x; curr = (curr * g->p) % g->z; } gettimeofday(&e1, NULL); fCount[1] = faultCount(); page = 0; curr = startPage; start[curr*PAGE_SIZE] = x; fCount[2] = faultCount(); gettimeofday(&s2, NULL); while (page++ < numPages) { barrier(); start[curr*PAGE_SIZE] = x; curr = (curr * g->p) % g->z; } gettimeofday(&e2, NULL); fCount[3] = faultCount(); } else { fCount[0] = faultCount(); gettimeofday(&s1, NULL); while (page++ < numPages) { barrier(); x = start[curr*PAGE_SIZE]; curr = (curr * g->p) % g->z; } gettimeofday(&e1, NULL); fCount[1] = faultCount(); page = 0; curr = startPage; x = start[curr*PAGE_SIZE]; fCount[2] = faultCount(); gettimeofday(&s2, NULL); while (page++ < numPages) { barrier(); x = start[curr*PAGE_SIZE]; curr = (curr * g->p) % g->z; } gettimeofday(&e2, NULL); fCount[3] = faultCount(); } struct timeval d1; struct timeval d2; struct timeval d3; sub(e1, s1, d1); sub(e2, s2, d2); sub(d1, d2, d3); // printf("%ld %ld\n", fCount[1]-fCount[0], fCount[3]-fCount[2]); double total = d3.tv_sec * 1000000 + d3.tv_usec; return total / numPages; }