diff --git a/src/anetz/anetz.c b/src/anetz/anetz.c index eae8beb..6f04c63 100644 --- a/src/anetz/anetz.c +++ b/src/anetz/anetz.c @@ -137,7 +137,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 *sounddev, int samplerate, int cross_channels, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_wave, const char *read_wave, int loopback, double loss_volume) +int anetz_create(int kanal, const char *sounddev, int samplerate, int cross_channels, double rx_gain, int page_sequence, int pre_emphasis, int de_emphasis, const char *write_wave, const char *read_wave, int loopback, double loss_volume) { anetz_t *anetz; int rc; @@ -163,7 +163,7 @@ int anetz_create(int kanal, const char *sounddev, int samplerate, int cross_chan } /* init audio processing */ - rc = dsp_init_sender(anetz); + rc = dsp_init_sender(anetz, page_sequence); if (rc < 0) { PDEBUG(DANETZ, DEBUG_ERROR, "Failed to init signal processing!\n"); goto error; @@ -372,6 +372,8 @@ inval: } PDEBUG(DANETZ, DEBUG_INFO, "Call to mobile station, paging with tones: %.1f %.1f %.1f %.1f\n", freq[0], freq[1], freq[2], freq[3]); + if (anetz->page_sequence) + PDEBUG(DANETZ, DEBUG_NOTICE, "Sending paging tones in sequence. 'click' sounds may appear, because the phase of each individual tone might be different.\n"); /* 4. trying to page mobile station */ anetz->callref = callref; diff --git a/src/anetz/anetz.h b/src/anetz/anetz.h index f1a64e7..50376c0 100644 --- a/src/anetz/anetz.h +++ b/src/anetz/anetz.h @@ -33,6 +33,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 */ + 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 */ int paging_tone; /* current tone (0..3) in sequenced mode */ @@ -42,7 +43,7 @@ typedef struct anetz { double anetz_kanal2freq(int kanal, int unterband); int anetz_init(void); -int anetz_create(int kanal, const char *sounddev, int samplerate, int cross_channels, double rx_gain, int pre_emphasis, int de_emphasis, const char *write_wave, const char *read_wave, int loopback, double loss_volume); +int anetz_create(int kanal, const char *sounddev, int samplerate, int cross_channels, double rx_gain, int page_sequence, int pre_emphasis, int de_emphasis, const char *write_wave, const char *read_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 298ed87..014b10c 100644 --- a/src/anetz/dsp.c +++ b/src/anetz/dsp.c @@ -48,8 +48,6 @@ #define LOSS_INTERVAL 100 /* filter steps (chunk durations) for one second interval */ #define LOSS_TIME 12 /* duration of signal loss before release */ -extern int page_sequence; - /* two signaling tones */ static double fsk_tones[2] = { 2280.0, @@ -84,7 +82,7 @@ void dsp_init(void) } /* Init transceiver instance. */ -int dsp_init_sender(anetz_t *anetz) +int dsp_init_sender(anetz_t *anetz, int page_sequence) { int16_t *spl; double coeff; @@ -93,6 +91,8 @@ int dsp_init_sender(anetz_t *anetz) PDEBUG(DDSP, DEBUG_DEBUG, "Init DSP for 'Sender'.\n"); + anetz->page_sequence = page_sequence; + audio_init_loss(&anetz->sender.loss, LOSS_INTERVAL, anetz->sender.loss_volume, LOSS_TIME); anetz->samples_per_chunk = anetz->sender.samplerate * CHUNK_DURATION; @@ -243,7 +243,7 @@ void dsp_set_paging(anetz_t *anetz, double *freq) * Use TX_PEAK_PAGE for all tones, which gives peak of (TX_PEAK_PAGE / 4) for each individual tone. */ static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) { - double phaseshift[5], phase[5]; + double phaseshift[4], phase[4]; int i; int32_t sample; @@ -277,31 +277,38 @@ static void fsk_paging_tone(anetz_t *anetz, int16_t *samples, int length) * Use TX_PEAK_PAGE / 2 for each tone, that is twice as much peak per tone. */ static void fsk_paging_tone_sequence(anetz_t *anetz, int16_t *samples, int length, int numspl) { - double phaseshift, phase; + double phaseshift[4], phase[4]; + int i; int tone, count; - phase = anetz->tone_phase256; + for (i = 0; i < 4; i++) { + phaseshift[i] = anetz->paging_phaseshift256[i]; + phase[i] = anetz->paging_phase256[i]; + } tone = anetz->paging_tone; count = anetz->paging_count; -next_tone: - phaseshift = anetz->paging_phaseshift256[tone]; - while (length) { - *samples++ = dsp_sine_page[((uint8_t)phase) & 0xff] >> 1; - phase += phaseshift; - if (phase >= 256) - phase -= 256; + *samples++ = dsp_sine_page[((uint8_t)phase[tone]) & 0xff] >> 1; + phase[0] += phaseshift[0]; + phase[1] += phaseshift[1]; + phase[2] += phaseshift[2]; + phase[3] += phaseshift[3]; + if (phase[0] >= 256) phase[0] -= 256; + if (phase[1] >= 256) phase[1] -= 256; + if (phase[2] >= 256) phase[2] -= 256; + if (phase[3] >= 256) phase[3] -= 256; if (++count == numspl) { count = 0; if (++tone == 4) tone = 0; - goto next_tone; } length--; } - anetz->tone_phase256 = phase; + for (i = 0; i < 4; i++) { + anetz->paging_phase256[i] = phase[i]; + } anetz->paging_tone = tone; anetz->paging_count = count; } @@ -341,8 +348,8 @@ void sender_send(sender_t *sender, int16_t *samples, int length) fsk_tone(anetz, samples, length); break; case DSP_MODE_PAGING: - if (page_sequence) - fsk_paging_tone_sequence(anetz, samples, length, page_sequence * anetz->sender.samplerate / 1000); + if (anetz->page_sequence) + fsk_paging_tone_sequence(anetz, samples, length, anetz->page_sequence * anetz->sender.samplerate / 1000); else fsk_paging_tone(anetz, samples, length); break; diff --git a/src/anetz/dsp.h b/src/anetz/dsp.h index 890fee4..1bc4fca 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 dsp_init_sender(anetz_t *anetz, 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); diff --git a/src/anetz/main.c b/src/anetz/main.c index 76c56aa..681196c 100644 --- a/src/anetz/main.c +++ b/src/anetz/main.c @@ -169,7 +169,7 @@ int main(int argc, char *argv[]) /* create transceiver instance */ for (i = 0; i < num_kanal; i++) { - rc = anetz_create(kanal[i], sounddev[i], samplerate, cross_channels, rx_gain, do_pre_emphasis, do_de_emphasis, write_wave, read_wave, loopback, lossdetect / 100.0); + rc = anetz_create(kanal[i], sounddev[i], samplerate, cross_channels, rx_gain, page_sequence, do_pre_emphasis, do_de_emphasis, write_wave, read_wave, loopback, lossdetect / 100.0); if (rc < 0) { fprintf(stderr, "Failed to create \"Sender\" instance. Quitting!\n"); goto fail;