/* v:\ece420\54x\dspclib\lab4bmain.c */ /* PN generation, IIR filtering, and autocorrelation added */ /* by Matt Kleffner - 9/2004 */ /* Original by dgs - 9/14/2001 */ /* Use governed by the Creative Commons Attribution License */ #include "v:\ece420\54x\dspclib\core.h" /* #define N 1024 */ /* Number of FFT points */ #include "lab4b.h" /* Define N here in header file */ /* function defined in pn.c */ int randsample(unsigned int *iseed); /* IIR values and buffers (declared in c_fft_given_iirc.asm) */ #define IIR_order 4 extern int scale; extern int coef[IIR_order]; extern int state[IIR_order]; int iirptr; /* function defined in autocorr.c */ void autocorr(void); /* Function defined by c_fft_given_iirc.asm */ void bit_rev_fft(void); /* FFT data buffers (declared in c_fft_given_iirc.asm) */ extern int bit_rev_data[N*2]; /* Data input for bit-reverse function */ extern int fft_data[N*2]; /* In-place FFT & Output array */ /* Our input/output buffers */ int inputs[N]; int outputs[N]; int display_inputs[N]; int autocorr_in[N]; int autocorr_out[N]; unsigned int *iseed; /* seed for randsample() */ volatile int input_full = 0; /* volatile means interrupt changes it */ int count = 0; interrupt void irq(void) { int *Xmitptr,*Rcvptr; /* pointers to Xmit & Rcv Bufs */ int i; static int in_irq = 0; /* Flag to prevent reentrance */ /* Make sure we're not in the interrupt (should never happen) */ if( in_irq ) return; /* Mark we're processing, and enable interrupts */ in_irq = 1; enable_irq(); /* The following waitaudio call is guaranteed not to actually wait; it will simply return the pointers. */ WaitAudio(&Rcvptr,&Xmitptr); /* input_full should never be true... */ if( !input_full ) { for (i=0; i= N ) input_full = 1; /* We're not in the interrupt anymore... */ disable_irq(); in_irq = 0; } main() { int i,j; *iseed = 1; iirptr = 0; /* Initialize IRQ stuff */ count = 0; input_full = 0; /* Initialize autocorr_out to zero since some values will remain zero */ for (i = 0; i < N; ++i) { autocorr_out[i] = 0; display_inputs[i] = 0; } for (i = 0; i < IIR_order; ++i) state[i] = 0; SetAudioInterrupt(irq); /* Set up interrupts */ while (1) { while( !input_full ); /* Wait for a data buffer to collect */ /* From here until we clear input_full can only take * * BlockLen sample times, so don't do too much here. */ /* First, transfer inputs and outputs */ for (i = 0; i < N; i++) { display_inputs[i] = autocorr_in[i]; outputs[i] = fft_data[i*2] << 8; /* Some statements useful in debugging */ /* display_inputs[i] = inputs[i]; */ /* autocorr_in[i] = inputs[i] */ } /* Last, set the DC coefficient to -1 for a trigger pulse */ outputs[0] = -32768; /* Done with that... ready for new data collection */ count = 0; /* Need to reset the count */ input_full = 0; /* Mark we're ready to collect more data */ /*************************************************************/ /* Now that we've gotten the data moved, we can do the */ /* more lengthy processing. */ /* Generate PN input */ for (i = 0; i < N; ++i) autocorr_in[i] = randsample(iseed); /* Filter PN input */ for (i = 0; i < N; ++i) { int sum = 0; /* Calculate and sum all feedback terms except the "oldest" one */ for (j = 0; j < (IIR_order-1); ++j) { sum += ((long int)coef[j] * (long int)state[iirptr]) >> 15; /* Avoid usage of "modulo" routine */ iirptr++; if (iirptr == IIR_order) iirptr = 0; } /* Calculate and sum oldest feedback term without incrementing iirptr */ sum += ((long int)coef[IIR_order-1] * (long int)state[iirptr]) >> 15; autocorr_in[i] = ((long int)scale * (long int)autocorr_in[i]) >> 15; autocorr_in[i] += sum; state[iirptr] = autocorr_in[i]; } /* Calculate autocorrelation */ autocorr(); /* Transfer autocorr output to FFT input buffer */ for (i = 0; i < N; i++) { bit_rev_data[i*2] = autocorr_out[i]; bit_rev_data[i*2+1] = 0; } /* Bit-reverse and compute FFT */ bit_rev_fft(); /* Done, wait for next time around! */ } }