A-Netz: Keep phase for each paging tone when played in sequence

If paging tones are played in sequence, only one tone out of four tones
is played at once. The phase of all tones are calculated as if each tone
would have been sent permanently.
This commit is contained in:
Andreas Eversberg 2016-11-13 05:51:09 +01:00
parent 3cd102c638
commit 52b1ac65f4
5 changed files with 32 additions and 22 deletions

View File

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

View File

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

View File

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

View File

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

View File

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