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:
parent
6941745fe9
commit
2674bdefe5
223
src/bpsk/demod.c
223
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user