double *xtract_init_window(const int N, const int type) { double *window; window = malloc(N * sizeof(double)); switch (type) { case XTRACT_GAUSS: gauss(window, N, 0.4); break; case XTRACT_HAMMING: hamming(window, N); break; case XTRACT_HANN: hann(window, N); break; case XTRACT_BARTLETT: bartlett(window, N); break; case XTRACT_TRIANGULAR: triangular(window, N); break; case XTRACT_BARTLETT_HANN: bartlett_hann(window, N); break; case XTRACT_BLACKMAN: blackman(window, N); break; case XTRACT_KAISER: kaiser(window, N, 3 * PI); break; case XTRACT_BLACKMAN_HARRIS: blackman_harris(window, N); break; default: hann(window, N); break; } return window; }
static void spectrogram_analyze(llsm_parameters param, FP_TYPE* x, int nx, int fs, FP_TYPE* f0, int nf0, int nfft, FP_TYPE* fftbuff, const char* wtype, FP_TYPE** spectrogram, FP_TYPE** phasegram, FP_TYPE** phasegram_d, FP_TYPE* minvec) { FP_TYPE* xbuff = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE* ybuffr = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE* ybuffi = calloc(nfft, sizeof(FP_TYPE)); for(int t = 0; t < nf0; t ++) { // 4 times fundamental period is the minimal window length that resolves the harmonics // for generalized Hamming/Blackman windows FP_TYPE resf = f0[t]; int winlen = resf > 0 ? min(nfft, floor(fs / resf * 2.0) * 2) : param.a_nhop * 2; int tn = t * param.a_nhop; FP_TYPE* w = NULL; if(! strcmp(wtype, "blackman_harris")) w = blackman_harris(winlen); else if(! strcmp(wtype, "hamming")) w = hamming(winlen); else if(! strcmp(wtype, "hanning")) w = hanning(winlen); FP_TYPE norm_factor = 2.0 / sumfp(w, winlen); FP_TYPE* xfrm, * xfrm_d; FP_TYPE* spec_magn, * spec_phse_, * spec_phse, * spec_phse_d; xfrm = xfrm_d = spec_magn = spec_phse_ = spec_phse = spec_phse_d = NULL; xfrm = fetch_frame(x, nx, tn, winlen); FP_TYPE mean_xfrm = sumfp(xfrm, winlen) / winlen; if(minvec != NULL) minvec[t] = minfp(xfrm, winlen); for(int i = 0; i < winlen; i ++) xfrm[i] -= mean_xfrm; if(phasegram_d) { xfrm_d = fetch_frame(x, nx, tn - 1, winlen); FP_TYPE mean_xfrm_d = sumfp(xfrm_d, winlen) / winlen; for(int i = 0; i < winlen; i ++) xfrm_d[i] -= mean_xfrm_d; } for(int i = 0; i < winlen; i ++) { xfrm[i] *= w[i]; if(phasegram_d) xfrm_d[i] *= w[i]; } // current frame memset(xbuff, 0, nfft * sizeof(FP_TYPE)); for(int i = 0; i < winlen / 2; i ++) { xbuff[i] = xfrm[i + winlen / 2]; xbuff[nfft - winlen / 2 + i] = xfrm[i]; } fft(xbuff, NULL, ybuffr, ybuffi, nfft, fftbuff); spec_magn = abscplx(ybuffr, ybuffi, nfft / 2); if(phasegram) spec_phse_ = argcplx(ybuffr, ybuffi, nfft / 2); if(phasegram) spec_phse = unwrap(spec_phse_, nfft / 2); free(spec_phse_); // delayed frame if(phasegram_d) { memset(xbuff, 0, nfft * sizeof(FP_TYPE)); for(int i = 0; i < winlen / 2; i ++) { xbuff[i] = xfrm_d[i + winlen / 2]; xbuff[nfft - winlen / 2 + i] = xfrm_d[i]; } fft(xbuff, NULL, ybuffr, ybuffi, nfft, fftbuff); spec_phse_ = argcplx(ybuffr, ybuffi, nfft / 2); spec_phse_d = unwrap(spec_phse_, nfft / 2); free(spec_phse_); } for(int i = 0; i < nfft / 2; i ++) { spectrogram[t][i] = log(spec_magn[i] * norm_factor); if(isnan(spectrogram[t][i]) || isinf(spectrogram[t][i])) spectrogram[t][i] = -100.0; if(phasegram) phasegram[t][i] = spec_phse[i]; if(phasegram_d) phasegram_d[t][i] = spec_phse_d[i]; } free(spec_magn); if(spec_phse) free(spec_phse); if(spec_phse_d) free(spec_phse_d); free(xfrm); if(xfrm_d) free(xfrm_d); free(w); } free(xbuff); free(ybuffr); free(ybuffi); }
/* thread spawned for each connection */ void process_echo_request(void *p) { int sd = (int)p; int n, i, nsamples; float sample_rate, center_freq; win_peak peak; jam_info info; time_info time; cplx *buf = prot_mem_malloc(sizeof(cplx) * WIN_SIZE); float *bhwin = prot_mem_malloc(sizeof(float) * WIN_SIZE); unsigned int run_time; blackman_harris(bhwin, WIN_SIZE); union Fpass{ unsigned int i[UNION_SIZE]; float fl[UNION_SIZE]; char ch[RECV_BUF_SIZE]; } fpass; time.trigger = 0; time.time = 0; time.index = 0; time.freq_vs_time = NULL; run_time = 0; while (1) { /* read a max of RECV_BUF_SIZE bytes from socket */ if ((n = read(sd, fpass.ch, RECV_BUF_SIZE)) < 0) { xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd); #ifndef OS_IS_FREERTOS close(sd); return; #else break; #endif } /* break if the recved message = "quit" */ if (!strncmp(fpass.ch, "quit", 4)) break; /* break if client closed connection */ if (n <= 0) break; ++run_time; /* Rearrange from network order */ for (i = 0; i < UNION_SIZE; ++i) { fpass.i[i] = ntohl(fpass.i[i]); } /* Get info from header */ nsamples = fpass.i[0]; sample_rate = fpass.fl[1]; center_freq = fpass.fl[2]; if (nsamples != 64) continue; /* Limit nsamples to window size */ if (nsamples > WIN_SIZE) nsamples = WIN_SIZE; uninter(&fpass.fl[3], buf, nsamples); for (i = 0; i < WIN_SIZE; ++i) { buf[i] *= bhwin[i]; } /* fft and get peak */ fft(buf, nsamples); peak = get_peak(buf, nsamples, sample_rate, center_freq); info = process_signal(peak, sample_rate, &time); if (info.valid) { printf("Time: %.2f Bandwidth: %.2f, Chirp Rate: %.2f\r\n", run_time / (sample_rate / 64000), info.bandwidth, info.chirprate); info.valid = 0; } /* handle request */ /*if ((nwrote = write(sd, fpass.ch, n)) < 0) { xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n", __FUNCTION__, n, nwrote); xil_printf("Closing socket %d\r\n", sd); #ifndef OS_IS_FREERTOS close(sd); return; #else break; #endif } */ } /* close connection */ clear_led(7); prot_mem_free(bhwin); prot_mem_free(buf); close(sd); #ifdef OS_IS_FREERTOS vTaskDelete(NULL); #endif }