bpsk: fix chunked operation

The cache was not behaving correctly at all.

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2020-06-10 19:16:12 +08:00
parent 6941745fe9
commit 2674bdefe5
1 changed files with 117 additions and 106 deletions

View File

@ -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)
{