// autotest helper function // _b : filter coefficients (numerator) // _a : filter coefficients (denominator) // _h_len : filter coefficients length // _x : input array // _x_len : input array length // _y : output array // _y_len : output array length void iirfilt_crcf_test(float * _b, float * _a, unsigned int _h_len, float complex * _x, unsigned int _x_len, float complex * _y, unsigned int _y_len) { float tol = 0.001f; // load filter coefficients externally iirfilt_crcf q = iirfilt_crcf_create(_b, _h_len, _a, _h_len); // allocate memory for output float complex y_test[_y_len]; unsigned int i; // compute output for (i=0; i<_x_len; i++) { iirfilt_crcf_execute(q, _x[i], &y_test[i]); CONTEND_DELTA( crealf(y_test[i]), crealf(_y[i]), tol ); CONTEND_DELTA( cimagf(y_test[i]), cimagf(_y[i]), tol ); } // destroy filter object iirfilt_crcf_destroy(q); }
int main() { // options unsigned int order=4; // filter order unsigned int n = order+1; float b[n], a[n]; // ... initialize filter coefficients ... // create filter object iirfilt_crcf q = iirfilt_crcf_create(b,n,a,n); float complex x; // input sample float complex y; // output sample // execute filter (repeat as necessary) iirfilt_crcf_execute(q,x,&y); // destroy filter object iirfilt_crcf_destroy(q); }
// destroy frame synchronizer object, freeing all internal memory void gmskframesync_destroy(gmskframesync _q) { #if DEBUG_GMSKFRAMESYNC // destroy debugging objects if (_q->debug_objects_created) { windowcf_destroy(_q->debug_x); windowf_destroy(_q->debug_fi); windowf_destroy(_q->debug_mf); windowf_destroy( _q->debug_framesyms); } #endif // destroy synchronizer objects #if GMSKFRAMESYNC_PREFILTER iirfilt_crcf_destroy(_q->prefilter);// pre-demodulator filter #endif firpfb_rrrf_destroy(_q->mf); // matched filter firpfb_rrrf_destroy(_q->dmf); // derivative matched filter nco_crcf_destroy(_q->nco_coarse); // coarse NCO // preamble detector_cccf_destroy(_q->frame_detector); windowcf_destroy(_q->buffer); free(_q->preamble_pn); free(_q->preamble_rx); // header packetizer_destroy(_q->p_header); free(_q->header_mod); free(_q->header_enc); free(_q->header_dec); // payload packetizer_destroy(_q->p_payload); free(_q->payload_enc); free(_q->payload_dec); // free main object memory free(_q); }
int main() { // options unsigned int order=4; // filter order float fc=0.1f; // cutoff frequency float f0=0.25f; // center frequency (bandpass|bandstop) float Ap=1.0f; // pass-band ripple [dB] float As=40.0f; // stop-band attenuation [dB] liquid_iirdes_filtertype ftype = LIQUID_IIRDES_ELLIP; liquid_iirdes_bandtype btype = LIQUID_IIRDES_BANDPASS; liquid_iirdes_format format = LIQUID_IIRDES_SOS; // CREATE filter object (and print to stdout) iirfilt_crcf myfilter; myfilter = iirfilt_crcf_create_prototype(ftype, btype, format, order, fc, f0, Ap, As); iirfilt_crcf_print(myfilter); // allocate memory for data arrays unsigned int n=128; // number of samples float complex x[n]; // input samples array float complex y[n]; // output samples array // run filter unsigned int i; for (i=0; i<n; i++) { // initialize input x[i] = randnf() + _Complex_I*randnf(); // EXECUTE filter (repeat as many times as desired) iirfilt_crcf_execute(myfilter, x[i], &y[i]); } // DESTROY filter object iirfilt_crcf_destroy(myfilter); }
void do_track(){ if (local_track_freq != shm_settings.track_frequency_target) { if (ff.sosMap.count(shm_settings.track_frequency_target)) { //frequency key exists if (track_filterA != NULL) iirfilt_crcf_destroy(track_filterA); if (track_filterB != NULL) iirfilt_crcf_destroy(track_filterB); if (track_filterC != NULL) iirfilt_crcf_destroy(track_filterC); float *b = &((ff.sosMap[shm_settings.track_frequency_target]->b)[0]); float *a = &((ff.sosMap[shm_settings.track_frequency_target]->a)[0]); track_filterA = iirfilt_crcf_create_sos(b,a,NUMBER_OF_SECTIONS); track_filterB = iirfilt_crcf_create_sos(b,a,NUMBER_OF_SECTIONS); track_filterC = iirfilt_crcf_create_sos(b,a,NUMBER_OF_SECTIONS); shm_results_track.track_state = 0; local_track_freq = shm_settings.track_frequency_target; float normalized_frequency = (float) shm_settings.track_frequency_target / (float) SAMPLING_FREQUENCY; nco_crcf_set_frequency(nco,2*M_PI*normalized_frequency); } else { //frequency key does not exist. Trigger error state shm_results_track.track_state = -1; std::cerr << shm_settings.track_frequency_target << " WARN TRACK FREQ NOT IN SOS TABLE" << std::endl; } shm_setg(hydrophones_results_track, shm_results_track); } std::complex<float> *chA_ptr, *chA_filtered_ptr; std::complex<float> *chB_ptr, *chB_filtered_ptr; std::complex<float> *chC_ptr, *chC_filtered_ptr; float *mag_ptr; windowcf_read(wchA,&chA_ptr); windowcf_read(wchB,&chB_ptr); windowcf_read(wchC,&chC_ptr); std::complex<float> filtOutA, filtOutB, filtOutC; for (int i = 0; i < SAMPLING_DEPTH; i++) { iirfilt_crcf_execute(track_filterA,chA_ptr[i],&filtOutA); iirfilt_crcf_execute(track_filterB,chB_ptr[i],&filtOutB); iirfilt_crcf_execute(track_filterC,chC_ptr[i],&filtOutC); windowcf_read(wchA_filtered,&chA_filtered_ptr); windowcf_read(wchB_filtered,&chB_filtered_ptr); windowcf_read(wchC_filtered,&chC_filtered_ptr); windowcf_push(wchA_filtered,filtOutA); windowcf_push(wchB_filtered,filtOutB); windowcf_push(wchC_filtered,filtOutC); float b_sqrd = std::pow(std::real(filtOutB),2); pwr_sum += b_sqrd; windowf_read(wmag_buffer,&mag_ptr); pwr_sum -= mag_ptr[0]; windowf_push(wmag_buffer,b_sqrd); double normalized_pwr = pwr_sum / (double)TRACK_LENGTH; if (normalized_pwr > shm_settings.track_magnitude_threshold && (track_sample_idx - shm_results_track.tracked_ping_time) >= shm_settings.track_cooldown_samples) { std::complex<float> dtft_coeff_A = goertzelNonInteger(chA_filtered_ptr,TRACK_LENGTH,shm_settings.track_frequency_target,SAMPLING_FREQUENCY); std::complex<float> dtft_coeff_B = goertzelNonInteger(chB_filtered_ptr,TRACK_LENGTH,shm_settings.track_frequency_target,SAMPLING_FREQUENCY); std::complex<float> dtft_coeff_C = goertzelNonInteger(chC_filtered_ptr,TRACK_LENGTH,shm_settings.track_frequency_target,SAMPLING_FREQUENCY); float phaseA = std::arg(dtft_coeff_A); float phaseB = std::arg(dtft_coeff_B); float phaseC = std::arg(dtft_coeff_C); shm_results_track.diff_phase_y = phase_difference(phaseC,phaseB); shm_results_track.diff_phase_x = phase_difference(phaseA,phaseB); float kx = SOUND_SPEED * shm_results_track.diff_phase_x / (NIPPLE_DISTANCE * 2 * M_PI * shm_settings.track_frequency_target); float ky = SOUND_SPEED * shm_results_track.diff_phase_y / (NIPPLE_DISTANCE * 2 * M_PI * shm_settings.track_frequency_target); float kz_2 = 1 - kx * kx - ky * ky; if (kz_2 < 0) { std::cerr << "WARNING: z mag is negative! " << kz_2 << std::endl; kz_2 = 0; } shm_results_track.tracked_ping_heading_radians = std::atan2(ky, kx); shm_results_track.tracked_ping_elevation_radians = std::acos(std::sqrt(kz_2)); shm_results_track.tracked_ping_count++; shm_results_track.tracked_ping_frequency = shm_results_spectrum.most_recent_ping_frequency; shm_results_track.tracked_ping_time = track_sample_idx; std::cout << "PING DETECTED @ n=" << track_sample_idx << " w/ pwr="<< normalized_pwr<< std::endl; std::cout << "@ HEADING=" << shm_results_track.tracked_ping_heading_radians*(180.0f/M_PI) << std::endl; shm_setg(hydrophones_results_track, shm_results_track); } track_sample_idx++; } }
int main() { // spectral periodogram options unsigned int nfft = 1200; // spectral periodogram FFT size unsigned int num_samples = 64000; // number of samples float fc = 0.20f; // carrier (relative to sampling rate) // create objects iirfilt_crcf filter_tx = iirfilt_crcf_create_lowpass(15, 0.05); nco_crcf mixer_tx = nco_crcf_create(LIQUID_VCO); nco_crcf mixer_rx = nco_crcf_create(LIQUID_VCO); iirfilt_crcf filter_rx = iirfilt_crcf_create_lowpass(7, 0.2); // set carrier frequencies nco_crcf_set_frequency(mixer_tx, fc * 2*M_PI); nco_crcf_set_frequency(mixer_rx, fc * 2*M_PI); // create objects for measuring power spectral density spgramcf spgram_tx = spgramcf_create_default(nfft); spgramf spgram_dac = spgramf_create_default(nfft); spgramcf spgram_rx = spgramcf_create_default(nfft); // run through loop one step at a time unsigned int i; for (i=0; i<num_samples; i++) { // STEP 1: generate input signal (filtered noise with offset tone) float complex v1 = (randnf() + randnf()*_Complex_I) + 3.0f*cexpf(-_Complex_I*0.2f*i); iirfilt_crcf_execute(filter_tx, v1, &v1); // save spectrum spgramcf_push(spgram_tx, v1); // STEP 2: mix signal up and save real part (DAC output) nco_crcf_mix_up(mixer_tx, v1, &v1); float v2 = crealf(v1); nco_crcf_step(mixer_tx); // save spectrum spgramf_push(spgram_dac, v2); // STEP 3: mix signal down and filter off image float complex v3; nco_crcf_mix_down(mixer_rx, v2, &v3); iirfilt_crcf_execute(filter_rx, v3, &v3); nco_crcf_step(mixer_rx); // save spectrum spgramcf_push(spgram_rx, v3); } // compute power spectral density output float psd_tx [nfft]; float psd_dac [nfft]; float psd_rx [nfft]; spgramcf_get_psd(spgram_tx, psd_tx); spgramf_get_psd( spgram_dac, psd_dac); spgramcf_get_psd(spgram_rx, psd_rx); // destroy objects spgramcf_destroy(spgram_tx); spgramf_destroy(spgram_dac); spgramcf_destroy(spgram_rx); iirfilt_crcf_destroy(filter_tx); nco_crcf_destroy(mixer_tx); nco_crcf_destroy(mixer_rx); iirfilt_crcf_destroy(filter_rx); // // export output file // FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); fprintf(fid,"nfft = %u;\n", nfft); fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"psd_tx = zeros(1,nfft);\n"); fprintf(fid,"psd_dac= zeros(1,nfft);\n"); fprintf(fid,"psd_rx = zeros(1,nfft);\n"); for (i=0; i<nfft; i++) { fprintf(fid,"psd_tx (%6u) = %12.4e;\n", i+1, psd_tx [i]); fprintf(fid,"psd_dac(%6u) = %12.4e;\n", i+1, psd_dac[i]); fprintf(fid,"psd_rx (%6u) = %12.4e;\n", i+1, psd_rx [i]); } fprintf(fid,"figure;\n"); fprintf(fid,"hold on;\n"); fprintf(fid," plot(f, psd_tx, '-', 'LineWidth',1.5,'Color',[0.7 0.7 0.7]);\n"); fprintf(fid," plot(f, psd_dac, '-', 'LineWidth',1.5,'Color',[0.0 0.5 0.3]);\n"); fprintf(fid," plot(f, psd_rx, '-', 'LineWidth',1.5,'Color',[0.0 0.3 0.5]);\n"); fprintf(fid,"hold off;\n"); fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid,"ylabel('Power Spectral Density [dB]');\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"axis([-0.5 0.5 -100 60]);\n"); fprintf(fid,"legend('transmit (complex)','DAC output (real)','receive (complex)','location','northeast');\n"); fclose(fid); printf("results written to %s.\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
int main() { unsigned int m = 12; // filter semi-length (actual length: 4*m+1) float As = 60.0f; // stop-band attenuation [dB] unsigned int num_samples = 400; // number of input samples unsigned int i; // allocate memory for data arrays float complex x [num_samples]; // input signal float complex y0[num_samples]; // float complex y1[num_samples]; // // generate the two signals iirfilt_crcf lowpass = iirfilt_crcf_create_lowpass(6,0.02); for (i=0; i<num_samples; i++) { // signal at negative frequency: tone float complex x_neg = cexpf(-_Complex_I*2*M_PI*0.059f*i); // signal at positive frequency: filtered noise float complex v; iirfilt_crcf_execute(lowpass, 4*randnf(), &v); float complex x_pos = v * cexpf(_Complex_I*2*M_PI*0.073f*i); // compsite x[i] = (x_neg + x_pos) * hamming(i,num_samples); } iirfilt_crcf_destroy(lowpass); // create/print the half-band resampler, with a specified // stopband attenuation level resamp2_cccf q = resamp2_cccf_create(m,-0.25f,As); resamp2_cccf_print(q); // run filter for (i=0; i<num_samples; i++) resamp2_cccf_filter_execute(q,x[i],&y0[i],&y1[i]); // // print results to file // FILE*fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s: auto-generated file\n",OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); fprintf(fid,"num_samples=%u;\n", num_samples); // output results for (i=0; i<num_samples; i++) { fprintf(fid,"x( %3u) = %12.4e + j*%12.4e;\n", i+1, crealf( x[i]), cimagf( x[i])); fprintf(fid,"y0(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y0[i]), cimagf(y0[i])); fprintf(fid,"y1(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y1[i]), cimagf(y1[i])); } // plot temporal results fprintf(fid,"\n\n"); fprintf(fid,"t = 0:(num_samples-1);\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(3,1,1);\n"); fprintf(fid," hold on;\n"); fprintf(fid," plot(t,real(x),'Color',[1 1 1]*0.7,'LineWidth',1);\n"); fprintf(fid," plot(t,imag(x),'Color',[1 1 1]*0.5,'LineWidth',2);\n"); fprintf(fid," hold off;\n"); fprintf(fid," grid on;\n"); fprintf(fid," legend('real','imag','location','northeast');\n"); fprintf(fid," axis([0 num_samples -2 2]);\n"); fprintf(fid," ylabel('original');\n"); fprintf(fid,"subplot(3,1,2);\n"); fprintf(fid," hold on;\n"); fprintf(fid," plot(t,real(y0),'Color',[1 1 1]*0.7,'LineWidth',1);\n"); fprintf(fid," plot(t,imag(y0),'Color',[0 0.5 0.2],'LineWidth',2);\n"); fprintf(fid," hold off;\n"); fprintf(fid," grid on;\n"); fprintf(fid," legend('real','imag','location','northeast');\n"); fprintf(fid," axis([0 num_samples -2 2]);\n"); fprintf(fid," ylabel('negative band');\n"); fprintf(fid,"subplot(3,1,3);\n"); fprintf(fid," hold on;\n"); fprintf(fid," plot(t,real(y1),'Color',[1 1 1]*0.7,'LineWidth',1);\n"); fprintf(fid," plot(t,imag(y1),'Color',[0 0.2 0.5],'LineWidth',2);\n"); fprintf(fid," hold off;\n"); fprintf(fid," grid on;\n"); fprintf(fid," legend('real','imag','location','northeast');\n"); fprintf(fid," axis([0 num_samples -2 2]);\n"); fprintf(fid," ylabel('positive band');\n"); fprintf(fid," xlabel('sample index');\n"); // plot spectrum results fprintf(fid,"\n\n"); fprintf(fid,"nfft=2400;\n"); fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n"); fprintf(fid,"w = hamming(num_samples)' / num_samples;\n"); fprintf(fid,"X = 20*log10(abs(fftshift(fft( x.*w, nfft))));\n"); fprintf(fid,"Y0 = 20*log10(abs(fftshift(fft(y0.*w, nfft))));\n"); fprintf(fid,"Y1 = 20*log10(abs(fftshift(fft(y1.*w, nfft))));\n"); fprintf(fid,"figure('Color','white');\n"); fprintf(fid," hold on;\n"); fprintf(fid," plot(f,X, 'Color',[1 1 1]*0.7,'LineWidth',2);\n"); fprintf(fid," plot(f,Y0,'Color',[0 0.2 0.5]);\n"); fprintf(fid," plot(f,Y1,'Color',[0 0.5 0.2]);\n"); fprintf(fid," hold off;\n"); fprintf(fid,"legend('original','negative','positive','location','northeast');\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"axis([-0.5 0.5 -120 20]);\n"); fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid,"ylabel('Power Spectral Density [dB]');\n"); fclose(fid); printf("results written to %s\n",OUTPUT_FILENAME); printf("done.\n"); return 0; }