kopia lustrzana https://github.com/projecthorus/radiosonde_auto_rx
Rebase fsk_demod.
rodzic
35746558c0
commit
2bdae57774
|
@ -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.
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
1145
utils/fsk.c
1145
utils/fsk.c
Plik diff jest za duży
Load Diff
47
utils/fsk.h
47
utils/fsk.h
|
@ -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
|
||||
|
|
|
@ -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,"]");
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#ifndef __MODEMPROBE_H
|
||||
#define __MODEMPROBE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <complex.h>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
Ładowanie…
Reference in New Issue