diff --git a/src/cnetz/cnetz.c b/src/cnetz/cnetz.c index df0968b..c97af0d 100644 --- a/src/cnetz/cnetz.c +++ b/src/cnetz/cnetz.c @@ -377,21 +377,23 @@ int cnetz_create(const char *kanal, enum cnetz_chan_type chan_type, const char * goto error; /* go into idle state */ - cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK); - cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_OGK, 0); + if (chan_type == CHAN_TYPE_OGK || chan_type == CHAN_TYPE_OGK_SPK) + cnetz_set_dsp_mode(cnetz, DSP_MODE_OGK); + else + cnetz_set_dsp_mode(cnetz, DSP_MODE_OFF); cnetz_go_idle(cnetz); #ifdef DEBUG_SPK transaction_t *trans = create_transaction(cnetz, TRANS_DS, 2, 2, 22002, -1, -1); trans->mo_call = 1; - cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 2); + cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31); #else /* create transaction for speech channel loopback */ if (loopback && chan_type == CHAN_TYPE_SPK) { transaction_t *trans = create_transaction(cnetz, TRANS_VHQ_K, 2, 2, 22002, -1, -1); trans->mo_call = 1; cnetz_set_dsp_mode(cnetz, DSP_MODE_SPK_K); - cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, 0); + cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_K, (cnetz->sched_ts + 1) & 31); } #endif @@ -509,10 +511,11 @@ void cnetz_go_idle(cnetz_t *cnetz) /* set scheduler to OgK or turn off SpK */ if (cnetz->dsp_mode == DSP_MODE_SPK_K || cnetz->dsp_mode == DSP_MODE_SPK_V) { - /* go idle after next frame/slot */ - cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, 1); + /* switch next frame after distributed signaling boundary (mutliple of 8 slots) */ + cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 8) & 24); } else { - cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, 0); + /* switch next frame */ + cnetz_set_sched_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF, (cnetz->sched_ts + 1) & 31); cnetz_set_dsp_mode(cnetz, (atoi(cnetz->sender.kanal) == CNETZ_OGK_KANAL) ? DSP_MODE_OGK : DSP_MODE_OFF); } @@ -533,7 +536,7 @@ static void cnetz_release(transaction_t *trans, uint8_t cause) trans_new_state(trans, (trans->cnetz->dsp_mode == DSP_MODE_OGK) ? TRANS_VA : TRANS_AF); trans->repeat = 0; trans->release_cause = cause; - trans->cnetz->sched_switch_mode = 0; + trans->cnetz->sched_dsp_mode_ts = -1; timer_stop(&trans->timer); } @@ -1068,7 +1071,7 @@ vak: /* change state to busy */ cnetz_new_state(spk, CNETZ_BUSY); /* schedule switching two slots ahead */ - cnetz_set_sched_dsp_mode(spk, DSP_MODE_SPK_K, 2); + cnetz_set_sched_dsp_mode(spk, DSP_MODE_SPK_K, (cnetz->sched_ts + 2) & 31); /* relink */ unlink_transaction(trans); link_transaction(trans, spk); @@ -1384,7 +1387,7 @@ no_auth: /* next sub frame */ trans_new_state(trans, TRANS_VHQ_V); trans->repeat = 0; - cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1); + cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, (cnetz->sched_ts + 1) & 31); #ifndef DEBUG_SPK timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */ #endif @@ -1401,7 +1404,7 @@ no_auth: /* next sub frame */ trans_new_state(trans, TRANS_VHQ_V); trans->repeat = 0; - cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, 1); + cnetz_set_sched_dsp_mode(cnetz, DSP_MODE_SPK_V, (cnetz->sched_ts + 1) & 31); timer_start(&trans->timer, 0.075 + 0.6 * F_VHQ); /* one slot + F_VHQ frames */ } break; diff --git a/src/cnetz/cnetz.h b/src/cnetz/cnetz.h index 88e621f..f8b0e1a 100644 --- a/src/cnetz/cnetz.h +++ b/src/cnetz/cnetz.h @@ -94,8 +94,8 @@ struct cnetz { int sched_ts; /* current time slot */ int sched_last_ts; /* last timeslot we transmitted, to sync time of the receiver */ int sched_r_m; /* Rufblock (0) / Meldeblock (1) */ - int sched_switch_mode; /* counts slots until mode is switched */ - enum dsp_mode sched_dsp_mode; /* what mode shall be switched to */ + enum dsp_mode sched_dsp_mode; /* what mode shall be switched to */ + int sched_dsp_mode_ts; /* time slot when to switch mode (-1 = don't switch) */ /* dsp states */ enum dsp_mode dsp_mode; /* current mode: audio, "Telegramm", .... */ diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c index 91f967c..ecf26a4 100644 --- a/src/cnetz/dsp.c +++ b/src/cnetz/dsp.c @@ -54,6 +54,27 @@ scrambler_t scrambler_test_scrambler1; scrambler_t scrambler_test_scrambler2; #endif +const char *cnetz_dsp_mode_name(enum dsp_mode mode) +{ + static char invalid[16]; + + switch (mode) { + case DSP_SCHED_NONE: + return "SCHED_NONE"; + case DSP_MODE_OFF: + return "OFF"; + case DSP_MODE_OGK: + return "OGK"; + case DSP_MODE_SPK_K: + return "SPK_K"; + case DSP_MODE_SPK_V: + return "SPK_V"; + } + + sprintf(invalid, "invalid(%d)", mode); + return invalid; +} + static sample_t ramp_up[256], ramp_down[256]; void dsp_init(void) @@ -166,6 +187,8 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en scrambler_setup(&scrambler_test_scrambler2, cnetz->sender.samplerate); #endif + cnetz->sched_dsp_mode_ts = -1; + return 0; error: @@ -636,10 +659,11 @@ again: } /* switch to speech channel */ - if (cnetz->sched_switch_mode && cnetz->sched_r_m == 0) { - if (--cnetz->sched_switch_mode == 0) { + if (cnetz->sched_dsp_mode_ts >= 0 && cnetz->sched_r_m == 0) { + if (cnetz->sched_dsp_mode_ts == cnetz->sched_ts) { /* OgK / SpK(K) / SpK(V) */ - PDEBUG_CHAN(DDSP, DEBUG_INFO, "Switching channel (mode)\n"); + PDEBUG_CHAN(DDSP, DEBUG_INFO, "Now switchting channel mode to %s at timeslot %d\n", cnetz_dsp_mode_name(cnetz->sched_dsp_mode), cnetz->sched_dsp_mode_ts); + cnetz->sched_dsp_mode_ts = -1; cnetz_set_dsp_mode(cnetz, cnetz->sched_dsp_mode); } } @@ -843,39 +867,22 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count) cnetz->sender.rxbuf_pos = pos; } -const char *cnetz_dsp_mode_name(enum dsp_mode mode) -{ - static char invalid[16]; - - switch (mode) { - case DSP_SCHED_NONE: - return "SCHED_NONE"; - case DSP_MODE_OFF: - return "OFF"; - case DSP_MODE_OGK: - return "OGK"; - case DSP_MODE_SPK_K: - return "SPK_K"; - case DSP_MODE_SPK_V: - return "SPK_V"; - } - - sprintf(invalid, "invalid(%d)", mode); - return invalid; -} - void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode) { - PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "DSP mode %s -> %s\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode)); - cnetz->dsp_mode = mode; + if (mode != cnetz->dsp_mode) { + PDEBUG_CHAN(DDSP, DEBUG_INFO, "DSP mode %s -> %s\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode)); + cnetz->dsp_mode = mode; + } /* we must get rid of partly received frame */ fsk_demod_reset(&cnetz->fsk_demod); } -void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead) +void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int timeslot) { - PDEBUG_CHAN(DDSP, DEBUG_DEBUG, " Schedule DSP mode %s -> %s in %d frames\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode), frames_ahead); - cnetz->sched_dsp_mode = mode; - cnetz->sched_switch_mode = frames_ahead; + if (mode != cnetz->dsp_mode) { + PDEBUG_CHAN(DDSP, DEBUG_INFO, "Schedule DSP mode %s -> %s at timeslot %d\n", cnetz_dsp_mode_name(cnetz->dsp_mode), cnetz_dsp_mode_name(mode), timeslot); + cnetz->sched_dsp_mode = mode; + cnetz->sched_dsp_mode_ts = timeslot; + } } diff --git a/src/cnetz/dsp.h b/src/cnetz/dsp.h index f5e3506..7af7c94 100644 --- a/src/cnetz/dsp.h +++ b/src/cnetz/dsp.h @@ -5,5 +5,5 @@ void dsp_cleanup_sender(cnetz_t *cnetz); void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result); void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count); void cnetz_set_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode); -void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int frames_ahead); +void cnetz_set_sched_dsp_mode(cnetz_t *cnetz, enum dsp_mode mode, int timeslot);