A-Netz: Option to set gain of paging tones

This commit is contained in:
Andreas Eversberg 2017-01-08 11:22:24 +01:00
parent d28467c125
commit bf0abd627d
6 changed files with 46 additions and 29 deletions

View File

@ -287,12 +287,20 @@ If the phone does not indicate an incoming call, increase the volume of the tran
Also be sure that you are actually dialing the right number, so the base station generates the correct paging tones for your phone.
</p>
<p>
As there is no emphasis, a transmitter with pre-emphasis will drastically lower the paging tones.
If you cannot disable pre-emphasis on the transmitter, try to raise the gain of the paging tones.
Add command "-V 12" to increase gain.
The frequency deviation of all 4 tones should be around 11 kHz.
</p>
<p>
Instead of transmitting all 4 tones at once, they can be transmitted after each other.
Each tone is plays for a short time.
After the last tone has been played, base station starts again with the first tone.
My phone also responds to a call, even if the tones cycle rather than sent simultaneously.
In this case the deviation level of each tone is two times higher (+6 dB). (The level transmitted is two times lower (-6 dB) than the peak level of 4 simultaneous tones. This may help transmitters with deviation limiters to make the phone ring.)
In this case the deviation level of each tone is four times higher (+12 dB).
This may help transmitters with deviation limiters to make the phone ring.)
Add command line option "-P 100" to send each tone for 100 milliseconds.
Try something between 50-200 milliseconds, if the phone still doesn't ring.
Be sure to check: Does your transmitter has enough frequency deviation (15 KHz is suggested)? Do you really send the correct number of your phone, check the frequencies of your phone and use "-D 0" option to see what 4 frequencies the base station actually transmits.

View File

@ -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;

View File

@ -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);

View File

@ -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];

View File

@ -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);

View File

@ -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;