A-Netz: Option to set gain of paging tones
This commit is contained in:
@@ -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.
|
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>
|
||||||
|
|
||||||
|
<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>
|
<p>
|
||||||
Instead of transmitting all 4 tones at once, they can be transmitted after each other.
|
Instead of transmitting all 4 tones at once, they can be transmitted after each other.
|
||||||
Each tone is plays for a short time.
|
Each tone is plays for a short time.
|
||||||
After the last tone has been played, base station starts again with the first tone.
|
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.
|
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.
|
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.
|
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.
|
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.
|
||||||
|
@@ -168,7 +168,7 @@ static void anetz_timeout(struct timer *timer);
|
|||||||
static void anetz_go_idle(anetz_t *anetz);
|
static void anetz_go_idle(anetz_t *anetz);
|
||||||
|
|
||||||
/* Create transceiver instance and link to a list. */
|
/* 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;
|
anetz_t *anetz;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -194,7 +194,7 @@ int anetz_create(int kanal, const char *audiodev, int samplerate, double rx_gain
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* init audio processing */
|
/* init audio processing */
|
||||||
rc = dsp_init_sender(anetz, page_sequence);
|
rc = dsp_init_sender(anetz, page_gain, page_sequence);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
PDEBUG(DANETZ, DEBUG_ERROR, "Failed to init signal processing!\n");
|
PDEBUG(DANETZ, DEBUG_ERROR, "Failed to init signal processing!\n");
|
||||||
goto error;
|
goto error;
|
||||||
|
@@ -34,6 +34,7 @@ typedef struct anetz {
|
|||||||
int tone_count; /* how long has that tone been detected */
|
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_phaseshift256; /* how much the phase of sine wave changes per sample */
|
||||||
double tone_phase256; /* current phase */
|
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 */
|
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_phaseshift256[4];/* how much the phase of sine wave changes per sample */
|
||||||
double paging_phase256[4]; /* current phase */
|
double paging_phase256[4]; /* current phase */
|
||||||
@@ -45,7 +46,7 @@ typedef struct anetz {
|
|||||||
|
|
||||||
double anetz_kanal2freq(int kanal, int unterband);
|
double anetz_kanal2freq(int kanal, int unterband);
|
||||||
int anetz_init(void);
|
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_destroy(sender_t *sender);
|
||||||
void anetz_loss_indication(anetz_t *anetz);
|
void anetz_loss_indication(anetz_t *anetz);
|
||||||
void anetz_receive_tone(anetz_t *anetz, int bit);
|
void anetz_receive_tone(anetz_t *anetz, int bit);
|
||||||
|
@@ -37,8 +37,6 @@
|
|||||||
/* signaling */
|
/* signaling */
|
||||||
#define BANDWIDTH 15000.0 /* maximum bandwidth */
|
#define BANDWIDTH 15000.0 /* maximum bandwidth */
|
||||||
#define TX_PEAK_TONE 8192.0 /* peak amplitude for all tones */
|
#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 */
|
#define CHUNK_DURATION 0.010 /* 10 ms */
|
||||||
|
|
||||||
// FIXME: how long until we detect a tone?
|
// FIXME: how long until we detect a tone?
|
||||||
@@ -56,7 +54,6 @@ static double fsk_tones[2] = {
|
|||||||
|
|
||||||
/* table for fast sine generation */
|
/* table for fast sine generation */
|
||||||
int dsp_sine_tone[256];
|
int dsp_sine_tone[256];
|
||||||
int dsp_sine_page[256];
|
|
||||||
|
|
||||||
/* global init for audio processing */
|
/* global init for audio processing */
|
||||||
void dsp_init(void)
|
void dsp_init(void)
|
||||||
@@ -68,22 +65,16 @@ void dsp_init(void)
|
|||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
s = sin((double)i / 256.0 * 2.0 * PI);
|
s = sin((double)i / 256.0 * 2.0 * PI);
|
||||||
dsp_sine_tone[i] = (int)(s * TX_PEAK_TONE);
|
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) {
|
if (TX_PEAK_TONE > 32767.0) {
|
||||||
fprintf(stderr, "TX_PEAK_TONE definition too high, please fix!\n");
|
fprintf(stderr, "TX_PEAK_TONE definition too high, please fix!\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if (TX_PEAK_PAGE > 32767.0) {
|
|
||||||
fprintf(stderr, "TX_PEAK_PAGE definition too high, please fix!\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init transceiver instance. */
|
/* 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;
|
int16_t *spl;
|
||||||
double coeff;
|
double coeff;
|
||||||
@@ -96,6 +87,11 @@ int dsp_init_sender(anetz_t *anetz, int page_sequence)
|
|||||||
anetz->sender.bandwidth = BANDWIDTH;
|
anetz->sender.bandwidth = BANDWIDTH;
|
||||||
anetz->sender.sample_deviation = 11000.0 / (double)TX_PEAK_TONE;
|
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;
|
anetz->page_sequence = page_sequence;
|
||||||
|
|
||||||
audio_init_loss(&anetz->sender.loss, LOSS_INTERVAL, anetz->sender.loss_volume, LOSS_TIME);
|
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.
|
/* 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)
|
static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length)
|
||||||
{
|
{
|
||||||
double phaseshift[4], phase[4];
|
double phaseshift[4], phase[4];
|
||||||
int i;
|
int i;
|
||||||
int32_t sample;
|
double sample;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
phaseshift[i] = anetz->paging_phaseshift256[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++) {
|
for (i = 0; i < length; i++) {
|
||||||
sample = (int32_t)dsp_sine_page[((uint8_t)phase[0]) & 0xff]
|
sample = (int32_t)dsp_sine_tone[((uint8_t)phase[0]) & 0xff]
|
||||||
+ (int32_t)dsp_sine_page[((uint8_t)phase[1]) & 0xff]
|
+ (int32_t)dsp_sine_tone[((uint8_t)phase[1]) & 0xff]
|
||||||
+ (int32_t)dsp_sine_page[((uint8_t)phase[2]) & 0xff]
|
+ (int32_t)dsp_sine_tone[((uint8_t)phase[2]) & 0xff]
|
||||||
+ (int32_t)dsp_sine_page[((uint8_t)phase[3]) & 0xff];
|
+ (int32_t)dsp_sine_tone[((uint8_t)phase[3]) & 0xff];
|
||||||
*samples++ = sample >> 2;
|
*samples++ = sample / 4.0 * anetz->page_gain;
|
||||||
phase[0] += phaseshift[0];
|
phase[0] += phaseshift[0];
|
||||||
phase[1] += phaseshift[1];
|
phase[1] += phaseshift[1];
|
||||||
phase[2] += phaseshift[2];
|
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
|
/* Generate audio stream of 4 sequenced paging tones. Keep phase for next call
|
||||||
* of function.
|
* 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:
|
* Click removal when changing tones that have individual phase:
|
||||||
* When tone changes to next tone, a transition of 2ms is performed. The last
|
* 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) {
|
while (length) {
|
||||||
/* use tone, but during transition of tones, keep phase 0 degrees (high level) until next tone reaches 0 degrees (high level) */
|
/* use tone, but during transition of tones, keep phase 0 degrees (high level) until next tone reaches 0 degrees (high level) */
|
||||||
if (!transition)
|
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 {
|
else {
|
||||||
/* fade between old an new tone */
|
/* fade between old an new tone */
|
||||||
*samples++
|
*samples++
|
||||||
= (double)dsp_sine_page[((uint8_t)phase[(tone - 1) & 3]) & 0xff] * (double)(transition - 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_page[((uint8_t)phase[tone]) & 0xff] * (double)count / (double)transition / 2.0;
|
+ (double)dsp_sine_tone[((uint8_t)phase[tone]) & 0xff] * (double)count / (double)transition / 2.0 * anetz->page_gain;
|
||||||
}
|
}
|
||||||
phase[0] += phaseshift[0];
|
phase[0] += phaseshift[0];
|
||||||
phase[1] += phaseshift[1];
|
phase[1] += phaseshift[1];
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
void dsp_init(void);
|
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_cleanup_sender(anetz_t *anetz);
|
||||||
void dsp_set_paging(anetz_t *anetz, double *freq);
|
void dsp_set_paging(anetz_t *anetz, double *freq);
|
||||||
void anetz_set_dsp_mode(anetz_t *anetz, enum dsp_mode mode, int detect_reset);
|
void anetz_set_dsp_mode(anetz_t *anetz, enum dsp_mode mode, int detect_reset);
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
#include "../common/main.h"
|
#include "../common/main.h"
|
||||||
#include "../common/debug.h"
|
#include "../common/debug.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
@@ -35,17 +36,21 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
/* settings */
|
/* settings */
|
||||||
|
double page_gain = 1;
|
||||||
int page_sequence = 0;
|
int page_sequence = 0;
|
||||||
double lossdetect = 0;
|
double lossdetect = 0;
|
||||||
|
|
||||||
void print_help(const char *arg0)
|
void print_help(const char *arg0)
|
||||||
{
|
{
|
||||||
print_help_common(arg0, "");
|
print_help_common(arg0, "[-V 12] ");
|
||||||
/* - - */
|
/* - - */
|
||||||
printf(" -G --geo <lat>,<lon>\n");
|
printf(" -G --geo <lat>,<lon>\n");
|
||||||
printf(" Give your coordinates of your location, to find closest base station.\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(" (e.g. '--geo 51.186959,7.080194') Or use '--geo list' to get a list of\n");
|
||||||
printf(" all base station locations.\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(" -P --page-sequence 0 | <ms>\n");
|
||||||
printf(" Cycle paging tones, rather than sending simultaniously. Try 100.\n");
|
printf(" Cycle paging tones, rather than sending simultaniously. Try 100.\n");
|
||||||
printf(" (default = '%d')\n", page_sequence);
|
printf(" (default = '%d')\n", page_sequence);
|
||||||
@@ -61,15 +66,17 @@ static int handle_options(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int skip_args = 0;
|
int skip_args = 0;
|
||||||
char *p;
|
char *p;
|
||||||
|
double gain_db;
|
||||||
|
|
||||||
static struct option long_options_special[] = {
|
static struct option long_options_special[] = {
|
||||||
{"geo", 1, 0, 'G'},
|
{"geo", 1, 0, 'G'},
|
||||||
|
{"page-gain", 1, 0, 'V'},
|
||||||
{"page-sequence", 1, 0, 'P'},
|
{"page-sequence", 1, 0, 'P'},
|
||||||
{"loss", 1, 0, 'L'},
|
{"loss", 1, 0, 'L'},
|
||||||
{0, 0, 0, 0}
|
{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) {
|
while (1) {
|
||||||
int option_index = 0, c;
|
int option_index = 0, c;
|
||||||
@@ -92,6 +99,11 @@ static int handle_options(int argc, char **argv)
|
|||||||
fprintf(stderr, "Invalid geo parameter\n");
|
fprintf(stderr, "Invalid geo parameter\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
|
case 'V':
|
||||||
|
gain_db = atof(optarg);
|
||||||
|
page_gain = pow(10, gain_db / 20.0);
|
||||||
|
skip_args += 2;
|
||||||
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
page_sequence = atoi(optarg);
|
page_sequence = atoi(optarg);
|
||||||
skip_args += 2;
|
skip_args += 2;
|
||||||
@@ -171,7 +183,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* create transceiver instance */
|
/* create transceiver instance */
|
||||||
for (i = 0; i < num_kanal; i++) {
|
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) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
Reference in New Issue
Block a user