-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathburst_catcher.c
78 lines (65 loc) · 2.37 KB
/
burst_catcher.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
* Copyright 2022 ICE9 Consulting LLC
*/
#include <complex.h>
#include <string.h>
#include <stdlib.h>
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#include <liquid/liquid.h>
#include "burst_catcher.h"
const float sql = -45.0f; // agc squelch
const float bt = 0.25f; // agc bandwidth
// starting size of burst buffer in floats
#define BURST_START_SIZE 2048
#define MAX_BURST_SIZE 32768
void burst_catcher_create(burst_catcher_t *c, unsigned freq) {
memset(c, 0, sizeof(*c));
c->freq = freq;
// agc
c->agc = agc_crcf_create();
agc_crcf_set_bandwidth(c->agc, bt);
agc_crcf_set_signal_level(c->agc,1e-3f); // initial guess at starting signal level
agc_crcf_squelch_enable(c->agc); // enable squelch
agc_crcf_squelch_set_threshold(c->agc, sql); // threshold for detection [dB]
agc_crcf_squelch_set_timeout (c->agc, 100); // timeout for hysteresis
}
void burst_catcher_destroy(burst_catcher_t *c) {
free(c->agc);
free(c->burst);
}
int burst_catcher_execute(burst_catcher_t *c, float complex *sample, burst_t *burst_out) {
agc_crcf_execute(c->agc, *sample, sample);
if (agc_crcf_squelch_get_status(c->agc) == LIQUID_AGC_SQUELCH_SIGNALHI) {
if (c->burst_len == c->burst_buf_size && c->burst_len < MAX_BURST_SIZE) {
c->burst_buf_size *= 2;
c->burst = realloc(c->burst, sizeof(float complex) * c->burst_buf_size);
}
if (c->burst_len < MAX_BURST_SIZE)
c->burst[c->burst_len++] = *sample;
} else if (agc_crcf_squelch_get_status(c->agc) == LIQUID_AGC_SQUELCH_RISE) {
c->burst = malloc(sizeof(float complex) * BURST_START_SIZE);
c->burst_buf_size = BURST_START_SIZE;
c->burst_len = 0;
clock_gettime(CLOCK_REALTIME, &c->timestamp);
} else if (agc_crcf_squelch_get_status(c->agc) == LIQUID_AGC_SQUELCH_TIMEOUT) {
burst_out->burst = c->burst;
burst_out->len = c->burst_len;
burst_out->num = c->burst_num;
burst_out->freq = c->freq;
burst_out->timestamp = c->timestamp;
c->burst = NULL;
c->burst_len = 0;
c->burst_buf_size = 0;
++c->burst_num;
return 1;
}
return 0;
}
void burst_destroy(burst_t *b) {
free(b->burst);
free(b->packet.demod);
free(b->packet.bits);
b->burst = NULL;
b->packet.demod = NULL;
b->packet.bits = NULL;
}