void levinson_durbin( scalar R[], /* order+1 autocorrelation coeff */ scalar lpcs[], /* order+1 LPC's */ int order /* order of the LPC analysis */ ) { scalar a[order+1][order+1]; scalar sum, e, k; int i,j; /* loop variables */ scalar ZERO = fl_to_numb(0.0); e = R[0]; /* Equation 38a, Makhoul */ for(i=1; i<=order; i++) { sum = ZERO; for(j=1; j<=i-1; j++) sum = s_add(sum, s_mul(a[i-1][j],R[i-j])); k = s_mul(-1.0, s_div(s_add(R[i], sum),e)); /* Equation 38b, Makhoul */ if (s_abs(k) > fl_to_numb(1.0)) k = ZERO; a[i][i] = k; for(j=1; j<=i-1; j++) a[i][j] = s_add(a[i-1][j] , s_mul(k,a[i-1][i-j])); /* Equation 38c, Makhoul */ e = s_mul(e, s_sub(fl_to_numb(1.0),s_mul(k,k))); /* Equation 38d, Makhoul */ } for(i=1; i<=order; i++) lpcs[i] = a[order][i]; lpcs[0] = fl_to_numb(1.0); }
void find_aks( scalar Sn[], /* Nsam samples with order sample memory */ scalar a[], /* order+1 LPCs with first coeff 1.0 */ int Nsam, /* number of input speech samples */ int order, /* order of the LPC analysis */ scalar *E /* residual energy */ ) { scalar Wn[LPC_MAX_N]; /* windowed frame of Nsam speech samples */ scalar R[order+1]; /* order+1 autocorrelation values of Sn[] */ int i; assert(Nsam < LPC_MAX_N); hanning_window(Sn,Wn,Nsam); autocorrelate(Wn,R,Nsam,order); levinson_durbin(R,a,order); *E = fl_to_numb(0.0); for(i=0; i<=order; i++) *E = s_add(*E , s_mul(a[i],R[i])); if (*E < fl_to_numb(0.0)) { #ifdef MATH_Q16_16 *E = 1; #else *E = powf(2, -16);//fl_to_numb(1E-12); For debuging purposes. #endif } }
void synthesis_filter( scalar res[], /* Nsam input residual (excitation) samples */ scalar a[], /* LPCs for this frame of speech samples */ int Nsam, /* number of speech samples */ int order, /* LPC order */ scalar Sn_[] /* Nsam output synthesised speech samples */ ) { int i,j; /* loop variables */ /* Filter Nsam samples */ for(i=0; i<Nsam; i++) { Sn_[i] = s_mul(res[i],a[0]); for(j=1; j<=order; j++) Sn_[i] = s_sub(Sn_[i], s_mul(Sn_[i-j],a[j])); } }
void hanning_window( scalar Sn[], /* input frame of speech samples */ scalar Wn[], /* output frame of windowed samples */ int Nsam /* number of samples */ ) { int i; /* loop variable */ scalar HALF = fl_to_numb(0.5); scalar PI2_ = fl_to_numb(2*PI); scalar Nsam_ = int_to_numb(Nsam-1); for(i=0; i<Nsam; i++){ scalar sc_cos = s_mul(HALF,s_cos(s_mul( PI2_, s_div(fl_to_numb((float)i),Nsam_)))); scalar sc_a = s_sub(HALF, sc_cos); Wn[i] = s_mul(Sn[i], sc_a); } }
void weight( scalar ak[], /* vector of order+1 LPCs */ scalar gamma, /* weighting factor */ int order, /* num LPCs (excluding leading 1.0) */ scalar akw[] /* weighted vector of order+1 LPCs */ ) { int i; for(i=1; i<=order; i++) akw[i] = s_mul(ak[i],s_powf(gamma,fl_to_numb((float)i))); }
void *nlp_create( int m /* analysis window size */ ) { NLP *nlp; int i; assert(m <= PMAX_M); nlp = (NLP*)malloc(sizeof(NLP)); if (nlp == NULL) return NULL; nlp->m = m; scalar PI2_ = fl_to_numb(2*PI); scalar DEC_ = int_to_numb(m/DEC - 1); scalar HALF = fl_to_numb(.5); scalar ZERO = fl_to_numb(0.0); scalar a, b, c; for(i=0; i<m/DEC; i++) { a = s_div(s_mul(PI2_, int_to_numb(i) ) , DEC_); b = s_mul(HALF,s_cos(a)); nlp->w[i] = s_sub(HALF, b); //nlp->w[i] = 0.5 - 0.5*cosf(2*PI*i/(m/DEC-1)); } for(i=0; i<PMAX_M; i++) nlp->sq[i] = ZERO; nlp->mem_x = ZERO; nlp->mem_y = ZERO; for(i=0; i<NLP_NTAP; i++) nlp->mem_fir[i] = ZERO; nlp->fft_cfg = kiss_fft_alloc (PE_FFT_SIZE, 0, NULL, NULL); assert(nlp->fft_cfg != NULL); return (void*)nlp; }
void de_emp( scalar Sn_de[], /* output frame of speech samples */ scalar Sn[], /* input frame of speech samples */ scalar *mem, /* Sn[-1]single sample memory */ int Nsam /* number of speech samples to use */ ) { int i; scalar BETA_ = fl_to_numb(BETA); for(i=0; i<Nsam; i++) { Sn_de[i] = s_add(Sn[i] , s_mul(BETA_, mem[0])); mem[0] = Sn_de[i]; } }
void inverse_filter( scalar Sn[], /* Nsam input samples */ scalar a[], /* LPCs for this frame of samples */ int Nsam, /* number of samples */ scalar res[], /* Nsam residual samples */ int order /* order of LPC */ ) { int i,j; /* loop variables */ for(i=0; i<Nsam; i++) { res[i] = fl_to_numb(0.0); for(j=0; j<=order; j++) res[i] = s_add(res[i] , s_mul(Sn[i-j],a[j])); } }
void autocorrelate( scalar Sn[], /* frame of Nsam windowed speech samples */ scalar Rn[], /* array of P+1 autocorrelation coefficients */ int Nsam, /* number of windowed samples to use */ int order /* order of LPC analysis */ ) { int i,j; /* loop variables */ scalar Zero = fl_to_numb(0.0); for(j=0; j<order+1; j++) { Rn[j] = Zero; for(i=0; i<Nsam-j; i++) Rn[j] = s_add(Rn[j] , s_mul(Sn[i],Sn[i+j])); } }
/* Add a weak learner h to the strong classifier H */ void addWeak( int posCount, int negCount, int blockCount, int selectTable[], float ***POS, float ***NEG, Matrix *posWeight, Matrix *negWeight, Ada *strong, int *hUsed ) { /* For all possible features (Bid, Fid) */ int Iid, Bid, Fid; Matrix posCorrect, negCorrect, ONES; /* classification correctness matrices */ Matrix bestPosCorrect, bestNegCorrect; float bestError = 1.f; int bestBid, bestFid; short bestParity; float bestDecision; float alpha; float normalize; #if SHOWAVGERROR float avgError = 1.f; int round = 0; #endif ones( &posCorrect, 1, posCount, 1 ); ones( &negCorrect, 1, posCount, 1 ); ones( &ONES, 1, posCount, 1 ); #if 0 /* Show the data weight */ full_dump( posWeight, "posWeight", ALL, FLOAT ); full_dump( negWeight, "negWeight", ALL, FLOAT ); #endif printf( "Add a weak classifier\n" ); for ( Bid = 0; Bid < blockCount; Bid++ ) { for ( Fid = 0; Fid < FEATURE_COUNT; Fid++ ) { float POS_mean = 0.f, NEG_mean = 0.f; float decision; float error = 0.f; short parity = +1; /* default: ... NEG_mean ... | ... POS_mean ... */ /* [0] Initilize the matrices: Restore to all 1's */ full_assign( &ONES, &posCorrect, ALL, ALL ); full_assign( &ONES, &negCorrect, ALL, ALL ); /* [1] Compute the POS & NEG mean feature value */ for ( Iid = 0; Iid < posCount; Iid++ ) { POS_mean += POS[ Iid ][ Bid ][ Fid ]; NEG_mean += NEG[ selectTable[ Iid ] ][ Bid ][ Fid ]; } POS_mean /= posCount; NEG_mean /= posCount; /* default decision threshold: avg of POS_mean and NEG_mean */ decision = ( POS_mean + NEG_mean ) / 2.f; if ( POS_mean < NEG_mean ) { parity = -1; /* toggle: ... POS_mean ... | ... NEG_mean ... */ } #if 0 printf( "Bid: %d, Fid: %d, POS_mean: %f, NEG_mean: %f\n", Bid, Fid, POS_mean, NEG_mean ); #endif /* [2] Classification and compute the WEIGHTED error rate */ for ( Iid = 0; Iid < posCount; Iid++ ) { /* positive & wrong */ if ( parity * POS[ Iid ][ Bid ][ Fid ] < parity * decision ) { error += posWeight->data[ 0 ][ 0 ][ Iid ]; posCorrect.data[ 0 ][ 0 ][ Iid ] = -1.f; } /* negative & wrong */ if ( parity * NEG[ selectTable[ Iid ] ][ Bid ][ Fid ] > parity * decision ) { error += negWeight->data[ 0 ][ 0 ][ Iid ]; negCorrect.data[ 0 ][ 0 ][ Iid ] = -1.f; } } #if SHOWAVGERROR printf( "Weighted error rate: %f\n", error ); #endif /* record the best h */ if ( error < bestError ) { copy( &posCorrect, &bestPosCorrect ); copy( &negCorrect, &bestNegCorrect ); bestError = error; bestBid = Bid; bestFid = Fid; bestParity = parity; bestDecision = decision; } #if SHOWAVGERROR round++; avgError += error; #endif } /* end of loop Fid */ } /* end of loop Bid */ #if SHOWAVGERROR avgError /= round; printf( "Avg. weighted error rate: %f\n", avgError ); #endif printf( "\nBest weighted error rate: %f, Bid: %d, Fid: %d\n", bestError, bestBid, bestFid ); /* make sure that best error rate < 0.5 (random guessing) */ if ( bestError >= 0.5 ) { error( "addWeak(): Best error rate is above 0.5!" ); } #if 0 full_dump( &bestPosCorrect, "bestPosCorrect", ALL, INT ); full_dump( &bestNegCorrect, "bestNegCorrect", ALL, INT ); #endif /* [3] Record the best parameters, then determine the alpha weight for this weak classifier. */ strong[ *hUsed ].Bid = bestBid; strong[ *hUsed ].Fid = bestFid; strong[ *hUsed ].parity = bestParity; strong[ *hUsed ].decision = bestDecision; alpha = logf( ( 1.f - bestError ) / bestError ) / 2.f; strong[ *hUsed ].alpha = alpha; printf( "alpha%d: %f\n", *hUsed, alpha ); /* [4] Update the data weight */ s_mul( &bestPosCorrect, -alpha ); s_mul( &bestNegCorrect, -alpha ); s_expRaise( &bestPosCorrect ); s_expRaise( &bestNegCorrect ); e_mul( &bestPosCorrect, posWeight, posWeight ); e_mul( &bestNegCorrect, negWeight, negWeight ); normalize = m_sum( posWeight ) + m_sum( negWeight ); s_mul( posWeight, 1.f / normalize ); s_mul( negWeight, 1.f / normalize ); (*hUsed)++; /* free memory space */ freeMatrix( &posCorrect ); freeMatrix( &negCorrect ); freeMatrix( &bestPosCorrect ); freeMatrix( &bestNegCorrect ); }
/* learn AdaBoost stage A[i,j] */ void learnA( int posCount, int negCount, int blockCount, int *rejectCount, bool rejected[], float ***POS, float ***NEG, Ada *H, float *F_current, float d_minA, float f_maxA, FILE *fout ) { int selectTable[ posCount ]; /* image selection table */ int imgCount = posCount * 2; float initialW = 1.f / (float)imgCount; Matrix posWeight, negWeight; /* data weight in AdaBoost */ int hAllocated = 10; int hUsed = 0; int Iid, t; float f_local = 1.f; float threshold = 0.f; /* threshold of the strong classifier A[i,j], should be recorded */ Matrix posResult, negResult; ones( &posWeight, 1, posCount, 1 ); ones( &negWeight, 1, posCount, 1 ); H = (Ada *)malloc( hAllocated * sizeof( Ada ) ); zeros( &posResult, 1, posCount, 1 ); zeros( &negResult, 1, posCount, 1 ); /* Initialize the data weight */ s_mul( &posWeight, initialW ); s_mul( &negWeight, initialW ); /* [0] Randomly select NEG examples from the bootstrap set * Report an error if NEG images are not enough */ if ( posCount + (*rejectCount) > negCount ) { fprintf( fout, "Warning: Not enough NEG images.\n" ); error( "learnA(): Not enough NEG images." ); } select_neg( posCount, negCount, rejected, selectTable ); while ( f_local > f_maxA ) { int fpCount; /* false positive count */ float d_local = 0.f; /* [1] Add a weak learner h to the strong classifier A[i,j] */ /* Use realloc() if H is full */ if ( hUsed == hAllocated ) { hAllocated *= 2; printf( "call realloc()\n" ); H = (Ada*)realloc( H, hAllocated * sizeof( Ada ) ); } addWeak( posCount, negCount, blockCount, selectTable, POS, NEG, &posWeight, &negWeight, H, &hUsed ); threshold = 0.f; /*** Adjust by the threshold ONLY WHEN NECESSARY ***/ float minPosResult = 0.f; /* minimum value of the positive result */ int detect = 0; /* detection count */ fpCount = 0; /* [2.1] Use the H(x) so far to trial-classify * H(x) = sign( sum[alpha_t * h_t(x)] ) * Process the POS and NEG together in one loop */ for ( Iid = 0; Iid < posCount; Iid++ ) { float posTemp = 0.f; float negTemp = 0.f; for ( t = 0; t < hUsed; t++ ) { int Bid = H[ t ].Bid; int Fid = H[ t ].Fid; short parity = H[ t ].parity; float decision = H[ t ].decision; float alpha = H[ t ].alpha; /* determine that positive is positive */ if ( parity * POS[ Iid ][ Bid ][ Fid ] >= parity * decision ) { posTemp += alpha; } /* determine that positive is negative */ else { posTemp -= alpha; } /* determine that negative is positive */ if ( parity * NEG[ selectTable[ Iid ] ][ Bid ][ Fid ] >= parity * decision ) { negTemp += alpha; } /* determine that negative is negative */ else { negTemp -= alpha; } } /* end of loop "t" */ /* Record into posResult or negResult, and collect min( posResult ) */ posResult.data[ 0 ][ 0 ][ Iid ] = posTemp; negResult.data[ 0 ][ 0 ][ Iid ] = negTemp; if ( posTemp < minPosResult ) { minPosResult = posTemp; } } /* end of loop "Iid" */ #if 0 full_dump( &posResult, "posResult", ALL, FLOAT ); full_dump( &negResult, "negResult", ALL, FLOAT ); #endif #if 1 /* count for detections and false positives */ for ( Iid = 0; Iid < posCount; Iid++ ) { if ( posResult.data[ 0 ][ 0 ][ Iid ] >= 0.f ) { detect++; } if ( negResult.data[ 0 ][ 0 ][ Iid ] >= 0.f ) { fpCount++; } } d_local = (float)detect / (float)posCount; printf( "Before modify threshold:\n Detection rate: %f ( %d / %d )\n", d_local, detect, posCount ); /* [3] Calculate f_local of H(x) */ f_local = (float)fpCount / (float)posCount; printf( " False positive rate: %f ( %d / %d )\n", f_local, fpCount, posCount ); #endif /* [2.2] Modify the threshold of H(x) to fulfill d_minA * If min( posResult ) < 0, then let * result = result - min( posResult ) so that all POS data are * determined as positive, i.e., detection rate = 100% */ if ( minPosResult < 0.f ) { threshold = minPosResult; s_add( &posResult, -threshold ); s_add( &negResult, -threshold ); } printf( "threshold: %f\n", threshold ); #if 0 full_dump( &posResult, "posResult", ALL, FLOAT ); full_dump( &negResult, "negResult", ALL, FLOAT ); #endif /* count for detections and false positives */ detect = 0; fpCount = 0; for ( Iid = 0; Iid < posCount; Iid++ ) { if ( posResult.data[ 0 ][ 0 ][ Iid ] >= 0.f ) { detect++; } if ( negResult.data[ 0 ][ 0 ][ Iid ] >= 0.f ) { fpCount++; } } d_local = (float)detect / (float)posCount; printf( " After modify threshold:\n Detection rate: %f ( %d / %d )\n", d_local, detect, posCount ); //assert( d_local >= d_minA ); /* [3] Calculate f_local of H(x) */ f_local = (float)fpCount / (float)posCount; printf( "False positive rate: %f ( %d / %d )\n", f_local, fpCount, posCount ); } /* end of loop "f_local > f_maxA" */ *F_current *= f_local; printf( "\nWeak learners used: %d\n", hUsed ); printf( "Overall false positive rate: %f\n", *F_current ); /* [4] Put in the "rejection list" the negative images rejected by H(x) */ for ( Iid = 0; Iid < posCount; Iid++ ) { if ( negResult.data[ 0 ][ 0 ][ Iid ] < 0.f ) { rejected[ selectTable[ Iid ] ] = true; (*rejectCount)++; } } printf( "Rejected %d negative images in total.\n", *rejectCount ); getchar(); /* [5] Output H(x) information to file */ fprintf( fout, "%d %f\n", hUsed, threshold ); for ( t = 0; t < hUsed; t++ ) { fprintf( fout, "%d %d %d %f %f\n", H[ t ].Bid, H[ t ].Fid, H[ t ].parity, H[ t ].decision, H[ t ].alpha ); } /* Free memory space */ freeMatrix( &posWeight ); freeMatrix( &negWeight ); free( H ); freeMatrix( &posResult ); freeMatrix( &negResult ); }