diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2017-01-08 11:22:24 +0100 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2017-01-08 11:22:24 +0100 |
commit | 0b3b65d9f10e4e7d12fcef2685e24cd8c5f2b18b (patch) | |
tree | e249dec5786a435e36c01f56daff530c564ebb4d /src | |
parent | 12a31f1b051e1afd020747448b7583d5f81cd092 (diff) |
A-Netz: Option to set gain of paging tones
Diffstat (limited to 'src')
-rw-r--r-- | src/anetz/anetz.c | 4 | ||||
-rw-r--r-- | src/anetz/anetz.h | 3 | ||||
-rw-r--r-- | src/anetz/dsp.c | 38 | ||||
-rw-r--r-- | src/anetz/dsp.h | 2 | ||||
-rw-r--r-- | src/anetz/main.c | 18 |
5 files changed, 37 insertions, 28 deletions
diff --git a/src/anetz/anetz.c b/src/anetz/anetz.c index 539edf7..77493f7 100644 --- a/src/anetz/anetz.c +++ b/src/anetz/anetz.c @@ -168,7 +168,7 @@ static void anetz_timeout(struct timer *timer); static void anetz_go_idle(anetz_t *anetz); /* Create transceiver instance and link to a list. */ -int anetz_create(int kanal, const char *audiodev, int samplerate, double rx_gain, int page_sequence, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback, double loss_volume) +int anetz_create(int kanal, const char *audiodev, int samplerate, double rx_gain, double page_gain, int page_sequence, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback, double loss_volume) { anetz_t *anetz; int rc; @@ -194,7 +194,7 @@ int anetz_create(int kanal, const char *audiodev, int samplerate, double rx_gain } /* init audio processing */ - rc = dsp_init_sender(anetz, page_sequence); + rc = dsp_init_sender(anetz, page_gain, page_sequence); if (rc < 0) { PDEBUG(DANETZ, DEBUG_ERROR, "Failed to init signal processing!\n"); goto error; diff --git a/src/anetz/anetz.h b/src/anetz/anetz.h index ed5c4d5..a464db3 100644 --- a/src/anetz/anetz.h +++ b/src/anetz/anetz.h @@ -34,6 +34,7 @@ typedef struct anetz { int tone_count; /* how long has that tone been detected */ double tone_phaseshift256; /* how much the phase of sine wave changes per sample */ double tone_phase256; /* current phase */ + double page_gain; /* factor to raise the paging tones */ int page_sequence; /* if set, use paging tones in sequence rather than parallel */ double paging_phaseshift256[4];/* how much the phase of sine wave changes per sample */ double paging_phase256[4]; /* current phase */ @@ -45,7 +46,7 @@ typedef struct anetz { double anetz_kanal2freq(int kanal, int unterband); int anetz_init(void); -int anetz_create(int kanal, const char *audiodev, int samplerate, double rx_gain, int page_sequence, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback, double loss_volume); +int anetz_create(int kanal, const char *audiodev, int samplerate, double rx_gain, double page_gain, int page_sequence, int pre_emphasis, int de_emphasis, const char *write_rx_wave, const char *write_tx_wave, const char *read_rx_wave, int loopback, double loss_volume); void anetz_destroy(sender_t *sender); void anetz_loss_indication(anetz_t *anetz); void anetz_receive_tone(anetz_t *anetz, int bit); diff --git a/src/anetz/dsp.c b/src/anetz/dsp.c index e47f7f2..ee5bdd7 100644 --- a/src/anetz/dsp.c +++ b/src/anetz/dsp.c @@ -37,8 +37,6 @@ /* signaling */ #define BANDWIDTH 15000.0 /* maximum bandwidth */ #define TX_PEAK_TONE 8192.0 /* peak amplitude for all tones */ -#warning FIXME: only with emphasis, use seperate option for volume, override by sdr -#define TX_PEAK_PAGE 32766.0 /* peak amplitude paging tone */ #define CHUNK_DURATION 0.010 /* 10 ms */ // FIXME: how long until we detect a tone? @@ -56,7 +54,6 @@ static double fsk_tones[2] = { /* table for fast sine generation */ int dsp_sine_tone[256]; -int dsp_sine_page[256]; /* global init for audio processing */ void dsp_init(void) @@ -68,22 +65,16 @@ void dsp_init(void) for (i = 0; i < 256; i++) { s = sin((double)i / 256.0 * 2.0 * PI); dsp_sine_tone[i] = (int)(s * TX_PEAK_TONE); - s = cos((double)i / 256.0 * 2.0 * PI); - dsp_sine_page[i] = (int)(s * TX_PEAK_PAGE); } if (TX_PEAK_TONE > 32767.0) { fprintf(stderr, "TX_PEAK_TONE definition too high, please fix!\n"); abort(); } - if (TX_PEAK_PAGE > 32767.0) { - fprintf(stderr, "TX_PEAK_PAGE definition too high, please fix!\n"); - abort(); - } } /* Init transceiver instance. */ -int dsp_init_sender(anetz_t *anetz, int page_sequence) +int dsp_init_sender(anetz_t *anetz, double page_gain, int page_sequence) { int16_t *spl; double coeff; @@ -96,6 +87,11 @@ int dsp_init_sender(anetz_t *anetz, int page_sequence) anetz->sender.bandwidth = BANDWIDTH; anetz->sender.sample_deviation = 11000.0 / (double)TX_PEAK_TONE; + anetz->page_gain = page_gain; + if (page_gain * TX_PEAK_TONE > 32767.0) { + page_gain = 32767.0 / TX_PEAK_TONE; + PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "Highest possible gain of paging tones is %.1f dB.\n", log10(page_gain) * 20); + } anetz->page_sequence = page_sequence; audio_init_loss(&anetz->sender.loss, LOSS_INTERVAL, anetz->sender.loss_volume, LOSS_TIME); @@ -245,12 +241,12 @@ void dsp_set_paging(anetz_t *anetz, double *freq) } /* Generate audio stream of 4 simultanious paging tones. Keep phase for next call of function. - * Use TX_PEAK_PAGE for all tones, which gives peak of (TX_PEAK_PAGE / 4) for each individual tone. */ + * Use TX_PEAK_TONE*page_gain for all tones, which gives peak of 1/4th for each individual tone. */ static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) { double phaseshift[4], phase[4]; int i; - int32_t sample; + double sample; for (i = 0; i < 4; i++) { phaseshift[i] = anetz->paging_phaseshift256[i]; @@ -258,11 +254,11 @@ static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) } for (i = 0; i < length; i++) { - sample = (int32_t)dsp_sine_page[((uint8_t)phase[0]) & 0xff] - + (int32_t)dsp_sine_page[((uint8_t)phase[1]) & 0xff] - + (int32_t)dsp_sine_page[((uint8_t)phase[2]) & 0xff] - + (int32_t)dsp_sine_page[((uint8_t)phase[3]) & 0xff]; - *samples++ = sample >> 2; + sample = (int32_t)dsp_sine_tone[((uint8_t)phase[0]) & 0xff] + + (int32_t)dsp_sine_tone[((uint8_t)phase[1]) & 0xff] + + (int32_t)dsp_sine_tone[((uint8_t)phase[2]) & 0xff] + + (int32_t)dsp_sine_tone[((uint8_t)phase[3]) & 0xff]; + *samples++ = sample / 4.0 * anetz->page_gain; phase[0] += phaseshift[0]; phase[1] += phaseshift[1]; phase[2] += phaseshift[2]; @@ -281,7 +277,7 @@ static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) /* Generate audio stream of 4 sequenced paging tones. Keep phase for next call * of function. * - * Use TX_PEAK_PAGE / 2 for each tone, that is twice as much peak per tone. + * Use TX_PEAK_PAGE for each tone, that is four times higher per tone. * * Click removal when changing tones that have individual phase: * When tone changes to next tone, a transition of 2ms is performed. The last @@ -304,12 +300,12 @@ static void fsk_paging_tone_sequence(anetz_t *anetz, int16_t *samples, int lengt while (length) { /* use tone, but during transition of tones, keep phase 0 degrees (high level) until next tone reaches 0 degrees (high level) */ if (!transition) - *samples++ = dsp_sine_page[((uint8_t)phase[tone]) & 0xff] >> 1; + *samples++ = dsp_sine_tone[((uint8_t)phase[tone]) & 0xff] * anetz->page_gain; else { /* fade between old an new tone */ *samples++ - = (double)dsp_sine_page[((uint8_t)phase[(tone - 1) & 3]) & 0xff] * (double)(transition - count) / (double)transition / 2.0 - + (double)dsp_sine_page[((uint8_t)phase[tone]) & 0xff] * (double)count / (double)transition / 2.0; + = (double)dsp_sine_tone[((uint8_t)phase[(tone - 1) & 3]) & 0xff] * (double)(transition - count) / (double)transition / 2.0 * anetz->page_gain + + (double)dsp_sine_tone[((uint8_t)phase[tone]) & 0xff] * (double)count / (double)transition / 2.0 * anetz->page_gain; } phase[0] += phaseshift[0]; phase[1] += phaseshift[1]; diff --git a/src/anetz/dsp.h b/src/anetz/dsp.h index 3f78028..aff93a9 100644 --- a/src/anetz/dsp.h +++ b/src/anetz/dsp.h @@ -1,6 +1,6 @@ void dsp_init(void); -int dsp_init_sender(anetz_t *anetz, int page_seqeuence); +int dsp_init_sender(anetz_t *anetz, double page_gain, int page_seqeuence); void dsp_cleanup_sender(anetz_t *anetz); void dsp_set_paging(anetz_t *anetz, double *freq); void anetz_set_dsp_mode(anetz_t *anetz, enum dsp_mode mode, int detect_reset); diff --git a/src/anetz/main.c b/src/anetz/main.c index d13d5be..a6fcfcb 100644 --- a/src/anetz/main.c +++ b/src/anetz/main.c @@ -22,6 +22,7 @@ #include <getopt.h> #include <stdlib.h> #include <string.h> +#include <math.h> #include "../common/main.h" #include "../common/debug.h" #include "../common/timer.h" @@ -35,17 +36,21 @@ #include "image.h" /* settings */ +double page_gain = 1; int page_sequence = 0; double lossdetect = 0; void print_help(const char *arg0) { - print_help_common(arg0, ""); + print_help_common(arg0, "[-V 12] "); /* - - */ printf(" -G --geo <lat>,<lon>\n"); printf(" Give your coordinates of your location, to find closest base station.\n"); printf(" (e.g. '--geo 51.186959,7.080194') Or use '--geo list' to get a list of\n"); printf(" all base station locations.\n"); + printf(" -V --page-gain <dB>\n"); + printf(" Raise the gain of paging tones to compensate loss due to pre-emphasis\n"); + printf(" of the transmitter. (If you can't disable it.)\n"); printf(" -P --page-sequence 0 | <ms>\n"); printf(" Cycle paging tones, rather than sending simultaniously. Try 100.\n"); printf(" (default = '%d')\n", page_sequence); @@ -61,15 +66,17 @@ static int handle_options(int argc, char **argv) { int skip_args = 0; char *p; + double gain_db; static struct option long_options_special[] = { {"geo", 1, 0, 'G'}, + {"page-gain", 1, 0, 'V'}, {"page-sequence", 1, 0, 'P'}, {"loss", 1, 0, 'L'}, {0, 0, 0, 0} }; - set_options_common("G:P:L:", long_options_special); + set_options_common("G:V:P:L:", long_options_special); while (1) { int option_index = 0, c; @@ -92,6 +99,11 @@ static int handle_options(int argc, char **argv) fprintf(stderr, "Invalid geo parameter\n"); exit(0); break; + case 'V': + gain_db = atof(optarg); + page_gain = pow(10, gain_db / 20.0); + skip_args += 2; + break; case 'P': page_sequence = atoi(optarg); skip_args += 2; @@ -171,7 +183,7 @@ int main(int argc, char *argv[]) /* create transceiver instance */ for (i = 0; i < num_kanal; i++) { - rc = anetz_create(kanal[i], audiodev[i], samplerate, rx_gain, page_sequence, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, loopback, lossdetect / 100.0); + rc = anetz_create(kanal[i], audiodev[i], samplerate, rx_gain, page_gain, page_sequence, do_pre_emphasis, do_de_emphasis, write_rx_wave, write_tx_wave, read_rx_wave, loopback, lossdetect / 100.0); if (rc < 0) { fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n"); goto fail; |