From 2674bdefe58c04c7ede38374e8b6c12636b36c56 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Wed, 10 Jun 2020 19:16:12 +0800 Subject: [PATCH] bpsk: fix chunked operation The cache was not behaving correctly at all. Signed-off-by: Sean Cross --- src/bpsk/demod.c | 223 +++++++++++++++++++++++++---------------------- 1 file changed, 117 insertions(+), 106 deletions(-) diff --git a/src/bpsk/demod.c b/src/bpsk/demod.c index 1c4b060..71e0fb5 100644 --- a/src/bpsk/demod.c +++ b/src/bpsk/demod.c @@ -37,8 +37,8 @@ struct bpsk_state /// If there aren't enough samples to convert data from q15 /// to f32, store them in here and return. - demod_sample_t cached[SAMPLES_PER_PERIOD]; - uint32_t cached_capacity; + demod_sample_t cache[SAMPLES_PER_PERIOD]; + uint32_t cache_capacity; arm_fir_instance_f32 fir; float32_t fir_state[SAMPLES_PER_PERIOD + FIR_STAGES - 1]; @@ -116,7 +116,7 @@ void bpsk_demod_init(void) // Force a buffer refill for the first iteration bpsk_state.current_offset = SAMPLES_PER_PERIOD; - bpsk_state.cached_capacity = 0; + bpsk_state.cache_capacity = 0; arm_fir_init_f32(&bpsk_state.i_lpf, LPF_STAGES, lpf_coefficients, bpsk_state.i_lpf_state, SAMPLES_PER_PERIOD); @@ -145,88 +145,88 @@ struct sample_wave sample_wave; uint32_t saved_samples_ptr; #endif -static FILE *output = NULL; -static void write_wav_stereo(int16_t *left, int16_t *right, unsigned int len, - const char *name) -{ - if (!output) - { - static uint8_t wav_header[44] = { - 0x52, - 0x49, - 0x46, - 0x46, - 0x1c, - 0x12, - 0x05, - 0x00, - 0x57, - 0x41, - 0x56, - 0x45, - 0x66, - 0x6d, - 0x74, - 0x20, - 0x10, - 0x00, - 0x00, - 0x00, - 0x01, - 0x00, - 0x02, // stereo - 0x00, - 0x11, - 0x2b, - 0x00, - 0x00, - 0x22, - 0x56, - 0x00, - 0x00, - 0x02, - 0x00, - 0x10, - 0x00, - 0x64, - 0x61, - 0x74, - 0x61, - 0xf8, - 0x11, - 0x05, - 0x00, - }; +// static FILE *output = NULL; +// static void write_wav_stereo(int16_t *left, int16_t *right, unsigned int len, +// const char *name) +// { +// if (!output) +// { +// static uint8_t wav_header[44] = { +// 0x52, +// 0x49, +// 0x46, +// 0x46, +// 0x1c, +// 0x12, +// 0x05, +// 0x00, +// 0x57, +// 0x41, +// 0x56, +// 0x45, +// 0x66, +// 0x6d, +// 0x74, +// 0x20, +// 0x10, +// 0x00, +// 0x00, +// 0x00, +// 0x01, +// 0x00, +// 0x02, // stereo +// 0x00, +// 0x11, +// 0x2b, +// 0x00, +// 0x00, +// 0x22, +// 0x56, +// 0x00, +// 0x00, +// 0x02, +// 0x00, +// 0x10, +// 0x00, +// 0x64, +// 0x61, +// 0x74, +// 0x61, +// 0xf8, +// 0x11, +// 0x05, +// 0x00, +// }; - output = fopen(name, "w+b"); - if (!output) - { - perror("unable to open filtered file"); - return; - } - if (fwrite(wav_header, sizeof(wav_header), 1, output) <= 0) - { - perror("error"); - fclose(output); - return; - } - } - for (unsigned int i = 0; i < len; i++) - { - if (fwrite(&(left[i]), 2, 1, output) != 1) - { - perror("error"); - fclose(output); - return; - } - if (fwrite(&(right[i]), 2, 1, output) != 1) - { - perror("error"); - fclose(output); - return; - } - } -} +// output = fopen(name, "w+b"); +// if (!output) +// { +// perror("unable to open filtered file"); +// return; +// } +// if (fwrite(wav_header, sizeof(wav_header), 1, output) <= 0) +// { +// perror("error"); +// fclose(output); +// return; +// } +// } +// for (unsigned int i = 0; i < len; i++) +// { +// if (fwrite(&(left[i]), 2, 1, output) != 1) +// { +// perror("error"); +// fclose(output); +// return; +// } +// if (fwrite(&(right[i]), 2, 1, output) != 1) +// { +// perror("error"); +// fclose(output); +// return; +// } +// } +// } static void bpsk_core(void) { @@ -277,11 +277,11 @@ static void bpsk_core(void) arm_fir_f32(&bpsk_state.i_lpf, i_mult_samps, bpsk_state.i_lpf_samples, SAMPLES_PER_PERIOD); arm_fir_f32(&bpsk_state.q_lpf, q_mult_samps, q_lpf_samples, SAMPLES_PER_PERIOD); - int16_t i_loop[SAMPLES_PER_PERIOD]; - int16_t q_loop[SAMPLES_PER_PERIOD]; - arm_float_to_q15(bpsk_state.i_lpf_samples, i_loop, SAMPLES_PER_PERIOD); - arm_float_to_q15(q_lpf_samples, q_loop, SAMPLES_PER_PERIOD); - write_wav_stereo(i_loop, q_loop, SAMPLES_PER_PERIOD, "quadrature_loop.wav"); + // int16_t i_loop[SAMPLES_PER_PERIOD]; + // int16_t q_loop[SAMPLES_PER_PERIOD]; + // arm_float_to_q15(bpsk_state.i_lpf_samples, i_loop, SAMPLES_PER_PERIOD); + // arm_float_to_q15(q_lpf_samples, q_loop, SAMPLES_PER_PERIOD); + // write_wav_stereo(i_loop, q_loop, SAMPLES_PER_PERIOD, "quadrature_loop.wav"); float32_t errorwindow[SAMPLES_PER_PERIOD]; arm_mult_f32(bpsk_state.i_lpf_samples, q_lpf_samples, errorwindow, @@ -305,36 +305,45 @@ int bpsk_demod(int *bit, demod_sample_t *samples, uint32_t nb, uint32_t *process bpsk_state.current_offset += 1; if (bpsk_state.current_offset >= SAMPLES_PER_PERIOD) { - bpsk_state.current_offset = 0; - + // If there aren't any bytes remaining to process, return. + if (nb == 0) { + return 0; + } // If there's data in the cache buffer, use that as the source // for data. - if (bpsk_state.cached_capacity > 0) + else if (bpsk_state.cache_capacity > 0) { - // If there won't be enough data to process, so copy the + // If there won't be enough data to process, copy the // remainder to the cache and return. - if (bpsk_state.cached_capacity + nb < SAMPLES_PER_PERIOD) + if (bpsk_state.cache_capacity + nb < SAMPLES_PER_PERIOD) { - memcpy(bpsk_state.cached + bpsk_state.cached_capacity, + printf("Buffer not big enough, stashing in cache\n"); + memcpy(&bpsk_state.cache[bpsk_state.cache_capacity], samples, nb * sizeof(uint16_t)); - bpsk_state.cached_capacity += nb; + bpsk_state.cache_capacity += nb; *processed_samples += nb; - fclose(output); + // fclose(output); return 0; } - uint32_t samples_to_take = (SAMPLES_PER_PERIOD - bpsk_state.cached_capacity); - memcpy(bpsk_state.cached + bpsk_state.cached_capacity, samples, + // There is enough data if we combine the cache with fresh data, + // so determine how many samples to take. + uint32_t samples_to_take = (SAMPLES_PER_PERIOD - bpsk_state.cache_capacity); + + // printf("Pulling %d samples from cache and adding %d samples from pool of %d\n", + // bpsk_state.cache_capacity, + // samples_to_take, nb); + memcpy(&bpsk_state.cache[bpsk_state.cache_capacity], samples, samples_to_take * sizeof(uint16_t)); - // There is enough data, so convert it to f32 - arm_q15_to_float(bpsk_state.cached, bpsk_state.current, + // There is enough data, so convert it to f32 and clear the cache + arm_q15_to_float(bpsk_state.cache, bpsk_state.current, SAMPLES_PER_PERIOD); - bpsk_state.cached_capacity = 0; + bpsk_state.cache_capacity = 0; nb -= samples_to_take; samples += samples_to_take; - (*processed_samples) += SAMPLES_PER_PERIOD; + (*processed_samples) += samples_to_take; } // Otherwise, the cache is empty, so operate directly on sample data else @@ -343,10 +352,10 @@ int bpsk_demod(int *bit, demod_sample_t *samples, uint32_t nb, uint32_t *process // cache. if (nb < SAMPLES_PER_PERIOD) { - memcpy(bpsk_state.cached, samples, nb * sizeof(uint16_t)); - bpsk_state.cached_capacity = nb; + // printf("Only %d samples left, stashing in cache\n", nb); + memcpy(bpsk_state.cache, samples, nb * sizeof(uint16_t)); + bpsk_state.cache_capacity = nb; (*processed_samples) += nb; - fclose(output); return 0; } @@ -358,8 +367,10 @@ int bpsk_demod(int *bit, demod_sample_t *samples, uint32_t nb, uint32_t *process } bpsk_core(); + bpsk_state.current_offset = 0; } + // If the PLL crosses the 50% threshold, indicate a new bit. if (bpsk_state.bit_pll < 0.5 && (bpsk_state.bit_pll + bpsk_state.pll_incr) >= 0.5) {