Rebase fsk_demod.

pull/276/head
Mark Jessop 2020-06-07 20:37:20 +09:30
rodzic 35746558c0
commit 2bdae57774
11 zmienionych plików z 795 dodań i 831 usunięć

Wyświetl plik

@ -38,12 +38,12 @@ NORMALISE = True
SAMPLES = [
['rs41_96k_float.bin', 4800, -20.0, 96000],
['rs92_96k_float.bin', 2400, -100, 96000], # No threshold set, as signal is continuous.
['rs92_96k_float.bin', 4800, -100, 96000], # No threshold set, as signal is continuous.
['dfm09_96k_float.bin', 2500, -100, 96000], # Weird baud rate. No threshold set, as signal is continuous.
['m10_96k_float.bin', 9616, -10.0, 96000], # Really weird baud rate.
['imet4_96k_float.bin', 1200, -10.0, 96000], # 1200 baud, but AFSK, so we expect 7-8 dB worse performance than the other sondes.
['rsngp_96k_float.bin', 2400, -100.0, 96000], # RS92-NGP - wider bandwidth.
['lms6-400_96k_float.bin', 4800, -100, 96000] # LMS6, 400 MHz variant. Continuous signal.
['lms6-400_96k_float.bin', 9600, -100, 96000] # LMS6, 400 MHz variant. Continuous signal.
]

Wyświetl plik

@ -121,7 +121,7 @@ processing_type = {
# # RS41 Decoding
'rs41_fsk_demod': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.125 2>/dev/null | csdr convert_f_s16 | ./tsrc - - 0.500 | ../fsk_demod --cs16 -b 1 -u 24000 --stats=100 2 48000 4800 - - 2>stats.txt |",
'demod' : "| csdr shift_addition_cc 0.125 2>/dev/null | csdr convert_f_s16 | ./tsrc - - 0.500 | ../fsk_demod --cs16 -b 1 -u 24000 --stats=5 2 48000 4800 - - 2>stats.txt |",
# Decode using rs41ecc
'decode': "../rs41mod --ecc --ptu --crc --bin --json 2>/dev/null",
@ -132,7 +132,7 @@ processing_type = {
# # RS92 Decoding
'rs92_fsk_demod': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=5 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../rs92mod -vx -v --crc --ecc --vel 2>/dev/null",
@ -142,7 +142,7 @@ processing_type = {
},
'm10_fsk_demod': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.0016666 -c | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96160 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null| ",
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.0016666 -c | ../fsk_demod --cs16 -b 1 -u 45000 --stats=5 2 96160 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null| ",
'decode': "tee test.wav | ../m10mod --json -vvv 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| grep aprsid | wc -l",
@ -154,7 +154,7 @@ processing_type = {
#python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null|
#../dfm09ecc -vv --json --dist --auto
'demod': '| csdr shift_addition_cc 0.125000 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 0.5208| ../fsk_demod --cs16 -b 1250 -u 23750 --stats=100 2 50000 2500 - - 2>stats.txt |',#' python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null| ',
'demod': '| csdr shift_addition_cc 0.125000 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 0.5208| ../fsk_demod --cs16 -b 1250 -u 23750 --stats=5 2 50000 2500 - - 2>stats.txt |',#' python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null| ',
'decode': '../dfm09mod -vv --json --dist --auto --bin 2>/dev/null',
"post_process" : " | grep frame | wc -l", # ECC
#"post_process" : "| grep -o '\[OK\]' | wc -l", # No ECC
@ -164,7 +164,7 @@ processing_type = {
# LMS6-400 Decoding
'lms6-400_fsk_demod': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=100 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=5 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../lms6Xmod --json 2>/dev/null",
@ -179,7 +179,78 @@ processing_type = {
# The recording bandwidth needs to be correspondingly huge, with ~480 kHz sample rate required to capture the signal.
# We need to resample up to a multiple of 9616 Hz to be able to get fsk_demod to decode.
# fsk_demod does not decode these types reliably at the moment.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ./tsrc - - 1.00166666 | ../fsk_demod --cs16 -b 5000 -u 230000 --stats=100 2 480800 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null|",
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ./tsrc - - 1.00166666 | ../fsk_demod --cs16 -b 5000 -u 230000 --stats=5 2 480800 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../mk2a_lms1680 -i --json 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep frame | wc -l",
# No low-SNR samples for this sonde available yet.
'files' : "./generated/lms6-1680*"
},
## Tests for the updated fsk_demod (2020-06)
'rs41_fsk_demod_new': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.125 2>/dev/null | csdr convert_f_s16 | ./tsrc - - 0.500 | ../fsk_demod --cs16 -b 1 -u 24000 --stats=5 2 48000 4800 - - 2>stats.txt |",
# Decode using rs41ecc
'decode': "../rs41mod --ecc --ptu --crc --bin --json 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep frame | wc -l",
'files' : "./generated/rs41*"
},
# # RS92 Decoding
'rs92_fsk_demod_new': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=5 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../rs92mod -vx -v --crc --ecc --vel 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep M2513116 | wc -l",
'files' : "./generated/rs92*"
},
'm10_fsk_demod_new': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 1.0016666 -c | ../fsk_demod --cs16 -b 1 -u 45000 --stats=5 2 96160 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null| ",
'decode': "tee test.wav | ../m10mod --json -vvv 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| grep aprsid | wc -l",
'files' : "./generated/m10*"
},
'dfm_fsk_demod_new': {
# cat ./generated/dfm09_96k_float_15.0dB.bin | csdr shift_addition_cc 0.25000 2>/dev/null | csdr convert_f_s16 |
#./tsrc - - 1.041666 | ../fsk_demod --cs16 -b 1 -u 45000 2 100000 2500 - - 2>/dev/null |
#python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null|
#../dfm09ecc -vv --json --dist --auto
'demod': '| csdr shift_addition_cc 0.125000 2>/dev/null | csdr convert_f_s16 | ../tsrc - - 0.5208| ../fsk_demod --cs16 -b 1250 -u 23750 --stats=5 2 50000 2500 - - 2>stats.txt |',#' python ./bit_to_samples.py 50000 2500 | sox -t raw -r 50k -e unsigned-integer -b 8 -c 1 - -r 50000 -b 8 -t wav - 2>/dev/null| ',
'decode': '../dfm09mod -vv --json --dist --auto --bin 2>/dev/null',
"post_process" : " | grep frame | wc -l", # ECC
#"post_process" : "| grep -o '\[OK\]' | wc -l", # No ECC
'files' : "./generated/dfm*.bin"
},
# LMS6-400 Decoding
'lms6-400_fsk_demod_new': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../fsk_demod --cs16 -b 1 -u 45000 --stats=5 2 96000 4800 - - 2>stats.txt | python ./bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../lms6Xmod --json 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| grep frame | wc -l",
'files' : "./generated/lms6-400*",
},
'lms6-1680_fsk_demod_new': {
# This is a weird one.
# The baud rate is ~9616 Baud, but the deviation is *huge* (~170 kHz occupied bandwidth).
# The recording bandwidth needs to be correspondingly huge, with ~480 kHz sample rate required to capture the signal.
# We need to resample up to a multiple of 9616 Hz to be able to get fsk_demod to decode.
# fsk_demod does not decode these types reliably at the moment.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ./tsrc - - 1.00166666 | ../fsk_demod --cs16 -b 5000 -u 230000 --stats=5 2 480800 9616 - - 2>stats.txt | python ./bit_to_samples.py 57696 9616 | sox -t raw -r 57696 -e unsigned-integer -b 8 -c 1 - -r 57696 -b 8 -t wav - 2>/dev/null|",
# Decode using rs41ecc
'decode': "../mk2a_lms1680 -i --json 2>/dev/null",
@ -616,7 +687,7 @@ def run_analysis(mode, file_mask=None, shift=0.0, verbose=False, log_output = No
_runtime = time.time() - _start
_result = "%s, %s" % (os.path.basename(_file), _output.strip())
_result = "%s, %s, %.1f" % (os.path.basename(_file), _output.strip(), _runtime)
print(_result)
if log_output is not None:
@ -633,7 +704,7 @@ def run_analysis(mode, file_mask=None, shift=0.0, verbose=False, log_output = No
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", type=str, default="rs41_csdr", help="Operation mode.")
parser.add_argument("-m", "--mode", type=str, default="rs41_fsk_demod", help="Operation mode.")
parser.add_argument("-f", "--files", type=str, default=None, help="Glob-path to files to run over.")
parser.add_argument("-v", "--verbose", action='store_true', default=False, help="Show additional debug info.")
parser.add_argument("-d", "--dry-run", action='store_true', default=False, help="Show additional debug info.")

Wyświetl plik

@ -38,6 +38,9 @@
#ifndef __FDMDV__
#define __FDMDV__
#include "comp.h"
#include "modem_stats.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -55,9 +58,6 @@ extern "C" {
#define CODEC2_WIN32SUPPORT
#endif
#include "comp.h"
#include "modem_stats.h"
#define FDMDV_NC 14 /* default number of data carriers */
#define FDMDV_NC_MAX 20 /* maximum number of data carriers */
#define FDMDV_BITS_PER_FRAME 28 /* 20ms frames, for nominal 1400 bit/s */

Wyświetl plik

@ -86,7 +86,7 @@ inline static COMP cadd(COMP a, COMP b)
inline static float cabsolute(COMP a)
{
return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
return sqrtf((a.real * a.real) + (a.imag * a.imag) );
}
/*

Plik diff jest za duży Load Diff

Wyświetl plik

@ -28,6 +28,7 @@
#ifndef __C2FSK_H
#define __C2FSK_H
#include <stdint.h>
#include "comp.h"
#include "kiss_fftr.h"
@ -40,9 +41,13 @@
#define FSK_SCALE 16383
/* default internal parameters */
#define FSK_DEFAULT_P 8
#define FSK_DEFAULT_NSYM 50
struct FSK {
/* Static parameters set up by fsk_init */
int Ndft; /* buffer size for freq offset est fft */
int Ndft; /* freq offset est fft */
int Fs; /* sample freq */
int N; /* processing buffer size */
int Rs; /* symbol rate */
@ -54,35 +59,35 @@ struct FSK {
int f1_tx; /* f1 for modulator */
int fs_tx; /* Space between TX freqs for modulatosr */
int mode; /* 2FSK or 4FSK */
float tc; /* time constant for smoothing FFTs */
int est_min; /* Minimum frequency for freq. estimator */
int est_max; /* Maximum frequency for freq. estimaotr */
int est_space; /* Minimum frequency spacing for freq. estimator */
float* hann_table; /* Precomputed or runtime computed hann window table */
float* hann_table; /* Precomputed or runtime computed hann window table */
/* Parameters used by demod */
COMP phi_c[MODE_M_MAX];
float* Sf; /* Average of magnitude spectrum */
COMP phi_c[MODE_M_MAX]; /* phase of each demod local oscillator */
COMP *f_dc; /* down converted samples */
kiss_fft_cfg fft_cfg; /* Config for KISS FFT, used in freq est */
float norm_rx_timing; /* Normalized RX timing */
COMP* samp_old; /* Tail end of last batch of samples */
int nstash; /* How many elements are in there */
float* fft_est; /* Freq est FFT magnitude */
/* Memory used by demod but not important between demod frames */
/* Parameters used by mod */
COMP tx_phase_c; /* TX phase, but complex */
/* Statistics generated by demod */
float EbNodB; /* Estimated EbNo in dB */
float f_est[MODE_M_MAX];/* Estimated frequencies */
float ppm; /* Estimated PPM clock offset */
float EbNodB; /* Estimated EbNo in dB */
float f_est[MODE_M_MAX]; /* Estimated frequencies (peak method) */
float f2_est[MODE_M_MAX];/* Estimated frequencies (mask method) */
int freq_est_type; /* which estimator to use */
float ppm; /* Estimated PPM clock offset */
/* Parameters used by mod/demod and driving code */
int nin; /* Number of samples to feed the next demod cycle */
int burst_mode; /* enables/disables 'burst' mode */
int lock_nin; /* locks nin during testing */
/* modem statistic struct */
struct MODEM_STATS *stats;
@ -107,17 +112,12 @@ struct FSK * fsk_create(int Fs, int Rs, int M, int tx_f1, int tx_fs);
* int tx_f1 - '0' frequency
* int tx_fs - frequency spacing
*/
struct FSK * fsk_create_hbr(int Fs, int Rs, int P, int M, int tx_f1, int tx_fs);
/*
* Set a new number of symbols per processing frame
*/
void fsk_set_nsym(struct FSK *fsk,int nsym);
struct FSK * fsk_create_hbr(int Fs, int Rs, int M, int P, int Nsym, int tx_f1, int tx_fs);
/*
* Set the minimum and maximum frequencies at which the freq. estimator can find tones
*/
void fsk_set_est_limits(struct FSK *fsk,int fmin, int fmax);
void fsk_set_freq_est_limits(struct FSK *fsk,int fmin, int fmax);
/*
* Clear the estimator states
@ -179,7 +179,7 @@ uint32_t fsk_nin(struct FSK *fsk);
*
* struct FSK *fsk - FSK config/state struct, set up by fsk_create
* uint8_t rx_bits[] - Buffer for Nbits unpacked bits to be written
* float fsk_in[] - nin samples of modualted FSK
* float fsk_in[] - nin samples of modulated FSK
*/
void fsk_demod(struct FSK *fsk, uint8_t rx_bits[],COMP fsk_in[]);
@ -199,6 +199,9 @@ void fsk_stats_normalise_eye(struct FSK *fsk, int normalise_enable);
/* Set the FSK modem into burst demod mode */
void fsk_enable_burst_mode(struct FSK *fsk,int nsyms);
void fsk_enable_burst_mode(struct FSK *fsk);
/* Set freq est algorithm 0: peak 1:mask */
void fsk_set_freq_est_alg(struct FSK *fsk, int est_type);
#endif

Wyświetl plik

@ -37,7 +37,6 @@
#include <signal.h>
#include <unistd.h>
#include "fsk.h"
#include "codec2_fdmdv.h"
#include "modem_stats.h"
@ -57,7 +56,6 @@ int main(int argc,char *argv[]){
int Fs,Rs,M,P,stats_ctr,stats_loop;
float loop_time;
int enable_stats = 0;
int hbr = 1;
FILE *fin,*fout;
uint8_t *bitbuf = NULL;
int16_t *rawbuf;
@ -69,86 +67,88 @@ int main(int argc,char *argv[]){
int complex_input = 1, bytes_per_sample = 2;
int stats_rate = 8;
int testframe_mode = 0;
P = 0;
P = 10; /* default */
M = 0;
int fsk_lower = -1;
int fsk_upper = -1;
int fsk_lower = 0;
int fsk_upper = 0;
int user_fsk_lower = 0;
int user_fsk_upper = 0;
int nsym = FSK_DEFAULT_NSYM;
int mask = 0;
int tx_tone_separation = 100;
/* -m 2/4 --mode 2/4 - FSK mode
* -l --lbr - Low bit rate mode
* -p n --conv n - Downconverted symbol size
* If p is unspecified, it will default to Ts
* -c --cs16 - Complex (signed 16-bit)
* -d --cu8 - Complex (unsigned 8-bit)
* If neither -c or -d are specified, input will be real valued signed 16-bit
* -t --stats - dump demod statistics to stderr
* -s --soft-dec - ouput soft decision (float 32-bit)
*/
/* usage: [-l] [-p P] [-s] [(-c|-d)] [-t] (2|4) SampleRate SymbolRatez InputModemRawFile OutputOneBitPerCharFile */
int o = 0;
int opt_idx = 0;
while( o != -1 ){
int o = 0;
int opt_idx = 0;
while( o != -1 ){
static struct option long_opts[] = {
{"help", no_argument, 0, 'h'},
{"lbr", no_argument, 0, 'l'},
{"conv", required_argument, 0, 'p'},
{"cs16", no_argument, 0, 'c'},
{"cu8", no_argument, 0, 'd'},
{"fsk_lower", optional_argument, 0, 'b'},
{"fsk_upper", optional_argument, 0, 'u'},
{"fsk_lower", required_argument, 0, 'b'},
{"fsk_upper", required_argument, 0, 'u'},
{"stats", optional_argument, 0, 't'},
{"soft-dec", no_argument, 0, 's'},
{"testframes",no_argument, 0, 'f'},
{"nsym", required_argument, 0, 'n'},
{"mask", required_argument, 0, 'm'},
{0, 0, 0, 0}
};
o = getopt_long(argc,argv,"fhlp:cdt::sb:u:",long_opts,&opt_idx);
o = getopt_long(argc,argv,"fhlp:cdt::sb:u:m",long_opts,&opt_idx);
switch(o){
case 'l':
hbr = 0;
break;
case 'c':
complex_input = 2;
bytes_per_sample = 2;
break;
case 'd':
complex_input = 2;
bytes_per_sample = 1;
break;
case 'f':
testframe_mode = 1;
break;
case 't':
enable_stats = 1;
if(optarg != NULL){
stats_rate = atoi(optarg);
if(stats_rate == 0){
stats_rate = 8;
}
case 'c':
complex_input = 2;
bytes_per_sample = 2;
break;
case 'd':
complex_input = 2;
bytes_per_sample = 1;
break;
case 'f':
testframe_mode = 1;
break;
case 't':
enable_stats = 1;
if(optarg != NULL){
stats_rate = atoi(optarg);
if(stats_rate == 0){
stats_rate = 8;
}
break;
case 's':
soft_dec_mode = 1;
break;
case 'p':
P = atoi(optarg);
break;
case 'b':
if (optarg != NULL){
fsk_lower = atoi(optarg);
}
break;
case 'u':
if (optarg != NULL){
fsk_upper = atoi(optarg);
}
break;
case 'h':
case '?':
goto helpmsg;
break;
}
break;
case 's':
soft_dec_mode = 1;
break;
case 'p':
P = atoi(optarg);
break;
case 'b':
if (optarg != NULL) {
fsk_lower = atoi(optarg);
user_fsk_lower = 1;
}
break;
case 'u':
if (optarg != NULL){
fsk_upper = atoi(optarg);
user_fsk_upper = 1;
}
break;
case 'n':
if (optarg != NULL) {
nsym = atoi(optarg);
}
break;
case 'm':
mask = 1;
tx_tone_separation = atoi(optarg);
break;
case 'h':
case '?':
goto helpmsg;
break;
}
}
int dx = optind;
@ -158,23 +158,26 @@ int main(int argc,char *argv[]){
goto helpmsg;
}
if( (argc - dx) > 5){
if( (argc - dx) > 5) {
fprintf(stderr, "Too many arguments\n");
helpmsg:
fprintf(stderr,"usage: %s [-l] [-p P] [-s] [(-c|-d)] [-t [r]] [-f] (2|4) SampleRate SymbolRate InputModemRawFile OutputFile\n",argv[0]);
fprintf(stderr," -lP --conv=P - P specifies the rate at which symbols are down-converted before further processing\n");
fprintf(stderr," P must be divisible by the symbol size. Smaller P values will result in faster\n");
fprintf(stderr," processing but lower demodulation preformance. If no P value is specified,\n");
fprintf(stderr," P will default to it's highes possible value\n");
fprintf(stderr," -c --cs16 - The raw input file will be in complex signed 16 bit format.\n");
fprintf(stderr," -d --cu8 - The raw input file will be in complex unsigned 8 bit format.\n");
fprintf(stderr," If neither -c nor -d are used, the input should be in signed 16 bit format.\n");
fprintf(stderr," -f --testframes - Testframe mode, prints stats to stderr when a testframe is detected, if -t (JSON) \n");
fprintf(stderr," is enabled stats will be in JSON format\n");
fprintf(stderr," -t[r] --stats=[r] - Print out modem statistics to stderr in JSON.\n");
fprintf(stderr," r, if provided, sets the number of modem frames between statistic printouts.\n");
fprintf(stderr," -s --soft-dec - The output file will be in a soft-decision format, with one 32-bit float per bit.\n");
fprintf(stderr," If -s is not used, the output will be in a 1 byte-per-bit format.\n");
helpmsg:
fprintf(stderr,"usage: %s [options] (2|4) SampleRate SymbolRate InputModemRawFile OutputFile\n",argv[0]);
fprintf(stderr," -c --cs16 The raw input file will be in complex signed 16 bit format.\n");
fprintf(stderr," -d --cu8 The raw input file will be in complex unsigned 8 bit format.\n");
fprintf(stderr," If neither -c nor -d are used, the input should be in signed 16 bit format.\n");
fprintf(stderr," -f --testframes Testframe mode, prints stats to stderr when a testframe is detected, if -t (JSON) \n");
fprintf(stderr," is enabled stats will be in JSON format\n");
fprintf(stderr," -t[r] --stats=[r] Print out modem statistics to stderr in JSON.\n");
fprintf(stderr," r, if provided, sets the number of modem frames between statistic printouts.\n");
fprintf(stderr," -s --soft-dec The output file will be in a soft-decision format, with one 32-bit float per bit.\n");
fprintf(stderr," If -s is not used, the output will be in a 1 byte-per-bit format.\n");
fprintf(stderr," -p P The demod internals operate at a rate of Fs/P, default %d\n", FSK_DEFAULT_P);
fprintf(stderr," P must be divisible by the symbol rate. Smaller P values will result in faster\n");
fprintf(stderr," processing but lower demodulation performance. Default %d\n", FSK_DEFAULT_P);
fprintf(stderr," --fsk_lower freq lower limit of freq estimator (default 0 for real input, -Fs/2 for complex input)\n");
fprintf(stderr," --fsk_upper freq upper limit of freq estimator (default Fs/2)\n");
fprintf(stderr," --nsym Nsym number of symbols used for estimators. Default %d\n", FSK_DEFAULT_NSYM);
fprintf(stderr," --mask TxFreqSpace Use \"mask\" freq estimator (default is \"peak\" estimator)\n");
exit(1);
}
@ -183,10 +186,6 @@ int main(int argc,char *argv[]){
Fs = atoi(argv[dx + 1]);
Rs = atoi(argv[dx + 2]);
if( P == 0 ){
P = Fs/Rs;
}
if( (M!=2) && (M!=4) ){
fprintf(stderr,"Mode %d is not valid. Mode must be 2 or 4.\n",M);
goto helpmsg;
@ -204,20 +203,26 @@ int main(int argc,char *argv[]){
}else{
fout = fopen(argv[dx + 4],"w");
}
/* set up FSK */
if(!hbr) {
fsk = fsk_create(Fs,Rs,M,1200,400);
}
else {
fsk = fsk_create_hbr(Fs,Rs,P,M,1200,400);
if(fsk_lower> 0 && fsk_upper > fsk_lower){
fsk_set_est_limits(fsk,fsk_lower,fsk_upper);
fprintf(stderr,"Setting estimator limits to %d to %d Hz.\n",fsk_lower, fsk_upper);
}
}
/* set up FSK */
#define UNUSED 1000
fsk = fsk_create_hbr(Fs,Rs,M,P,nsym,UNUSED,tx_tone_separation);
/* set freq estimator limits */
if (!user_fsk_lower) {
if (complex_input == 1)
fsk_lower = 0;
else
fsk_lower = -Fs/2;
}
if (!user_fsk_upper) {
fsk_upper = Fs/2;
}
fprintf(stderr,"Setting estimator limits to %d to %d Hz.\n", fsk_lower, fsk_upper);
fsk_set_freq_est_limits(fsk,fsk_lower,fsk_upper);
fsk_set_freq_est_alg(fsk, mask);
if(fin==NULL || fout==NULL || fsk==NULL){
fprintf(stderr,"Couldn't open files\n");
exit(1);
@ -270,7 +275,7 @@ int main(int argc,char *argv[]){
while( fread(rawbuf,bytes_per_sample*complex_input,fsk_nin(fsk),fin) == fsk_nin(fsk) ){
/* convert input to a buffer of floats. Note scaling isn't really necessary for FSK */
if (complex_input == 1) {
if (complex_input == 1) {
/* S16 real input */
for(i=0;i<fsk_nin(fsk);i++){
modbuf[i].real = ((float)rawbuf[i])/FDMDV_SCALE;
@ -304,7 +309,7 @@ int main(int argc,char *argv[]){
testframe_detected = 0;
if (testframe_mode) {
/* attempt to find a testframe and update stats */
/* update silding window of input bits */
/* update silding window of input bits */
int errs;
for(j=0; j<fsk->Nbits; j++) {
@ -336,7 +341,7 @@ int main(int argc,char *argv[]){
biterr += errs;
if (enable_stats == 0) {
fprintf(stderr,"errs: %d FSK BER %f, bits tested %d, bit errors %d\n",
errs, ((float)biterr/(float)bitcnt),bitcnt,biterr);
errs, ((float)biterr/(float)bitcnt),bitcnt,biterr);
}
}
}
@ -352,12 +357,17 @@ int main(int argc,char *argv[]){
time_t seconds = time(NULL);
fprintf(stderr,"\"secs\": %ld, \"EbNodB\": %5.1f, \"ppm\": %4d,",seconds, stats.snr_est, (int)fsk->ppm);
fprintf(stderr," \"f1_est\":%.1f, \"f2_est\":%.1f",fsk->f_est[0],fsk->f_est[1]);
float *f_est;
if (fsk->freq_est_type)
f_est = fsk->f2_est;
else
f_est = fsk->f_est;
fprintf(stderr," \"f1_est\":%.1f, \"f2_est\":%.1f",f_est[0],f_est[1]);
/* Print 4FSK stats if in 4FSK mode */
if(fsk->mode == 4){
fprintf(stderr,", \"f3_est\":%.1f, \"f4_est\":%.1f",fsk->f_est[2],fsk->f_est[3]);
fprintf(stderr,", \"f3_est\":%.1f, \"f4_est\":%.1f",f_est[2],f_est[3]);
}
if (testframe_mode == 0) {
@ -379,7 +389,7 @@ int main(int argc,char *argv[]){
fprintf(stderr,"\"samp_fft\":[");
Ndft = fsk->Ndft/2;
for(i=0; i<Ndft; i++){
fprintf(stderr,"%f ",(fsk->fft_est)[i]);
fprintf(stderr,"%f ",(fsk->Sf)[i]);
if(i<Ndft-1) fprintf(stderr,",");
}
fprintf(stderr,"]");

Wyświetl plik

@ -27,6 +27,7 @@
#ifndef __MODEMPROBE_H
#define __MODEMPROBE_H
#include <stdint.h>
#include <stdlib.h>
#include <complex.h>

Wyświetl plik

@ -40,16 +40,19 @@ void modem_stats_open(struct MODEM_STATS *f)
/* init the FFT */
#ifndef __EMBEDDED__
for(i=0; i<2*MODEM_STATS_NSPEC; i++)
f->fft_buf[i] = 0.0;
f->fft_cfg = kiss_fft_alloc (2*MODEM_STATS_NSPEC, 0, NULL, NULL);
assert(f->fft_cfg != NULL);
#endif
}
void modem_stats_close(struct MODEM_STATS *f)
{
#ifndef __EMBEDDED__
KISS_FFT_FREE(f->fft_cfg);
#endif
}
/*---------------------------------------------------------------------------*\
@ -81,6 +84,7 @@ void modem_stats_close(struct MODEM_STATS *f)
\*---------------------------------------------------------------------------*/
#ifndef __EMBEDDED__
void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin)
{
int i,j;
@ -116,3 +120,4 @@ void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COM
mag_spec_dB[i] -= full_scale_dB;
}
}
#endif

Wyświetl plik

@ -25,17 +25,17 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __MODEM_STATS__
#define __MODEM_STATS__
#include "comp.h"
#include "kiss_fft.h"
#define MODEM_STATS_NC_MAX 20
#ifdef __cplusplus
extern "C" {
#endif
#define MODEM_STATS_NC_MAX 50
#define MODEM_STATS_NR_MAX 8
#define MODEM_STATS_ET_MAX 8
#define MODEM_STATS_EYE_IND_MAX 160
@ -46,9 +46,11 @@
struct MODEM_STATS {
int Nc;
float snr_est; /* estimated SNR of rx signal in dB (3 kHz noise BW) */
#ifndef __EMBEDDED__
COMP rx_symbols[MODEM_STATS_NR_MAX][MODEM_STATS_NC_MAX+1];
/* latest received symbols, for scatter plot */
int nr; /* number of rows in rx_symbols */
#endif
int nr; /* number of rows in rx_symbols */
int sync; /* demod sync state */
float foff; /* estimated freq offset in Hz */
float rx_timing; /* estimated optimum timing offset in samples */
@ -57,6 +59,7 @@ struct MODEM_STATS {
/* eye diagram traces */
/* Eye diagram plot -- first dim is trace number, second is the trace idx */
#ifndef __EMBEDDED__
float rx_eye[MODEM_STATS_ET_MAX][MODEM_STATS_EYE_IND_MAX];
int neyetr; /* How many eye traces are plotted */
int neyesamp; /* How many samples in the eye diagram */
@ -64,19 +67,23 @@ struct MODEM_STATS {
/* optional for FSK modems - est tone freqs */
float f_est[MODEM_STATS_MAX_F_EST];
#endif
/* Buf for FFT/waterfall */
float fft_buf[2*MODEM_STATS_NSPEC];
kiss_fft_cfg fft_cfg;
#ifndef __EMBEDDED__
float fft_buf[2*MODEM_STATS_NSPEC];
kiss_fft_cfg fft_cfg;
#endif
};
void modem_stats_open(struct MODEM_STATS *f);
void modem_stats_close(struct MODEM_STATS *f);
void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin);
#endif
#ifdef __cplusplus
}
#endif
#endif

80
utils/test.c 100644
Wyświetl plik

@ -0,0 +1,80 @@
/*
tsrc.c
David Rowe
Sat Nov 3 2012
Unit test for libresample code.
build: gcc tsrc.c -o tsrc -lm -lsamplerate
*/
#include <assert.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define N 10000 /* processing buffer size */
void display_help(void) {
fprintf(stderr, "\nusage: tsrc inputRawFile OutputRawFile OutSampleRatio [-l] [-c]\n");
fprintf(stderr, "\nUse - for stdin/stdout\n\n");
fprintf(stderr, "-l fast linear resampler\n");
fprintf(stderr, "-c complex (two channel) resampling\n\n");
}
int main(int argc, char *argv[]) {
FILE *fin, *fout;
short in_short[N], out_short[N];
float in[N], out[N];
SRC_DATA data;
int error, nin, nremaining, i, output_rate, symbol_rate, samples_per_symbol;
if (argc < 3) {
display_help();
exit(1);
}
if (strcmp(argv[1], "-") == 0)
fin = stdin;
else
fin = fopen(argv[1], "rb");
assert(fin != NULL);
if (strcmp(argv[2], "-") == 0)
fout = stdout;
else
fout = fopen(argv[2], "wb");
assert(fout != NULL);
output_rate = atof(argv[3]);
symbol_rate = atof(argv[4]);
samples_per_symbol = output_rate / symbol_rate;
char in_char;
while(fread(&in_char, 1, 1, fin) == 1) {
if(in_char == 0){
for (i=0; i<samples_per_symbol; i++){
fprintf('\0')
}
}
fwrite(out_short, sizeof(short), data.output_frames_gen*channels, fout);
if (fout == stdout) fflush(stdout);
}
//fprintf(stderr, "total_in: %d total_out: %d\n", total_in, total_out);
fclose(fout);
fclose(fin);
return 0;
}