aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-05-19 19:11:59 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2017-05-19 19:11:59 +0200
commit76a3484c5c90cf5bcbcc26d4f14dbe5c062656c5 (patch)
tree07af5877caac137f94e436f0d018d8ba0c6f5c5d
parentc086e66b7cd3ad08b6840c8ea8a704d76171eabd (diff)
C-Netz: Make demodulation algorithm (slope or leve) slectable via option
By default (auto), the algorithm is selected, depending on sound card or SDR usage. For testing and debugging purpose, the algorithm can be forced.
-rw-r--r--src/cnetz/cnetz.c4
-rw-r--r--src/cnetz/cnetz.h2
-rw-r--r--src/cnetz/dsp.c4
-rw-r--r--src/cnetz/dsp.h2
-rw-r--r--src/cnetz/fsk_demod.c15
-rw-r--r--src/cnetz/fsk_demod.h1
-rw-r--r--src/cnetz/main.c39
7 files changed, 55 insertions, 12 deletions
diff --git a/src/cnetz/cnetz.c b/src/cnetz/cnetz.c
index 2286e46..0921723 100644
--- a/src/cnetz/cnetz.c
+++ b/src/cnetz/cnetz.c
@@ -216,7 +216,7 @@ int cnetz_init(void)
static void cnetz_go_idle(cnetz_t *cnetz);
/* Create transceiver instance and link to a list. */
-int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, int samplerate, double rx_gain, int auth, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback)
+int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int auth, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback)
{
sender_t *sender;
cnetz_t *cnetz;
@@ -290,7 +290,7 @@ int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev
#endif
/* init audio processing */
- rc = dsp_init_sender(cnetz, measure_speed, clock_speed, use_sdr);
+ rc = dsp_init_sender(cnetz, measure_speed, clock_speed, demod);
if (rc < 0) {
PDEBUG(DCNETZ, DEBUG_ERROR, "Failed to init signal processing!\n");
goto error;
diff --git a/src/cnetz/cnetz.h b/src/cnetz/cnetz.h
index b5be755..1856db4 100644
--- a/src/cnetz/cnetz.h
+++ b/src/cnetz/cnetz.h
@@ -127,7 +127,7 @@ int cnetz_channel_by_short_name(const char *short_name);
const char *chan_type_short_name(enum cnetz_chan_type chan_type);
const char *chan_type_long_name(enum cnetz_chan_type chan_type);
int cnetz_init(void);
-int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, int samplerate, double rx_gain, int auth, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback);
+int cnetz_create(int kanal, enum cnetz_chan_type chan_type, const char *audiodev, int use_sdr, enum demod_type demod, int samplerate, double rx_gain, int auth, int ms_power, int measure_speed, double clock_speed[2], int polarity, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback);
void cnetz_destroy(sender_t *sender);
void cnetz_sync_frame(cnetz_t *cnetz, double sync, int ts);
int cnetz_meldeaufruf(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c
index 00f1ed0..2c2ca4e 100644
--- a/src/cnetz/dsp.c
+++ b/src/cnetz/dsp.c
@@ -83,7 +83,7 @@ static void dsp_init_ramp(cnetz_t *cnetz)
}
/* Init transceiver instance. */
-int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], int use_sdr)
+int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], enum demod_type demod)
{
int rc = 0;
double size;
@@ -136,7 +136,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], in
/* reinit the sample rate to shrink/expand audio */
init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / 1.1, 3300.0); /* 66 <-> 60 */
- rc = fsk_fm_init(&cnetz->fsk_demod, cnetz, cnetz->sender.samplerate, (double)BITRATE / (1.0 + clock_speed[0] / 1000000.0), (use_sdr) ? FSK_DEMOD_LEVEL : FSK_DEMOD_SLOPE);
+ rc = fsk_fm_init(&cnetz->fsk_demod, cnetz, cnetz->sender.samplerate, (double)BITRATE / (1.0 + clock_speed[0] / 1000000.0), demod);
if (rc < 0)
goto error;
diff --git a/src/cnetz/dsp.h b/src/cnetz/dsp.h
index 7528e18..4e66f26 100644
--- a/src/cnetz/dsp.h
+++ b/src/cnetz/dsp.h
@@ -1,6 +1,6 @@
void dsp_init(void);
-int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], int use_sdr);
+int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], enum demod_type demod);
void dsp_cleanup_sender(cnetz_t *cnetz);
void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result);
void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count);
diff --git a/src/cnetz/fsk_demod.c b/src/cnetz/fsk_demod.c
index 99d3dc4..2f56bf0 100644
--- a/src/cnetz/fsk_demod.c
+++ b/src/cnetz/fsk_demod.c
@@ -135,7 +135,7 @@
#include "dsp.h"
#include "telegramm.h"
-int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitrate, enum demod_type demod_type)
+int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitrate, enum demod_type demod)
{
int len, half;
@@ -146,12 +146,19 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
}
fsk->cnetz = cnetz;
- fsk->demod_type = demod_type;
+ fsk->demod_type = demod;
- if (demod_type == FSK_DEMOD_SLOPE)
+ switch (demod) {
+ case FSK_DEMOD_SLOPE:
PDEBUG(DDSP, DEBUG_INFO, "Detecting level change by looking at slope (good for sound cards)\n");
- if (demod_type == FSK_DEMOD_LEVEL)
+ break;
+ case FSK_DEMOD_LEVEL:
PDEBUG(DDSP, DEBUG_INFO, "Detecting level change by looking zero crosssing (good for SDR)\n");
+ break;
+ default:
+ PDEBUG(DDSP, DEBUG_ERROR, "Wrong demod type, please fix!\n");
+ abort();
+ }
len = (int)((double)samplerate / bitrate + 0.5);
half = (int)((double)samplerate / bitrate / 2.0 + 0.5);
diff --git a/src/cnetz/fsk_demod.h b/src/cnetz/fsk_demod.h
index d8d645f..3410268 100644
--- a/src/cnetz/fsk_demod.h
+++ b/src/cnetz/fsk_demod.h
@@ -11,6 +11,7 @@ enum fsk_sync {
};
enum demod_type {
+ FSK_DEMOD_AUTO, /* auto selection of the demod type below */
FSK_DEMOD_SLOPE, /* check for highest slope (good for sound cards) */
FSK_DEMOD_LEVEL, /* check for zero crossing (good for SDR) */
};
diff --git a/src/cnetz/main.c b/src/cnetz/main.c
index 0d4ee87..b4578e8 100644
--- a/src/cnetz/main.c
+++ b/src/cnetz/main.c
@@ -47,6 +47,7 @@ int set_clock_speed = 0;
const char *flip_polarity = "auto";
int ms_power = 0; /* 0..3 */
int auth = 0;
+enum demod_type demod = FSK_DEMOD_AUTO;
void print_help(const char *arg0)
{
@@ -75,6 +76,15 @@ void print_help(const char *arg0)
printf(" Enable authentication on the base station. Since we cannot\n");
printf(" authenticate, because we don't know the secret key and the algorithm,\n");
printf(" we just accept any card. With this we get the vendor IDs of the phone.\n");
+ printf(" -D --demod auto | slope | level\n");
+ printf(" Adjust demodulation algorithm. Use 'slope' to detect a level change\n");
+ printf(" by finding the highest slope of a bit transition. It is useful, if\n");
+ printf(" the receiver drifts to 0 after a while, due to DC decoupling. This\n");
+ printf(" happens in every analog receiver and in every sound card input.\n");
+ printf(" Use 'level' to detect a level change by passing zero level. This\n");
+ printf(" requires a DC coupled signal, which is produced by SDR.\n");
+ printf(" Use 'auto' to select 'slope' for sound card input and 'level' for SDR\n");
+ printf(" input. (default = '%s')\n", (demod == FSK_DEMOD_LEVEL) ? "level" : (demod == FSK_DEMOD_SLOPE) ? "slope" : "auto");
printf("\nstation-id: Give 7 digit station-id, you don't need to enter it for every\n");
printf(" start of this program.\n");
print_hotkeys_common();
@@ -94,10 +104,11 @@ static int handle_options(int argc, char **argv)
{"flip-polarity", 1, 0, 'F'},
{"ms-power", 1, 0, 'P'},
{"authentication", 0, 0, 'A'},
+ {"demod", 1, 0, 'D'},
{0, 0, 0, 0}
};
- set_options_common("T:MS:F:N:P:AV", long_options_special);
+ set_options_common("T:MS:F:N:P:AD:", long_options_special);
while (1) {
int option_index = 0, c;
@@ -161,6 +172,19 @@ static int handle_options(int argc, char **argv)
auth = 1;
skip_args += 1;
break;
+ case 'D':
+ if (!strcasecmp(optarg, "auto"))
+ demod = FSK_DEMOD_AUTO;
+ else if (!strcasecmp(optarg, "slope"))
+ demod = FSK_DEMOD_SLOPE;
+ else if (!strcasecmp(optarg, "level"))
+ demod = FSK_DEMOD_LEVEL;
+ else {
+ fprintf(stderr, "Given demodulation type '%s' is illegal, see help!\n", optarg);
+ exit(0);
+ }
+ skip_args += 2;
+ break;
default:
opt_switch_common(c, argv[0], &skip_args);
}
@@ -299,9 +323,20 @@ int main(int argc, char *argv[])
if (use_sdr && polarity == 0)
polarity = 1; /* SDR is always positive */
+ /* demodulation algorithm */
+ if (demod == FSK_DEMOD_AUTO)
+ demod = (use_sdr) ? FSK_DEMOD_LEVEL : FSK_DEMOD_SLOPE;
+ if (demod == FSK_DEMOD_LEVEL && !use_sdr) {
+ fprintf(stderr, "*******************************************************************************\n");
+ fprintf(stderr, "I strongly suggest to use 'slope' demodulation algorithm!!!\n");
+ fprintf(stderr, "Using sound card will cause the DC levels to return to 0. Using 'level' assumes\n");
+ fprintf(stderr, "that a frequency offset never returns to 0. (Use this only with SDR.)\n");
+ fprintf(stderr, "*******************************************************************************\n");
+ }
+
/* create transceiver instance */
for (i = 0; i < num_kanal; i++) {
- rc = cnetz_create(kanal[i], chan_type[i], audiodev[i], use_sdr, samplerate, rx_gain, auth, ms_power, (i == 0) ? measure_speed : 0, clock_speed, polarity, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, loopback);
+ rc = cnetz_create(kanal[i], chan_type[i], audiodev[i], use_sdr, demod, samplerate, rx_gain, auth, ms_power, (i == 0) ? measure_speed : 0, clock_speed, polarity, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, loopback);
if (rc < 0) {
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
goto fail;