void main(void) { const short m = 31; volatile short fr[31]; overlay volatile short fi[31]; struct Classification classification; setup(); LATCbits.LATC2 = 1; while(1) { ISRflag = 0; LATCbits.LATC0 = 0; // fill fr and/or fi from ADC (details to come) fix_fft(fr, fi, m); classification = *classify(fr, fi); // if something set vibrate pin // print classification(s) to LCD while(1) { Delay10TCYx(1); LATCbits.LATC1 = 1; if(ISRflag) { break; } LATCbits.LATC1 = 0; } } }
static void do_fft(gint16 out_data[], gint16 in_data[]) { gint16 im[SAMPLES]; memset(im, 0, sizeof(im)); window(in_data, SAMPLES); fix_fft(in_data, im, LOG, 0); fix_loud(out_data, in_data, im, SAMPLES/2, 0); }
void test( const char* label, char* data ) { for( int i=0; i<NUM_SAMPLES; i++ ) { mImagData[i] = 0; } fix_fft( data, mImagData, 6, 0 ); Magnitude( mMagnitude, data, mImagData, NUM_SAMPLES/2 ); ComPrintDataUchar( label, mMagnitude, NUM_SAMPLES/2 ); }
void fft_task( void ) { static fixed imag[NFFT]; static uint16_t i = 0; TASK_BEGIN(); while(1) { TASK_SEM_WAIT(&data_ready); led_red_toggle(); for(i = 0; i < NFFT; i++) { imag[i] = 0; } // compute FFT from 512 samples, the routines takes 200 ms fix_fft(processing_buf, imag, M, 0); processing_buf = NULL; led_green_toggle(); } TASK_END(); }
void Sound::run(){ signed int val; for (uint8_t i=0; i < SAMPLES_COUNT; i++){ val = analogRead(MIC_PIN); data[i] = val / 2 - 128; im[i] = 0; } //this could be done with the fix_fftr function without the im array. fix_fft(data,im,BANDS_COUNT,0); // this gets the absolute value of the values in the array, so we're only dealing with positive numbers for (uint8_t i=0; i< SAMPLES_COUNT;i++){ data[i] = sqrt(data[i] * data[i] + im[i] * im[i]); }; // Bands for(uint8_t i=0; i < AVG_BANDS_COUNT; i++){ _bandAmp[i] = 0; for(uint8_t j = 0; j < BAND_WIDTH/4; j++){ _bandAmp[i] += data[i*BAND_WIDTH/4 + j]; } if(_bandAmp[i] > maxBandAmp[i]){ maxBandAmp[i] = _bandAmp[i]; } } // Volume _volume = 0; for(uint8_t i = 0; i < AVG_BANDS_COUNT ; i++){ _volume += _bandAmp[i]; } if(_volume > maxVolume){ maxVolume = _volume; } }
void PerimeterClass::filterFrequencyMagnitude(byte idx){ mag[idx] = 0; int8_t im[FFTBINS]; memset(im, 0, sizeof im); int8_t *samples = ADCMan.getCapture(idxPin[idx]); //if (idx == 0) printADCMinMax(samples); fix_fft(samples, im, 7, 0); //digitalWrite(pinLED, LOW); for (byte i=0; i < FFTBINS/2; i++){ int v = sqrt(samples[i] * samples[i] + im[i] * im[i]); allmag[i] = max(allmag[i], v); if (i > 0) { // ignore 50 Hz band // find overall frequencies peak (peak) if (v > peakV){ peakV = v; peakBin = i; } } if (i == BANDPASS_BIN) { // bandpass //analogWrite(LED, min(255, v)); mag[idx] = max(mag[idx], v); //mag[channel] += v; peak[idx] = max(peak[idx], v); //if (v > 20) digitalWrite(pinLED, HIGH); } } //if (idx ==0) Serial.println(mag[idx]); ADCMan.restart(idxPin[idx]); if (millis() >= nextTime){ nextTime = millis() + 1000; int sum = peak[0] + peak[1]; //printResults(); peak[0]=0; peak[1]=0; peakV = 0; peakBin = 0; } }
void scanner(void) { int i, j, j2, f, n_read, offset, bin_e, bin_len, buf_len, ds, ds_p; int32_t w; struct tuning_state *ts; bin_e = tunes[0].bin_e; bin_len = 1 << bin_e; buf_len = tunes[0].buf_len; for (i=0; i<tune_count; i++) { if (do_exit >= 2) {return;} ts = &tunes[i]; f = (int)rtlsdr_get_center_freq(dev); if (f != ts->freq) { retune(dev, ts->freq);} rtlsdr_read_sync(dev, ts->buf8, buf_len, &n_read); if (n_read != buf_len) { fprintf(stderr, "Error: dropped samples.\n");} /* rms */ if (bin_len == 1) { rms_power(ts); continue; } /* prep for fft */ for (j=0; j<buf_len; j++) { fft_buf[j] = (int16_t)ts->buf8[j] - 127; } ds = ts->downsample; ds_p = ts->downsample_passes; if (boxcar && ds > 1) { j=2, j2=0; while (j < buf_len) { fft_buf[j2] += fft_buf[j]; fft_buf[j2+1] += fft_buf[j+1]; fft_buf[j] = 0; fft_buf[j+1] = 0; j += 2; if (j % (ds*2) == 0) { j2 += 2;} } } else if (ds_p) { /* recursive */ for (j=0; j < ds_p; j++) { downsample_iq(fft_buf, buf_len >> j); } /* droop compensation */ if (comp_fir_size == 9 && ds_p <= CIC_TABLE_MAX) { generic_fir(fft_buf, buf_len >> j, cic_9_tables[ds_p]); generic_fir(fft_buf+1, (buf_len >> j)-1, cic_9_tables[ds_p]); } } remove_dc(fft_buf, buf_len / ds); remove_dc(fft_buf+1, (buf_len / ds) - 1); /* window function and fft */ for (offset=0; offset<(buf_len/ds); offset+=(2*bin_len)) { // todo, let rect skip this for (j=0; j<bin_len; j++) { w = (int32_t)fft_buf[offset+j*2]; w *= (int32_t)(window_coefs[j]); //w /= (int32_t)(ds); fft_buf[offset+j*2] = (int16_t)w; w = (int32_t)fft_buf[offset+j*2+1]; w *= (int32_t)(window_coefs[j]); //w /= (int32_t)(ds); fft_buf[offset+j*2+1] = (int16_t)w; } fix_fft(fft_buf+offset, bin_e); if (!peak_hold) { for (j=0; j<bin_len; j++) { ts->avg[j] += real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]); } } else { for (j=0; j<bin_len; j++) { ts->avg[j] = MAX(real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]), ts->avg[j]); } } ts->samples += ds; } }
int main(void) { short real[N], image[N]; float datacpx[N]; int outLED[N]; int i,j,window; int timeL; print("FFT start\n"); Xil_Out32(OLED_BASE_ADDR,0xff); OLED_Init(); OLED_ShowString(0,0, "Hello FFT!"); OLED_Refresh_Gram(); //srand(time(0)); while(1){ init_timer(timer_ctrl, timer_counter_l, timer_counter_h); start_timer(timer_ctrl); OLED_Clear(); for (i = 0; i < N; i++) outLED[i] = 0; for(window = 0; window<WINDOW; ++window) { //Generate input data for (i = 0; i < N; i++) { #ifdef FIX_POINT real[i] = ((rand()%128-64)/128.0f)*(1<<14); image[i] = 0; #else //datacpx[2*i]=(cos(2 * M_PI * 4 * i / N)); datacpx[2*i]=(rand()%128-64)/128.0f; datacpx[2*i+1] = 0; #endif } timeL = *timer_counter_l; //FFT #ifdef FIX_POINT fix_fft(real, image, POW_N); #else fft(datacpx,N,1); #endif printf("FFT: %d us\n",(*timer_counter_l - timeL)/333); timeL = *timer_counter_l; //Conj for (i = 0; i < N; i++) { #ifdef FIX_POINT //printf("real[%d]= %d image[%d]= %d\n",i,real[i],i,image[i]); int conj_pdt_out =sqrt((real[i]*real[i]) + (image[i]*image[i])); #else int conj_pdt_out =sqrt((datacpx[2*i]*datacpx[2*i]) + (datacpx[2*i+1]*datacpx[2*i+1])); #endif //conj_pdt_out=conj_pdt_out/2; outLED[i]+=conj_pdt_out; } printf("Conj: %d us\n",(*timer_counter_l - timeL)/333); } timeL = *timer_counter_l; //Averaging for(i=0;i<N;++i) { #ifdef FIX_POINT outLED[i]=outLED[i]>>10; #else outLED[i]=outLED[i]/8; #endif } printf("Averaging: %d us\n",(*timer_counter_l - timeL)/333); stop_timer(timer_ctrl); //Display for(i=0;i<N;++i) { //printf("real[%d]= %d image[%d]= %d\n",i,real[i],i,image[i]); for(j=0; j< outLED[i]; ++j) OLED_DrawPoint(i,63-j,1); } OLED_Refresh_Gram(); } return 0; }
void SR_FFT( short * real, short * imag, short samples_exp ) { fix_fft(real, imag, samples_exp, 0); }
int main(int argc, char* argv[]) { /**************************** config **********************************/ int N = 512; int scaleby = 16384; /**********************************************************************/ if ( argc != 3 ) { printf( "usage: %s input-file-name output-file-name\n", argv[0] ); return 1; } char* fin = argv[1]; char* fout = argv[2]; int i,j,axis; int nLines = getNumberOfLines(fin); int log2nLines = fix_log2(nLines); int padLines = (1<<(log2nLines+1)) - nLines; int dataLines = 1<<(log2nLines+1); // FFT size and input signal size int log2n = fix_log2(N); int loops = dataLines>>log2n; // read CSV and pad with 0's until the next power of 2^m readCSV(fin, 6, 0, nLines); for ( i=0; i<padLines; ++i ) { for ( axis=0; axis<6; ++axis ) { dataIn[nLines+i][axis] = 0; } } for ( axis=0; axis<6; ++axis ) { // remove the mean, keep only signal with amp > 1, and scale the data int sum = 0, mean = 0; for ( j=0; j<nLines; j++ ) { sum += dataIn[j][axis]; } mean = sum>>log2nLines; for ( j=0; j<nLines; j++ ) { dataIn[j][axis] -= mean; } int scalefactor = fix_log2(scaleby); for ( j=0; j<nLines; j++ ) { if (dataIn[j][axis] != 0) { dataIn[j][axis] <<= scalefactor; } } // loop over the data in N segments and FFT int re[N], im[N], amp[N]; for ( j=0; j<N; ++j ) { amp[j] = 0; } for ( j=0; j<loops; ++j ) { for( i=0; i<N; i++ ) { im[i] = 0; re[i] = dataIn[N*j+i][axis]; } // compute the FFT of the samples fix_fft(re,im,log2n,0); for (i=1; i<N; i++){ amp[i] += re[i]*re[i] + im[i]*im[i]; } } // average the frequency-bin amplitudes over nonzero sampled dataset int nonzeros = 0; for ( j=0; j<N; ++j ) { if ( amp[j] != 0 ) ++nonzeros; } for ( j=1; j<N; j++ ) { amp[j] = sqrt(amp[j]); amp[j] >>= fix_log2(nonzeros); } // store in six-axis array for ( j=0; j<N; ++j ) { ampFull[j][axis] = amp[j]; } } writeCSV(fout, ampFull, 6, N/2); return 0; }