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
|
/// If there aren't enough samples to convert data from q15
|
||||||
/// to f32, store them in here and return.
|
/// to f32, store them in here and return.
|
||||||
demod_sample_t cached[SAMPLES_PER_PERIOD];
|
demod_sample_t cache[SAMPLES_PER_PERIOD];
|
||||||
uint32_t cached_capacity;
|
uint32_t cache_capacity;
|
||||||
|
|
||||||
arm_fir_instance_f32 fir;
|
arm_fir_instance_f32 fir;
|
||||||
float32_t fir_state[SAMPLES_PER_PERIOD + FIR_STAGES - 1];
|
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
|
// Force a buffer refill for the first iteration
|
||||||
bpsk_state.current_offset = SAMPLES_PER_PERIOD;
|
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,
|
arm_fir_init_f32(&bpsk_state.i_lpf, LPF_STAGES, lpf_coefficients,
|
||||||
bpsk_state.i_lpf_state, SAMPLES_PER_PERIOD);
|
bpsk_state.i_lpf_state, SAMPLES_PER_PERIOD);
|
||||||
@ -145,88 +145,88 @@ struct sample_wave sample_wave;
|
|||||||
uint32_t saved_samples_ptr;
|
uint32_t saved_samples_ptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static FILE *output = NULL;
|
// static FILE *output = NULL;
|
||||||
static void write_wav_stereo(int16_t *left, int16_t *right, unsigned int len,
|
// static void write_wav_stereo(int16_t *left, int16_t *right, unsigned int len,
|
||||||
const char *name)
|
// const char *name)
|
||||||
{
|
// {
|
||||||
if (!output)
|
// if (!output)
|
||||||
{
|
// {
|
||||||
static uint8_t wav_header[44] = {
|
// static uint8_t wav_header[44] = {
|
||||||
0x52,
|
// 0x52,
|
||||||
0x49,
|
// 0x49,
|
||||||
0x46,
|
// 0x46,
|
||||||
0x46,
|
// 0x46,
|
||||||
0x1c,
|
// 0x1c,
|
||||||
0x12,
|
// 0x12,
|
||||||
0x05,
|
// 0x05,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x57,
|
// 0x57,
|
||||||
0x41,
|
// 0x41,
|
||||||
0x56,
|
// 0x56,
|
||||||
0x45,
|
// 0x45,
|
||||||
0x66,
|
// 0x66,
|
||||||
0x6d,
|
// 0x6d,
|
||||||
0x74,
|
// 0x74,
|
||||||
0x20,
|
// 0x20,
|
||||||
0x10,
|
// 0x10,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x01,
|
// 0x01,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x02, // stereo
|
// 0x02, // stereo
|
||||||
0x00,
|
// 0x00,
|
||||||
0x11,
|
// 0x11,
|
||||||
0x2b,
|
// 0x2b,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x22,
|
// 0x22,
|
||||||
0x56,
|
// 0x56,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x02,
|
// 0x02,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x10,
|
// 0x10,
|
||||||
0x00,
|
// 0x00,
|
||||||
0x64,
|
// 0x64,
|
||||||
0x61,
|
// 0x61,
|
||||||
0x74,
|
// 0x74,
|
||||||
0x61,
|
// 0x61,
|
||||||
0xf8,
|
// 0xf8,
|
||||||
0x11,
|
// 0x11,
|
||||||
0x05,
|
// 0x05,
|
||||||
0x00,
|
// 0x00,
|
||||||
};
|
// };
|
||||||
|
|
||||||
output = fopen(name, "w+b");
|
// output = fopen(name, "w+b");
|
||||||
if (!output)
|
// if (!output)
|
||||||
{
|
// {
|
||||||
perror("unable to open filtered file");
|
// perror("unable to open filtered file");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if (fwrite(wav_header, sizeof(wav_header), 1, output) <= 0)
|
// if (fwrite(wav_header, sizeof(wav_header), 1, output) <= 0)
|
||||||
{
|
// {
|
||||||
perror("error");
|
// perror("error");
|
||||||
fclose(output);
|
// fclose(output);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for (unsigned int i = 0; i < len; i++)
|
// for (unsigned int i = 0; i < len; i++)
|
||||||
{
|
// {
|
||||||
if (fwrite(&(left[i]), 2, 1, output) != 1)
|
// if (fwrite(&(left[i]), 2, 1, output) != 1)
|
||||||
{
|
// {
|
||||||
perror("error");
|
// perror("error");
|
||||||
fclose(output);
|
// fclose(output);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if (fwrite(&(right[i]), 2, 1, output) != 1)
|
// if (fwrite(&(right[i]), 2, 1, output) != 1)
|
||||||
{
|
// {
|
||||||
perror("error");
|
// perror("error");
|
||||||
fclose(output);
|
// fclose(output);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
static void bpsk_core(void)
|
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.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);
|
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 i_loop[SAMPLES_PER_PERIOD];
|
||||||
int16_t q_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(bpsk_state.i_lpf_samples, i_loop, SAMPLES_PER_PERIOD);
|
||||||
arm_float_to_q15(q_lpf_samples, q_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");
|
// write_wav_stereo(i_loop, q_loop, SAMPLES_PER_PERIOD, "quadrature_loop.wav");
|
||||||
|
|
||||||
float32_t errorwindow[SAMPLES_PER_PERIOD];
|
float32_t errorwindow[SAMPLES_PER_PERIOD];
|
||||||
arm_mult_f32(bpsk_state.i_lpf_samples, q_lpf_samples, errorwindow,
|
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;
|
bpsk_state.current_offset += 1;
|
||||||
if (bpsk_state.current_offset >= SAMPLES_PER_PERIOD)
|
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
|
// If there's data in the cache buffer, use that as the source
|
||||||
// for data.
|
// 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.
|
// 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));
|
samples, nb * sizeof(uint16_t));
|
||||||
bpsk_state.cached_capacity += nb;
|
bpsk_state.cache_capacity += nb;
|
||||||
*processed_samples += nb;
|
*processed_samples += nb;
|
||||||
fclose(output);
|
// fclose(output);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t samples_to_take = (SAMPLES_PER_PERIOD - bpsk_state.cached_capacity);
|
// There is enough data if we combine the cache with fresh data,
|
||||||
memcpy(bpsk_state.cached + bpsk_state.cached_capacity, samples,
|
// 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));
|
samples_to_take * sizeof(uint16_t));
|
||||||
|
|
||||||
// There is enough data, so convert it to f32
|
// There is enough data, so convert it to f32 and clear the cache
|
||||||
arm_q15_to_float(bpsk_state.cached, bpsk_state.current,
|
arm_q15_to_float(bpsk_state.cache, bpsk_state.current,
|
||||||
SAMPLES_PER_PERIOD);
|
SAMPLES_PER_PERIOD);
|
||||||
bpsk_state.cached_capacity = 0;
|
bpsk_state.cache_capacity = 0;
|
||||||
|
|
||||||
nb -= samples_to_take;
|
nb -= samples_to_take;
|
||||||
samples += 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
|
// Otherwise, the cache is empty, so operate directly on sample data
|
||||||
else
|
else
|
||||||
@ -343,10 +352,10 @@ int bpsk_demod(int *bit, demod_sample_t *samples, uint32_t nb, uint32_t *process
|
|||||||
// cache.
|
// cache.
|
||||||
if (nb < SAMPLES_PER_PERIOD)
|
if (nb < SAMPLES_PER_PERIOD)
|
||||||
{
|
{
|
||||||
memcpy(bpsk_state.cached, samples, nb * sizeof(uint16_t));
|
// printf("Only %d samples left, stashing in cache\n", nb);
|
||||||
bpsk_state.cached_capacity = nb;
|
memcpy(bpsk_state.cache, samples, nb * sizeof(uint16_t));
|
||||||
|
bpsk_state.cache_capacity = nb;
|
||||||
(*processed_samples) += nb;
|
(*processed_samples) += nb;
|
||||||
fclose(output);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,8 +367,10 @@ int bpsk_demod(int *bit, demod_sample_t *samples, uint32_t nb, uint32_t *process
|
|||||||
}
|
}
|
||||||
|
|
||||||
bpsk_core();
|
bpsk_core();
|
||||||
|
bpsk_state.current_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If the PLL crosses the 50% threshold, indicate a new bit.
|
// 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)
|
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