SPAN_DECLARE(complexf_t) dds_complexf(uint32_t *phase_acc, int32_t phase_rate) { complexf_t amp; amp = complex_setf(dds_lookupx(*phase_acc + (1 << 30)), dds_lookupx(*phase_acc)); *phase_acc += phase_rate; return amp; }
SPAN_DECLARE(complexf_t) dds_complex_modf(uint32_t *phase_acc, int32_t phase_rate, float scale, int32_t phase) { complexf_t amp; amp = complex_setf(dds_lookupx(*phase_acc + phase + (1 << 30))*scale, dds_lookupx(*phase_acc + phase)*scale); *phase_acc += phase_rate; return amp; }
static complexf_t cvec_dot_prodf_dumb(const complexf_t x[], const complexf_t y[], int n) { int i; complexf_t z; complexf_t z1; z = complex_setf(0.0f, 0.0f); for (i = 0; i < n; i++) { z1 = complex_mulf(&x[i], &y[i]); z = complex_addf(&z, &z1); } return z; }
static int periodogram_tests(void) { int i; int j; int k; int len; complexf_t coeffs[PG_WINDOW/2]; complexf_t camp[BLOCK_LEN]; complexf_t last_result; complexf_t result; complexf_t phase_offset; float freq_error; float pg_scale; float level; float scale1; float scale2; int32_t phase_rate1; int32_t phase_rate2; uint32_t phase_acc1; uint32_t phase_acc2; awgn_state_t noise_source_re; awgn_state_t noise_source_im; phase_rate1 = DEC_RATIO*dds_phase_ratef(FREQ1 - 5.0f); phase_rate2 = DEC_RATIO*dds_phase_ratef(FREQ2); phase_acc1 = 0; phase_acc2 = 0; len = periodogram_generate_coeffs(coeffs, FREQ1, DEC_SAMPLE_RATE, PG_WINDOW); if (len != PG_WINDOW/2) { printf("Test failed\n"); return -1; } pg_scale = periodogram_generate_phase_offset(&phase_offset, FREQ1, DEC_SAMPLE_RATE, PG_WINDOW); scale1 = dds_scaling_dbm0f(-6.0f); scale2 = dds_scaling_dbm0f(-6.0f); for (k = -50; k < 0; k++) { printf("Setting noise to %ddBm0\n", k); awgn_init_dbm0(&noise_source_re, 1234567, (float) k); awgn_init_dbm0(&noise_source_im, 7654321, (float) k); last_result = complex_setf(0.0f, 0.0f); for (i = 0; i < 100; i++) { for (j = 0; j < PG_WINDOW; j++) { result = dds_complexf(&phase_acc1, phase_rate1); camp[j].re = result.re*scale1; camp[j].im = result.im*scale1; result = dds_complexf(&phase_acc2, phase_rate2); camp[j].re += result.re*scale2; camp[j].im += result.im*scale2; camp[j].re += awgn(&noise_source_re); camp[j].im += awgn(&noise_source_im); } result = periodogram(coeffs, camp, PG_WINDOW); level = sqrtf(result.re*result.re + result.im*result.im); freq_error = periodogram_freq_error(&phase_offset, pg_scale, &last_result, &result); last_result = result; if (i == 0) continue; printf("Signal level = %.5f, freq error = %.5f\n", level, freq_error); if (level < scale1*0.8f || level > scale1*1.2f) { printf("Test failed - %ddBm0 of noise, signal is %f (%f)\n", k, level, scale1); return -1; } if (freq_error < -10.0f || freq_error > 10.0f) { printf("Test failed - %ddBm0 of noise, %fHz error\n", k, freq_error); return -1; } } } return 0; }
SPAN_DECLARE(complexf_t) dds_lookup_complexf(uint32_t phase) { return complex_setf(dds_lookupx(phase + (1 << 30)), dds_lookupx(phase)); }