Added vector complex sine generator

master
Xavier Arteaga 6 years ago
parent 7bd3a9a43b
commit baac179d95

@ -160,6 +160,8 @@ SRSLTE_API void srslte_vec_interleave(const cf_t *x, const cf_t *y, cf_t *z, con
SRSLTE_API void srslte_vec_interleave_add(const cf_t *x, const cf_t *y, cf_t *z, const int len); SRSLTE_API void srslte_vec_interleave_add(const cf_t *x, const cf_t *y, cf_t *z, const int len);
SRSLTE_API void srslte_vec_gen_sine(cf_t amplitude, float freq, cf_t* z, int len);
SRSLTE_API void srslte_vec_apply_cfo(const cf_t *x, float cfo, cf_t *z, int len); SRSLTE_API void srslte_vec_apply_cfo(const cf_t *x, float cfo, cf_t *z, int len);
SRSLTE_API float srslte_vec_estimate_frequency(const cf_t* x, int len); SRSLTE_API float srslte_vec_estimate_frequency(const cf_t* x, int len);

@ -135,6 +135,8 @@ SRSLTE_API void srslte_vec_interleave_simd(const cf_t *x, const cf_t *y, cf_t *z
SRSLTE_API void srslte_vec_interleave_add_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len); SRSLTE_API void srslte_vec_interleave_add_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len);
SRSLTE_API void srslte_vec_gen_sine_simd(cf_t amplitude, float freq, cf_t* z, int len);
SRSLTE_API void srslte_vec_apply_cfo_simd(const cf_t *x, float cfo, cf_t *z, int len); SRSLTE_API void srslte_vec_apply_cfo_simd(const cf_t *x, float cfo, cf_t *z, int len);
SRSLTE_API float srslte_vec_estimate_frequency_simd(const cf_t* x, int len); SRSLTE_API float srslte_vec_estimate_frequency_simd(const cf_t* x, int len);

@ -800,6 +800,22 @@ TEST(srslte_vec_apply_cfo,
free(z); free(z);
) )
TEST(
srslte_vec_gen_sine, MALLOC(cf_t, z);
const float freq = 0.1f;
cf_t gold;
cf_t x = RANDOM_CF();
TEST_CALL(srslte_vec_gen_sine(x, freq, z, block_size))
for (int i = 0; i < block_size; i++) {
gold = x * cexpf(_Complex_I * 2.0f * (float)M_PI * i * freq);
mse += cabsf(gold - z[i]) / cabsf(gold);
} mse /= block_size;
free(z);)
TEST(srslte_vec_estimate_frequency, MALLOC(cf_t, x); float freq_gold = 0.1f; float freq = 0.1f; TEST(srslte_vec_estimate_frequency, MALLOC(cf_t, x); float freq_gold = 0.1f; float freq = 0.1f;
for (int i = 0; i < block_size; i++) { x[i] = cexpf(-I * 2.0f * M_PI * (float)i * freq_gold); } for (int i = 0; i < block_size; i++) { x[i] = cexpf(-I * 2.0f * M_PI * (float)i * freq_gold); }
@ -971,6 +987,10 @@ int main(int argc, char **argv) {
passed[func_count][size_count] = test_srslte_vec_apply_cfo(func_names[func_count], &timmings[func_count][size_count], block_size); passed[func_count][size_count] = test_srslte_vec_apply_cfo(func_names[func_count], &timmings[func_count][size_count], block_size);
func_count++; func_count++;
passed[func_count][size_count] =
test_srslte_vec_gen_sine(func_names[func_count], &timmings[func_count][size_count], block_size);
func_count++;
passed[func_count][size_count] = passed[func_count][size_count] =
test_srslte_vec_estimate_frequency(func_names[func_count], &timmings[func_count][size_count], block_size); test_srslte_vec_estimate_frequency(func_names[func_count], &timmings[func_count][size_count], block_size);
func_count++; func_count++;

@ -464,6 +464,11 @@ void srslte_vec_interleave_add(const cf_t *x, const cf_t *y, cf_t *z, const int
srslte_vec_interleave_add_simd(x, y, z, len); srslte_vec_interleave_add_simd(x, y, z, len);
} }
void srslte_vec_gen_sine(cf_t amplitude, float freq, cf_t* z, int len)
{
srslte_vec_gen_sine_simd(amplitude, freq, z, len);
}
void srslte_vec_apply_cfo(const cf_t *x, float cfo, cf_t *z, int len) { void srslte_vec_apply_cfo(const cf_t *x, float cfo, cf_t *z, int len) {
srslte_vec_apply_cfo_simd(x, cfo, z, len); srslte_vec_apply_cfo_simd(x, cfo, z, len);
} }

@ -1507,6 +1507,52 @@ void srslte_vec_interleave_add_simd(const cf_t *x, const cf_t *y, cf_t *z, const
} }
} }
void srslte_vec_gen_sine_simd(cf_t amplitude, float freq, cf_t* z, int len)
{
const float TWOPI = 2.0f * (float)M_PI;
cf_t osc = cexpf(_Complex_I * TWOPI * freq);
cf_t phase = 1.0f;
int i = 0;
#if SRSLTE_SIMD_CF_SIZE
__attribute__((aligned(64))) cf_t _phase[SRSLTE_SIMD_CF_SIZE];
_phase[0] = phase;
if (i < len - SRSLTE_SIMD_CF_SIZE + 1) {
for (int k = 1; k < SRSLTE_SIMD_CF_SIZE; k++) {
_phase[k] = _phase[k - 1] * osc;
}
}
simd_cf_t _simd_osc = srslte_simd_cf_set1(cexpf(_Complex_I * TWOPI * freq * SRSLTE_SIMD_CF_SIZE));
simd_cf_t _simd_phase = srslte_simd_cfi_load(_phase);
simd_cf_t a = srslte_simd_cf_set1(amplitude);
if (SRSLTE_IS_ALIGNED(z)) {
for (; i < len - SRSLTE_SIMD_CF_SIZE + 1; i += SRSLTE_SIMD_CF_SIZE) {
simd_cf_t r = srslte_simd_cf_prod(a, _simd_phase);
srslte_simd_cfi_store(&z[i], r);
_simd_phase = srslte_simd_cf_prod(_simd_phase, _simd_osc);
}
} else {
for (; i < len - SRSLTE_SIMD_CF_SIZE + 1; i += SRSLTE_SIMD_CF_SIZE) {
simd_cf_t r = srslte_simd_cf_prod(a, _simd_phase);
srslte_simd_cfi_storeu(&z[i], r);
_simd_phase = srslte_simd_cf_prod(_simd_phase, _simd_osc);
}
}
// Store pahse and get last phase
srslte_simd_cfi_store(_phase, _simd_phase);
phase = _phase[0];
#endif /* SRSLTE_SIMD_CF_SIZE */
for (; i < len; i++) {
z[i] = amplitude * phase;
phase *= osc;
}
}
void srslte_vec_apply_cfo_simd(const cf_t *x, float cfo, cf_t *z, int len) { void srslte_vec_apply_cfo_simd(const cf_t *x, float cfo, cf_t *z, int len) {
const float TWOPI = 2.0f * (float) M_PI; const float TWOPI = 2.0f * (float) M_PI;
int i = 0; int i = 0;

Loading…
Cancel
Save