Change scanner to use dft_detect.

pull/120/head
Mark Jessop 2019-02-27 20:55:46 +10:30
rodzic 745321d931
commit 54e8f9c313
11 zmienionych plików z 1443 dodań i 1239 usunięć

Wyświetl plik

@ -191,54 +191,80 @@ def detect_sonde(frequency, rs_path="./", dwell_time=10, sdr_fm='rtl_fm', device
else:
gain_param = ''
# Sample Source (rtl_fm)
rx_test_command = "timeout %ds %s %s-p %d -d %s %s-M fm -F9 -s 22k -f %d 2>/dev/null |" % (dwell_time, sdr_fm, bias_option, int(ppm), str(device_idx), gain_param, frequency)
# Sample filtering
rx_test_command += "sox -t raw -r 22k -e s -b 16 -c 1 - -r 48000 -t wav - highpass 20 2>/dev/null |"
rx_test_command += os.path.join(rs_path,"rs_detect") + " -z -t 8 2>/dev/null >/dev/null"
# Sample decoding / detection
rx_test_command += os.path.join(rs_path,"dft_detect") + " 2>/dev/null"
#print(rx_test_command)
logging.debug("Scanner #%s - Attempting sonde detection on %.3f MHz" % (str(device_idx), frequency/1e6))
try:
FNULL = open(os.devnull, 'w')
ret_code = subprocess.call(rx_test_command, shell=True, stderr=FNULL)
ret_output = subprocess.check_output(rx_test_command, shell=True, stderr=FNULL)
FNULL.close()
except subprocess.CalledProcessError as e:
# dft_detect returns a code of 1 if no sonde is detected.
# logging.debug("Scanner - dfm_detect return code: %s" % e.returncode)
if e.returncode >= 2:
ret_output = e.output
else:
return None
except Exception as e:
# Something broke when running the detection function.
logging.error("Scanner #%s - Error when running rs_detect - %s" % (str(device_idx), str(e)))
logging.error("Scanner #%s - Error when running dft_detect - %s" % (str(device_idx), str(e)))
return None
# Shift down by a byte... for some reason.
# NOTE: For some reason, we don't need to do this when using subprocess.call vs when using os.system.
# Should probably figure out why this is the case at some point.
#ret_code = ret_code >> 8
# Check for no output from dft_detect.
if ret_output is None or ret_output == "":
#logging.error("Scanner - dft_detect returned no output?")
return None
# Default is non-inverted FM.
inv = ""
# dft_detect return codes:
# 2 = DFM
# 3 = RS41
# 4 = RS92
# 5 = M10
# 6 = IMET (AB)
# 7 = IMET (RS)
# 8 = LMS6
# 9 = C34/C50
# Check if the inverted bit is set
if (ret_code & 0x80) > 0:
# If the inverted bit is set, we have to do some munging of the return code to get the sonde type.
ret_code = abs(-1 * (0x100 - ret_code))
# Split the line into sonde type and correlation score.
_fields = ret_output.split(':')
inv = "-"
if len(_fields) <2:
logging.error("Scanner - malformed output from dft_detect: %s" % ret_output.strip())
return None
else:
ret_code = abs(ret_code)
_type = _fields[0]
_score = float(_fields[1].strip())
if ret_code == 3:
logging.debug("Scanner #%s - Detected a RS41!" % str(device_idx))
return inv+"RS41"
elif ret_code == 4:
logging.debug("Scanner #%s - Detected a RS92!" % str(device_idx))
return inv+"RS92"
elif ret_code == 2:
logging.debug("Scanner #%s - Detected a DFM Sonde!" % str(device_idx))
return inv+"DFM"
elif ret_code == 5:
logging.debug("Scanner #%s - Detected a M10 Sonde!" % str(device_idx))
return inv+"M10"
elif ret_code == 6:
logging.debug("Scanner #%s - Detected a iMet Sonde! (Unsupported)" % str(device_idx))
return inv+"iMet"
if 'RS41' in _type:
logging.debug("Scanner #%s - Detected a RS41! (Score: %.2f)" % (str(device_idx), _score))
return "RS41"
elif 'RS92' in _type:
logging.debug("Scanner #%s - Detected a RS92! (Score: %.2f)" % (str(device_idx), _score))
return "RS92"
elif 'DFM' in _type:
logging.debug("Scanner #%s - Detected a DFM Sonde! (Score: %.2f)" % (str(device_idx), _score))
return "DFM"
elif 'M10' in _type:
logging.debug("Scanner #%s - Detected a M10 Sonde! (Score: %.2f)" % (str(device_idx), _score))
return "M10"
elif 'IMET' in _type:
logging.debug("Scanner #%s - Detected a iMet Sonde! (Unsupported, type %s) (Score: %.2f)" % (str(device_idx), _type, _score))
return "iMet"
elif 'LMS6' in _type:
logging.debug("Scanner #%s - Detected a LMS6 Sonde! (Unsupported) (Score: %.2f)" % (str(device_idx), _score))
return 'LMS6'
elif 'C34' in _type:
logging.debug("Scanner #%s - Detected a Meteolabor C34/C50 Sonde! (Unsupported) (Score: %.2f)" % (str(device_idx), _score))
return 'C34C50'
else:
return None

Wyświetl plik

@ -6,7 +6,6 @@
# Build rs_detect.
echo "Building rs_detect"
cd ../scan/
gcc rs_detect.c -lm -o rs_detect
gcc dft_detect.c -lm -o dft_detect
echo "Building RS92/RS41/DFM Demodulators"

Wyświetl plik

@ -414,6 +414,61 @@ int read_sbit(FILE *fp, int symlen, int *bit, int inv, int ofs, int reset, int c
return 0;
}
int read_spkbit(FILE *fp, int symlen, int *bit, int inv, int ofs, int reset, int cm, int spike) {
// symlen==2: manchester2 10->0,01->1: 2.bit
static double bitgrenze;
static unsigned long scount;
float sample;
float avg;
float ths = 0.5, scale = 0.27;
double sum = 0.0;
if (reset) {
scount = 0;
bitgrenze = 0;
}
if (symlen == 2) {
bitgrenze += samples_per_bit;
do {
if (buffered > 0) buffered -= 1;
else if (f32buf_sample(fp, inv, cm) == EOF) return EOF;
sample = bufs[(sample_out-buffered + ofs + M) % M];
avg = 0.5*(bufs[(sample_out-buffered-1 + ofs + M) % M]
+bufs[(sample_out-buffered+1 + ofs + M) % M]);
if (spike && fabs(sample - avg) > ths) sample = avg + scale*(sample - avg); // spikes
sum -= sample;
scount++;
} while (scount < bitgrenze); // n < samples_per_bit
}
bitgrenze += samples_per_bit;
do {
if (buffered > 0) buffered -= 1;
else if (f32buf_sample(fp, inv, cm) == EOF) return EOF;
sample = bufs[(sample_out-buffered + ofs + M) % M];
avg = 0.5*(bufs[(sample_out-buffered-1 + ofs + M) % M]
+bufs[(sample_out-buffered+1 + ofs + M) % M]);
if (spike && fabs(sample - avg) > ths) sample = avg + scale*(sample - avg); // spikes
sum += sample;
scount++;
} while (scount < bitgrenze); // n < samples_per_bit
if (sum >= 0) *bit = 1;
else *bit = 0;
return 0;
}
/* -------------------------------------------------------------------------- */
int read_softbit(FILE *fp, int symlen, int *bit, float *sb, float level, int inv, int ofs, int reset, int cm) {

Wyświetl plik

@ -2,6 +2,7 @@
float read_wav_header(FILE*, float, int);
int f32buf_sample(FILE*, int, int);
int read_sbit(FILE*, int, int*, int, int, int, int);
int read_spkbit(FILE*, int, int*, int, int, int, int, int);
int read_softbit(FILE *fp, int symlen, int *bit, float *sb, float level, int inv, int ofs, int reset, int cm);
float header_level(char hdr[], int hLen, unsigned int pos, int inv);

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,19 +1,115 @@
float read_wav_header(FILE*, float, int);
int f32buf_sample(FILE*, int, int);
int read_sbit(FILE*, int, int*, int, int, int, int);
int read_IDsbit(FILE*, int, int*, int, int, int, int);
int read_softbit(FILE *fp, int symlen, int *bit, float *sb, float level, int inv, int ofs, int reset, int cm);
float header_level(char hdr[], int hLen, unsigned int pos, int inv);
int getCorrDFT(int, int, unsigned int, float *, unsigned int *);
int headcmp(int, char*, int, unsigned int, int, int);
int get_fqofs(int, unsigned int, float *, float *);
float get_bufvar(int);
float get_bufmu(int);
#include <math.h>
#include <complex.h>
int init_buffers(char*, int, float, int);
int free_buffers(void);
typedef unsigned char ui8_t;
typedef unsigned short ui16_t;
typedef unsigned int ui32_t;
typedef char i8_t;
typedef short i16_t;
typedef int i32_t;
unsigned int get_sample(void);
typedef struct {
int sr; // sample_rate
int LOG2N;
int N;
int N2;
float *xn;
float complex *ew;
float complex *Fm;
float complex *X;
float complex *Z;
float complex *cx;
float complex *win; // float real
} dft_t;
typedef struct {
FILE *fp;
//
int sr; // sample_rate
int bps; // bits/sample
int nch; // channels
int ch; // select channel
//
int symlen;
float sps; // samples per symbol
float _spb; // samples per bit
float br; // baud rate
//
ui32_t sample_in;
ui32_t sample_out;
ui32_t delay;
int buffered;
int N;
int M;
int K;
float *match;
float *bufs;
float dc_ofs;
float dc;
//
int N_norm;
int Nvar;
float xsum;
float qsum;
float *xs;
float *qs;
// IQ-data
int opt_iq;
int N_IQBUF;
float complex *raw_iqbuf;
float complex *rot_iqbuf;
//
char *rawbits;
char *hdr;
int hdrlen;
//
float BT; // bw/time (ISI)
float h; // modulation index
// DFT
dft_t DFT;
double df;
int len_sq;
ui32_t sample_posframe;
ui32_t sample_posnoise;
double V_noise;
double V_signal;
double SNRdB;
} dsp_t;
typedef struct {
int sr; // sample_rate
int bps; // bits_sample bits/sample
int nch; // channels
int sel_ch; // select wav channel
} pcm_t;
float read_wav_header(pcm_t *, FILE *);
int f32buf_sample(dsp_t *, int);
int read_slbit(dsp_t *, int, int*, int, int, int, float);
int getCorrDFT(dsp_t *, int, ui32_t, float *, ui32_t *);
int headcmp(dsp_t *, int, ui32_t, int, int);
int get_fqofs_rs41(dsp_t *, ui32_t, float *, float *);
float get_bufvar(dsp_t *, int);
float get_bufmu(dsp_t *, int);
int init_buffers(dsp_t *);
int free_buffers(dsp_t *);
ui32_t get_sample(dsp_t *);

Wyświetl plik

@ -41,7 +41,7 @@ typedef struct {
float meas24[5];
float status[2];
float _frmcnt;
char sonde_id[16];
char sonde_id[16]; // "ID__:xxxxxxxx\0\0"
} gpx_t;
gpx_t gpx;
@ -56,7 +56,7 @@ pcksts_t pck[9];
char dat_str[9][13+1];
// JSON Buffer to store sonde ID
char json_sonde_id[] = "DFMxx-xxxxxxxxyy";
char json_sonde_id[] = "DFMxx-xxxxxxxx\0\0";
int option_verbose = 0, // ausfuehrliche Anzeige
option_raw = 0, // rohe Frames
@ -409,122 +409,207 @@ float get_Temp4(float *meas) { // meas[0..4]
#define SNbit 0x0100
int conf_out(ui8_t *conf_bits, int ec) {
int conf_id;
int ret = 0;
int val, hl;
int val;
ui8_t conf_id;
ui8_t hl;
ui32_t SN6, SN;
static int chAbit, chA[2];
static int chCbit, chC[2];
static int chDbit, chD[2];
static int ch7bit, ch7[2];
static ui32_t SN_A, SN_C, SN_D, SN_7;
static ui8_t max_ch;
static ui8_t nul_ch;
static ui8_t sn2_ch, sn_ch;
static ui32_t SN_X;
static int chXbit, chX[2];
static ui8_t dfm6typ;
conf_id = bits2val(conf_bits, 4);
// gibt es Kanaele > 6 (2-teilige ID)?
// if (conf_id > 6) gpx.SN6 = 0; // -> DFM-09,PS-15 // SNbit?
//
// SN/ID immer im letzten Kanal?
if ((gpx.sonde_typ & 0xF) < 7 && conf_id == 6) {
SN6 = bits2val(conf_bits+4, 4*6); // DFM-06: Kanal 6
if (SN6 == gpx.SN6 && SN6 != 0) { // nur Nibble-Werte 0..9
gpx.sonde_typ = SNbit | 6;
ptu_out = 6;
ret = 6;
sprintf(gpx.sonde_id, "ID06:%6X", gpx.SN6);
sprintf(json_sonde_id, "DFM06-%6X", gpx.SN6);
}
else {
gpx.sonde_typ = 0;
}
gpx.SN6 = SN6;
if (conf_id > 4 && bits2val(conf_bits+8, 4*5) == 0) nul_ch = bits2val(conf_bits, 8);
dfm6typ = ((nul_ch & 0xF0)==0x50) && (nul_ch & 0x0F);
if (dfm6typ) ptu_out = 6;
if (dfm6typ && (gpx.sonde_typ & 0xF) > 6)
{ // reset if 0x5A, 0x5B (DFM-06)
gpx.sonde_typ = 0;
max_ch = conf_id;
}
if (conf_id == 0xA) { // 0xACxxxxy , DFM-09
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1); // val&0xF 0,1?
chA[hl] = (val >> 4) & 0xFFFF;
chAbit |= 1 << hl;
if (chAbit == 3) { // DFM-09: Kanal A
SN = (chA[0] << 16) | chA[1];
if ( SN == SN_A ) {
gpx.sonde_typ = SNbit | 0xA;
gpx.SN = SN;
ptu_out = 9;
ret = 9;
sprintf(gpx.sonde_id, "ID09:%6u", gpx.SN);
sprintf(json_sonde_id, "DFM09-%6u", gpx.SN);
if (conf_id > 4 && conf_id > max_ch) max_ch = conf_id; // mind. 5 Kanaele // reset? lower 0xsCaaaab?
if (conf_id > 4 && conf_id == (nul_ch>>4)+1)
{
sn2_ch = bits2val(conf_bits, 8);
if (option_auto)
{
sn_ch = ((sn2_ch>>4) & 0xF);
if (conf_id == sn_ch)
{
if ( (nul_ch & 0x58) == 0x58 ) { // 0x5A, 0x5B
SN6 = bits2val(conf_bits+4, 4*6); // DFM-06: Kanal 6
if (SN6 == gpx.SN6 && SN6 != 0) { // nur Nibble-Werte 0..9
gpx.sonde_typ = SNbit | 6;
ptu_out = 6;
sprintf(gpx.sonde_id, "ID06:%6X", gpx.SN6);
sprintf(json_sonde_id, "DFM06-%6X", gpx.SN6);
}
else { // reset
gpx.sonde_typ = 0;
sprintf(json_sonde_id, "DFMxx-xxxxxxxx"); //json_sonde_id[0] = '\0';
}
gpx.SN6 = SN6;
}
else if ( (sn2_ch & 0xF) == 0xC // 0xsCaaaab, s==sn_ch , s: 0xA=DFM-09 , 0xC=DFM-17? 0xD=?
|| (sn2_ch & 0xF) == 0x0 ) // 0xs0aaaab, s==sn_ch , s: 0x7,0x8: pilotsonde PS-15?
{
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
chX[hl] = (val >> 4) & 0xFFFF;
chXbit |= 1 << hl;
if (chXbit == 3) {
SN = (chX[0] << 16) | chX[1];
if ( SN == SN_X || SN_X == 0 ) {
gpx.sonde_typ = SNbit | sn_ch;
gpx.SN = SN;
if (sn_ch == 0xA /*&& (sn2_ch & 0xF) == 0xC*/) ptu_out = 9; else ptu_out = 0;
// PS-15 ? (sn2_ch & 0xF) == 0x0 : ptu_out = 0
// DFM-17? (sn_ch == 0xC) ptu_out = 9 ? // test 0xD ...?
if ( (gpx.sonde_typ & 0xF) == 0xA) {
sprintf(gpx.sonde_id, "ID09:%6u", gpx.SN);
sprintf(json_sonde_id, "DFM09-%6u", gpx.SN);
}
else {
sprintf(gpx.sonde_id, "ID-%1X:%6u", gpx.sonde_typ & 0xF, gpx.SN);
sprintf(json_sonde_id, "DFMx%1X-%6u", gpx.sonde_typ & 0xF,gpx.SN);
}
}
else { // reset
gpx.sonde_typ = 0;
sprintf(json_sonde_id, "DFMxx-xxxxxxxx"); //json_sonde_id[0] = '\0';
}
SN_X = SN;
chXbit = 0;
}
}
ret = (gpx.sonde_typ & 0xF);
}
}
}
if (option_auto == 0) {
// gibt es Kanaele > 6 (2-teilige ID)?
// if (conf_id > 6) gpx.SN6 = 0; // -> DFM-09,PS-15 // SNbit?
//
// SN/ID immer im letzten Kanal? davor xy00000-Kanal? (mind. 1)
if ((gpx.sonde_typ & 0xF) < 7 && conf_id == 6) {
SN6 = bits2val(conf_bits+4, 4*6); // DFM-06: Kanal 6
if (SN6 == gpx.SN6 && SN6 != 0) { // nur Nibble-Werte 0..9
gpx.sonde_typ = SNbit | 6;
ptu_out = 6;
ret = 6;
sprintf(gpx.sonde_id, "ID06:%6X", gpx.SN6);
sprintf(json_sonde_id, "DFM06-%6X", gpx.SN6);
}
else {
gpx.sonde_typ = 0;
}
SN_A = SN;
chAbit = 0;
gpx.SN6 = SN6;
}
}
if (conf_id == 0xC) { // 0xCCxxxxy , DFM-17?
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
chC[hl] = (val >> 4) & 0xFFFF;
chCbit |= 1 << hl;
if (chCbit == 3) { // DFM-17? Kanal C
SN = (chC[0] << 16) | chC[1];
if ( SN == SN_C ) {
gpx.sonde_typ = SNbit | 0xC;
gpx.SN = SN;
ptu_out = 9;
ret = 17;
sprintf(gpx.sonde_id, "ID-%1X:%6u", gpx.sonde_typ & 0xF, gpx.SN);
sprintf(json_sonde_id, "DFM17-%6u", gpx.SN);
if (conf_id == 0xA) { // 0xACxxxxy , DFM-09
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1); // val&0xF 0,1?
chA[hl] = (val >> 4) & 0xFFFF;
chAbit |= 1 << hl;
if (chAbit == 3) { // DFM-09: Kanal A
SN = (chA[0] << 16) | chA[1];
if ( SN == SN_A ) {
gpx.sonde_typ = SNbit | 0xA;
gpx.SN = SN;
ptu_out = 9;
ret = 9;
sprintf(gpx.sonde_id, "ID09:%6u", gpx.SN);
sprintf(json_sonde_id, "DFM09-%6u", gpx.SN);
}
else {
gpx.sonde_typ = 0;
}
SN_A = SN;
chAbit = 0;
}
else {
gpx.sonde_typ = 0;
}
SN_C = SN;
chCbit = 0;
}
}
if (conf_id == 0xD) { // 0xDCxxxxy , DFM-17?
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
chD[hl] = (val >> 4) & 0xFFFF;
chDbit |= 1 << hl;
if (chDbit == 3) { // DFM-17? Kanal D
SN = (chD[0] << 16) | chD[1];
if ( SN == SN_D ) {
gpx.sonde_typ = SNbit | 0xD;
gpx.SN = SN;
ptu_out = 9;
ret = 18;
sprintf(gpx.sonde_id, "ID-%1X:%6u", gpx.sonde_typ & 0xF, gpx.SN);
sprintf(json_sonde_id, "DFM17-%6u", gpx.SN);
if (conf_id == 0xC) { // 0xCCxxxxy , DFM-17?
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
chC[hl] = (val >> 4) & 0xFFFF;
chCbit |= 1 << hl;
if (chCbit == 3) { // DFM-17? Kanal C
SN = (chC[0] << 16) | chC[1];
if ( SN == SN_C ) {
gpx.sonde_typ = SNbit | 0xC;
gpx.SN = SN;
ptu_out = 9; // ?
ret = 17;
sprintf(gpx.sonde_id, "ID-%1X:%6u", gpx.sonde_typ & 0xF, gpx.SN);
sprintf(json_sonde_id, "DFM17-%6u", gpx.SN);
}
else {
gpx.sonde_typ = 0;
}
SN_C = SN;
chCbit = 0;
}
else {
gpx.sonde_typ = 0;
}
SN_D = SN;
chDbit = 0;
}
}
if (conf_id == 0x7) { // 0x70xxxxy , pilotsonde PS-15?
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
ch7[hl] = (val >> 4) & 0xFFFF;
ch7bit |= 1 << hl;
if (ch7bit == 3) { // PS-15: Kanal 7
SN = (ch7[0] << 16) | ch7[1];
if ( SN == SN_7 ) {
gpx.sonde_typ = SNbit | 0x7;
gpx.SN = SN;
ptu_out = 0;
ret = 15;
sprintf(gpx.sonde_id, "ID15:%6u", gpx.SN);
sprintf(json_sonde_id, "DFM15-%6u", gpx.SN);
if (conf_id == 0xD) { // 0xDCxxxxy , DFM-17?
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
chD[hl] = (val >> 4) & 0xFFFF;
chDbit |= 1 << hl;
if (chDbit == 3) { // DFM-17? Kanal D
SN = (chD[0] << 16) | chD[1];
if ( SN == SN_D ) {
gpx.sonde_typ = SNbit | 0xD;
gpx.SN = SN;
ptu_out = 0; // ...
ret = 18;
sprintf(gpx.sonde_id, "ID-%1X:%6u", gpx.sonde_typ & 0xF, gpx.SN);
sprintf(json_sonde_id, "DFM17-%6u", gpx.SN);
}
else {
gpx.sonde_typ = 0;
}
SN_D = SN;
chDbit = 0;
}
else {
gpx.sonde_typ = 0;
}
if (conf_id == 0x7) { // 0x70xxxxy , pilotsonde PS-15?
val = bits2val(conf_bits+8, 4*5);
hl = (val & 1);
ch7[hl] = (val >> 4) & 0xFFFF;
ch7bit |= 1 << hl;
if (ch7bit == 3) { // PS-15: Kanal 7
SN = (ch7[0] << 16) | ch7[1];
if ( SN == SN_7 ) {
gpx.sonde_typ = SNbit | 0x7;
gpx.SN = SN;
ptu_out = 0;
ret = 15;
sprintf(gpx.sonde_id, "ID15:%6u", gpx.SN);
sprintf(json_sonde_id, "DFM15-%6u", gpx.SN);
}
else {
gpx.sonde_typ = 0;
}
SN_7 = SN;
ch7bit = 0;
}
SN_7 = SN;
ch7bit = 0;
}
}
@ -561,8 +646,14 @@ void print_gpx() {
int output = 0;
int jsonout = 0;
output |= start;
if (option_json && start == 0) { // JSON: initial reset
sprintf(json_sonde_id, "DFMxx-xxxxxxxx"); //json_sonde_id[0] = '\0';
}
for (i = 0; i < 9/*8*/; i++) { // trigger: pck8
if ( !( (option_dist || option_json) && pck[i].ec < 0) )
{
@ -588,7 +679,7 @@ void print_gpx() {
if (option_raw == 2) {
for (i = 0; i < 9; i++) {
printf(" %s", dat_str[i]);
if (option_ecc) printf(" [%1X] ", pck[i].ec&0xF);
if (option_ecc) printf(" (%1X) ", pck[i].ec&0xF);
}
for (i = 0; i < 9; i++) {
for (j = 0; j < 13; j++) dat_str[i][j] = ' ';
@ -599,11 +690,11 @@ void print_gpx() {
printf("[%3d] ", gpx.frnr);
printf("%4d-%02d-%02d ", gpx.jahr, gpx.monat, gpx.tag);
printf("%02d:%02d:%04.1f ", gpx.std, gpx.min, gpx.sek);
if (option_verbose >= 2 && option_ecc) printf("[%1X,%1X,%1X] ", pck[0].ec&0xF, pck[8].ec&0xF, pck[1].ec&0xF);
if (option_verbose >= 2 && option_ecc) printf("(%1X,%1X,%1X) ", pck[0].ec&0xF, pck[8].ec&0xF, pck[1].ec&0xF);
printf(" ");
printf(" lat: %.5f ", gpx.lat); if (option_verbose >= 2 && option_ecc) printf("[%1X] ", pck[2].ec&0xF);
printf(" lon: %.5f ", gpx.lon); if (option_verbose >= 2 && option_ecc) printf("[%1X] ", pck[3].ec&0xF);
printf(" alt: %.1f ", gpx.alt); if (option_verbose >= 2 && option_ecc) printf("[%1X] ", pck[4].ec&0xF);
printf(" lat: %.5f ", gpx.lat); if (option_verbose >= 2 && option_ecc) printf("(%1X) ", pck[2].ec&0xF);
printf(" lon: %.5f ", gpx.lon); if (option_verbose >= 2 && option_ecc) printf("(%1X) ", pck[3].ec&0xF);
printf(" alt: %.1f ", gpx.alt); if (option_verbose >= 2 && option_ecc) printf("(%1X) ", pck[4].ec&0xF);
printf(" vH: %5.2f ", gpx.horiV);
printf(" D: %5.1f ", gpx.dir);
printf(" vV: %5.2f ", gpx.vertV);
@ -798,7 +889,10 @@ int main(int argc, char **argv) {
option_inv = 0x1;
}
else if ( (strcmp(*argv, "--ecc") == 0) ) { option_ecc = 1; }
else if ( (strcmp(*argv, "--ptu") == 0) ) { option_ptu = 1; ptu_out = 1; }
else if ( (strcmp(*argv, "--ptu") == 0) ) {
option_ptu = 1;
//ptu_out = 1; // force ptu (non PS-15)
}
else if ( (strcmp(*argv, "--auto") == 0) ) { option_auto = 1; }
else if ( (strcmp(*argv, "--dist") == 0) ) { option_dist = 1; option_ecc = 1; }
else if ( (strcmp(*argv, "--json") == 0) ) { option_json = 1; option_ecc = 1; }

Wyświetl plik

@ -781,6 +781,8 @@ int print_frame(int pos) {
int main(int argc, char **argv) {
int spike = 0;
FILE *fp = NULL;
char *fpname = NULL;
float spb = 0.0;
@ -841,6 +843,9 @@ int main(int argc, char **argv) {
else if ( (strcmp(*argv, "--dc") == 0) ) {
option_dc = 1;
}
else if ( (strcmp(*argv, "--spike") == 0) ) {
spike = 1;
}
else if ( (strcmp(*argv, "--ch2") == 0) ) { wav_channel = 1; } // right channel (default: 0=left)
else if ( (strcmp(*argv, "--ths") == 0) ) {
++argv;
@ -906,8 +911,8 @@ int main(int argc, char **argv) {
herrs = headcmp(1, rawheader, headerlen, mv_pos, mv<0, option_dc); // header nicht manchester!
herr1 = 0;
if (herrs <= 3 && herrs > 0) {
herr1 = headcmp(1, rawheader, headerlen, mv_pos+1, mv<0, option_dc);
//int herr2 = headcmp(1, rawheader, headerlen, mv_pos-1, mv<0, option_dc);
herr1 = headcmp(1, rawheader, headerlen, mv_pos+1, mv<0, 0); // nur 1x dc
//int herr2 = headcmp(1, rawheader, headerlen, mv_pos-1, mv<0, 0);
if (herr1 < herrs) {
herrs = herr1;
herr1 = 1;
@ -924,7 +929,7 @@ int main(int argc, char **argv) {
while ( pos < BITFRAME_LEN+BITAUX_LEN ) {
header_found = !(pos>=BITFRAME_LEN-10);
bitQ = read_sbit(fp, symlen, &bit, option_inv, bitofs, bitpos==0, !header_found); // symlen=2, return: zeroX/bit
bitQ = read_spkbit(fp, symlen, &bit, option_inv, bitofs, bitpos==0, !header_found, spike); // symlen=2, return: zeroX/bit
if (bitQ == EOF) { break; }
frame_bits[pos] = 0x31 ^ (bit0 ^ bit);
pos++;
@ -940,7 +945,7 @@ int main(int argc, char **argv) {
// bis Ende der Sekunde vorspulen; allerdings Doppel-Frame alle 10 sek
if (option_verbose < 3) { // && (regulare frame) // print_frame-return?
while ( bitpos < 5*BITFRAME_LEN ) {
bitQ = read_sbit(fp, symlen, &bit, option_inv, bitofs, bitpos==0, 0); // symlen=2, return: zeroX/bit
bitQ = read_spkbit(fp, symlen, &bit, option_inv, bitofs, bitpos==0, 0, spike); // symlen=2, return: zeroX/bit
if ( bitQ == EOF) break;
bitpos++;
}

Wyświetl plik

@ -47,6 +47,7 @@ rscfg_t cfg_rs41 = { 41, (320-56)/2, 56, 8, 8, 320};
typedef struct {
int frnr;
char id[9];
ui8_t numSV;
int week; int gpssec;
int jahr; int monat; int tag;
int wday;
@ -326,6 +327,23 @@ int check_CRC(ui32_t pos, ui32_t pck) {
#define crc_ZERO (1<<6) // LEN variable
#define pck_ZERO 0x7600
#define pck_ZEROstd 0x7611 // NDATA std-frm, no aux
#define pos_ZEROstd 0x12B // pos_AUX(0)
/*
frame[pos_FRAME-1] == 0x0F: len == NDATA_LEN(320)
frame[pos_FRAME-1] == 0xF0: len == FRAME_LEN(518)
*/
int frametype() { // -4..+4: 0xF0 -> -4 , 0x0F -> +4
int i;
ui8_t b = frame[pos_FRAME-1];
int ft = 0;
for (i = 0; i < 4; i++) {
ft += ((b>>i)&1) - ((b>>(i+4))&1);
}
return ft;
}
ui8_t calibytes[51*16];
@ -345,7 +363,7 @@ int get_SatData() {
int i, n;
int sv;
ui32_t minPR;
int Nfix;
int numSV;
double pDOP, sAcc;
fprintf(stdout, "[%d]\n", u2(frame+pos_FrameNb));
@ -377,10 +395,10 @@ int get_SatData() {
(i16_t)u2(frame+pos_GPSecefV+2),
(i16_t)u2(frame+pos_GPSecefV+4));
Nfix = frame[pos_numSats];
sAcc = frame[pos_sAcc]/10.0;
pDOP = frame[pos_pDOP]/10.0;
fprintf(stdout, "numSatsFix: %2d sAcc: %.1f pDOP: %.1f\n", Nfix, sAcc, pDOP);
numSV = frame[pos_numSats];
sAcc = frame[pos_sAcc]/10.0; if (frame[pos_sAcc] == 0xFF) sAcc = -1.0;
pDOP = frame[pos_pDOP]/10.0; if (frame[pos_pDOP] == 0xFF) pDOP = -1.0;
fprintf(stdout, "numSatsFix: %2d sAcc: %.1f pDOP: %.1f\n", numSV, sAcc, pDOP);
fprintf(stdout, "CRC: ");
@ -749,6 +767,8 @@ int get_GPSkoord() {
if (dir < 0) dir += 360;
gpx.vD = dir;
gpx.numSV = frame[pos_numSats];
return 0;
}
@ -778,6 +798,8 @@ int get_Aux() {
count7E = 0;
pos7E = pos_AUX;
if (frametype(gpx) > 0) return 0; //pos7E == pos7611 ...
// 7Exx: xdata
while ( pos7E < FRAME_LEN && framebyte(pos7E) == 0x7E ) {
@ -790,7 +812,8 @@ int get_Aux() {
//fprintf(stdout, " # %02x : ", framebyte(pos7E+2));
for (i = 1; i < auxlen; i++) {
fprintf(stdout, "%c", framebyte(pos7E+2+i));
ui8_t c = framebyte(pos7E+2+i);
if (c > 0x1E) fprintf(stdout, "%c", c);
}
count7E++;
pos7E += 2+auxlen+2;
@ -880,20 +903,6 @@ int get_Calconf(int out) {
return 0;
}
/*
frame[pos_FRAME-1] == 0x0F: len == NDATA_LEN(320)
frame[pos_FRAME-1] == 0xF0: len == FRAME_LEN(518)
*/
int frametype() { // -4..+4: 0xF0 -> -4 , 0x0F -> +4
int i;
ui8_t b = frame[pos_FRAME-1];
int ft = 0;
for (i = 0; i < 4; i++) {
ft += ((b>>i)&1) - ((b>>(i+4))&1);
}
return ft;
}
/* ------------------------------------------------------------------------------------ */
/*
(uses fec-lib by KA9Q)
@ -946,15 +955,26 @@ int rs41_ecc(int frmlen) {
errors2 = rs_decode(cw2, err_pos2, err_val2);
if (option_ecc == 2 && (errors1 < 0 || errors2 < 0)) {
if (option_ecc == 2 && (errors1 < 0 || errors2 < 0))
{ // 2nd pass
frame[pos_FRAME] = (pck_FRAME>>8)&0xFF; frame[pos_FRAME+1] = pck_FRAME&0xFF;
frame[pos_PTU] = (pck_PTU >>8)&0xFF; frame[pos_PTU +1] = pck_PTU &0xFF;
frame[pos_GPS1] = (pck_GPS1 >>8)&0xFF; frame[pos_GPS1 +1] = pck_GPS1 &0xFF;
frame[pos_GPS2] = (pck_GPS2 >>8)&0xFF; frame[pos_GPS2 +1] = pck_GPS2 &0xFF;
frame[pos_GPS3] = (pck_GPS3 >>8)&0xFF; frame[pos_GPS3 +1] = pck_GPS3 &0xFF;
if (frametype() < -2) {
// AUX-frames mit vielen Fehlern besser mit 00 auffuellen
// std-O3-AUX-frame: NDATA+7
if (frametype() < -2) { // ft >= 0: NDATA_LEN , ft < 0: FRAME_LEN
for (i = NDATA_LEN + 7; i < FRAME_LEN-2; i++) frame[i] = 0;
}
else { // std-frm (len=320): std_ZERO-frame (7611 00..00 ECC7)
for (i = NDATA_LEN; i < FRAME_LEN; i++) frame[i] = 0;
frame[pos_ZEROstd ] = 0x76; // pck_ZEROstd
frame[pos_ZEROstd+1] = 0x11; // pck_ZEROstd
for (i = pos_ZEROstd+2; i < NDATA_LEN-2; i++) frame[i] = 0;
frame[NDATA_LEN-2] = 0xEC; // crc(pck_ZEROstd)
frame[NDATA_LEN-1] = 0xC7; // crc(pck_ZEROstd)
}
for (i = 0; i < rs_K; i++) cw1[rs_R+i] = frame[cfg_rs41.msgpos+2*i ];
for (i = 0; i < rs_K; i++) cw2[rs_R+i] = frame[cfg_rs41.msgpos+2*i+1];
errors1 = rs_decode(cw1, err_pos1, err_val1);
@ -1036,6 +1056,7 @@ int print_position(int ec) {
{
//fprintf(stdout, " (%.1f %.1f %.1f) ", gpx.vN, gpx.vE, gpx.vU);
fprintf(stdout," vH: %4.1f D: %5.1f° vV: %3.1f ", gpx.vH, gpx.vD, gpx.vU);
if (option_verbose == 3) fprintf(stdout," numSV: %02d ", gpx.numSV);
}
}
if (option_ptu && !err0) {
@ -1085,9 +1106,9 @@ int print_position(int ec) {
// Print JSON output required by auto_rx.
if (!err && !err1 && !err3) { // frame-nb/id && gps-time && gps-position (crc-)ok; 3 CRCs, RS not needed
if (option_ptu && !err0 && gpx.T > -273.0) {
printf("{ \"frame\": %d, \"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f, \"temp\":%.1f }\n", gpx.frnr, gpx.id, gpx.jahr, gpx.monat, gpx.tag, gpx.std, gpx.min, gpx.sek, gpx.lat, gpx.lon, gpx.alt, gpx.vH, gpx.vD, gpx.vU, gpx.T );
printf("{ \"frame\": %d, \"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f, \"sats\": %d, \"temp\":%.1f }\n", gpx.frnr, gpx.id, gpx.jahr, gpx.monat, gpx.tag, gpx.std, gpx.min, gpx.sek, gpx.lat, gpx.lon, gpx.alt, gpx.vH, gpx.vD, gpx.vU, gpx.numSV, gpx.T );
} else {
printf("{ \"frame\": %d, \"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f }\n", gpx.frnr, gpx.id, gpx.jahr, gpx.monat, gpx.tag, gpx.std, gpx.min, gpx.sek, gpx.lat, gpx.lon, gpx.alt, gpx.vH, gpx.vD, gpx.vU );
printf("{ \"frame\": %d, \"id\": \"%s\", \"datetime\": \"%04d-%02d-%02dT%02d:%02d:%06.3fZ\", \"lat\": %.5f, \"lon\": %.5f, \"alt\": %.5f, \"vel_h\": %.5f, \"heading\": %.5f, \"vel_v\": %.5f, \"sats\": %d }\n", gpx.frnr, gpx.id, gpx.jahr, gpx.monat, gpx.tag, gpx.std, gpx.min, gpx.sek, gpx.lat, gpx.lon, gpx.alt, gpx.vH, gpx.vD, gpx.vU, gpx.numSV );
}
printf("\n");
}
@ -1142,7 +1163,14 @@ void print_frame(int len) {
}
if (option_ecc) {
if (ec >= 0) fprintf(stdout, " [OK]"); else fprintf(stdout, " [NO]");
if (option_ecc == 2 && ec > 0) fprintf(stdout, " (%d)", ec);
if (option_ecc == 2) {
if (ec > 0) fprintf(stdout, " (%d)", ec);
if (ec < 0) {
if (ec == -1) fprintf(stdout, " (-+)");
else if (ec == -2) fprintf(stdout, " (+-)");
else /*ec == -3*/ fprintf(stdout, " (--)");
}
}
}
fprintf(stdout, "\n");
}
@ -1179,8 +1207,8 @@ int main(int argc, char *argv[]) {
float thres = 0.7;
int bitofs = 0;
int symlen = 1;
int bitofs = 2;
#ifdef CYGWIN
@ -1338,8 +1366,9 @@ int main(int argc, char *argv[]) {
Qerror_count += 1;
}
}
header_found = 0;
print_frame(ft_len);
header_found = 0;
while ( bit_count < BITS*(FRAME_LEN-8+24) ) {
bitQ = read_sbit(fp, symlen, &bit, option_inv, bitofs, bit_count==0, 0); // symlen=1, return: zeroX/bit

Plik diff jest za duży Load Diff

Wyświetl plik

@ -22,8 +22,8 @@ static int wav_channel = 0; // audio channel: left
//int dfm_bps = 2500;
static char dfm_header[] = "01100101011001101010010110101010";
static char dfm_header[] = "10011010100110010101101001010101"; // DFM-09
// "01100101011001101010010110101010"; // DFM-06
//int vai_bps = 4800;
static char rs41_header[] = "00001000011011010101001110001000"
"01000100011010010100100000011111";
@ -54,7 +54,7 @@ static char imet_preamble[] = "11110000111100001111000011110000"
//int imet1ab_bps = 9600; // 1200 bits/sec
static char imet1ab_header[] = "11110000111100001111000011110000"
// "11110000""10101100110010101100101010101100"
// "11110000""10101100110010101100101010101100"
"11110000""10101100110010101100101010101100";
@ -83,14 +83,14 @@ typedef struct {
float thres;
float complex *Fm;
char *type;
unsigned char tn;
ui8_t tn; // signed?
} rsheader_t;
#define Nrs 9
#define idxAB 7
#define idxRS 8
static rsheader_t rs_hdr[Nrs] = {
{ 2500, 0, 0, dfm_header, 1.0, 0.0, 0.65, NULL, "DFM", 2},
{ 2500, 0, 0, dfm_header, 1.0, 0.0, 0.65, NULL, "DFM9", 2}, // DFM6: -2 (unsigned)
{ 4800, 0, 0, rs41_header, 0.5, 0.0, 0.70, NULL, "RS41", 3},
{ 4800, 0, 0, rs92_header, 0.5, 0.0, 0.70, NULL, "RS92", 4},
{ 4800, 0, 0, lms6_header, 1.0, 0.0, 0.70, NULL, "LMS6", 8},
@ -594,7 +594,7 @@ static int init_buffers() {
b += b0*pulse(t+1, sigma);
}
if (pos < hLen) {
if (pos < hLen-1) {
b2 = ((bits[pos+1] & 0x1) - 0.5)*2.0;
b += b2*pulse(t-1, sigma);
}
@ -661,6 +661,7 @@ int main(int argc, char **argv) {
int header_found = 0;
int herrs;
float thres = 0.76;
float tl = -1.0;
int j_max;
float mv_max;
@ -682,12 +683,15 @@ int main(int argc, char **argv) {
else if ( (strcmp(*argv, "-v") == 0) || (strcmp(*argv, "--verbose") == 0) ) {
option_verbose = 1;
}
else if ( (strcmp(*argv, "--dc") == 0) ) {
option_dc = 1;
}
//else if ( (strcmp(*argv, "--dc") == 0) ) { option_dc = 1; }
else if ( (strcmp(*argv, "-s") == 0) || (strcmp(*argv, "--silent") == 0) ) {
option_silent = 1;
}
else if ( (strcmp(*argv, "-t") == 0) || (strcmp(*argv, "--time") == 0) ) {
++argv;
if (*argv) tl = atof(*argv);
else return -50;
}
else if ( (strcmp(*argv, "--ch2") == 0) ) { wav_channel = 1; } // right channel (default: 0=left)
else if ( (strcmp(*argv, "--ths") == 0) ) {
++argv;
@ -695,13 +699,13 @@ int main(int argc, char **argv) {
thres = atof(*argv);
for (j = 0; j < Nrs; j++) rs_hdr[j].thres = thres;
}
else return -1;
else return -50;
}
else {
fp = fopen(*argv, "rb");
if (fp == NULL) {
fprintf(stderr, "%s konnte nicht geoeffnet werden\n", *argv);
return -1;
return -50;
}
wavloaded = 1;
}
@ -714,14 +718,14 @@ int main(int argc, char **argv) {
if ( j < 0 ) {
fclose(fp);
fprintf(stderr, "error: wav header\n");
return -1;
return -50;
}
K = init_buffers();
if ( K < 0 ) {
fprintf(stderr, "error: init buffers\n");
return -1;
return -50;
};
for (j = 0; j < Nrs; j++) {
@ -734,6 +738,8 @@ int main(int argc, char **argv) {
while ( f32buf_sample(fp, option_inv, 1) != EOF ) {
if (tl > 0 && sample_in > (tl+1)*sample_rate) break; // (int)sample_out < 0
k += 1;
if (k >= K-4) {
@ -754,7 +760,7 @@ int main(int argc, char **argv) {
if (mp[j] > 0 && (mv[j] > rs_hdr[j].thres || mv[j] < -rs_hdr[j].thres)) {
if (mv_pos[j] > mv0_pos[j]) {
herrs = headcmp(1, rs_hdr[j].header, rs_hdr[j].hLen, mv_pos[j], mv[j]<0, option_dc, rs_hdr[j].spb);
herrs = headcmp(1, rs_hdr[j].header, rs_hdr[j].hLen, mv_pos[j], mv[j]<0, 0, rs_hdr[j].spb);
if (herrs < 2) { // max 1 bitfehler in header
if ( strncmp(rs_hdr[j].type, "IMET", 4) == 0 )
@ -843,7 +849,7 @@ int main(int argc, char **argv) {
if (header_found) {
if (!option_silent) {
fprintf(stdout, "sample: %d\n", mv_pos[j]);
if (option_verbose) fprintf(stdout, "sample: %d\n", mv_pos[j]);
fprintf(stdout, "%s: %.4f\n", rs_hdr[j].type, mv[j]);
}
if ((j < 3) && mv[j] < 0) header_found = -1;