From 743d147d1672837595ae1d6aa024522f4a011614 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 19 Aug 2017 12:27:05 +0200 Subject: SDR: Turn TX power off if requested by network The power level is ramped smoothly within 1 ms up or down. R2000, AMPS and C-Netz turn off power when voice channel is not i use. C-Netz turns off power between OgK timeslots. --- src/amps/amps.h | 2 - src/amps/dsp.c | 33 ++------- src/anetz/dsp.c | 4 +- src/bnetz/dsp.c | 4 +- src/cnetz/dsp.c | 78 ++++++++------------- src/common/call.c | 4 +- src/common/fm_modulation.c | 163 ++++++++++++++++++++++++++++++++++++++------ src/common/fm_modulation.h | 13 +++- src/common/sdr.c | 6 +- src/common/sdr.h | 2 +- src/common/sender.c | 6 +- src/common/sender.h | 4 +- src/common/sound.h | 2 +- src/common/sound_alsa.c | 2 +- src/nmt/dsp.c | 4 +- src/r2000/dsp.c | 6 +- src/test/test_performance.c | 4 +- 17 files changed, 221 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/amps/amps.h b/src/amps/amps.h index 8684f5a..5f82a23 100644 --- a/src/amps/amps.h +++ b/src/amps/amps.h @@ -144,8 +144,6 @@ typedef struct amps { int sat_detect_count; /* current number of consecutive detections/losses */ int sig_detected; /* current detection state flag (delayed detection) */ int sig_detect_count; /* current number of consecutive detections/losses */ - double test_phaseshift65536; /* how much the phase of sine wave changes per sample */ - double test_phase65536; /* current phase */ transaction_t *trans_list; /* list of transactions */ diff --git a/src/amps/dsp.c b/src/amps/dsp.c index e65e791..efa89f7 100644 --- a/src/amps/dsp.c +++ b/src/amps/dsp.c @@ -138,7 +138,6 @@ static double sat_freq[4] = { }; static sample_t dsp_sine_sat[65536]; -static sample_t dsp_sine_test[65536]; static uint8_t dsp_sync_check[0x800]; @@ -152,7 +151,6 @@ void dsp_init(void) for (i = 0; i < 65536; i++) { s = sin((double)i / 65536.0 * 2.0 * PI); dsp_sine_sat[i] = s * ((!tacs) ? AMPS_SAT_DEVIATION : TACS_SAT_DEVIATION); - dsp_sine_test[i] = s * ((!tacs) ? AMPS_FSK_DEVIATION : TACS_FSK_DEVIATION); } /* sync checker */ @@ -267,10 +265,6 @@ int dsp_init_sender(amps_t *amps, int tolerant) audio_goertzel_init(&s->sat_goertzel[4], (!tacs) ? 10000.0 : 8000.0, amps->sender.samplerate); sat_reset(amps, "Initial state"); - /* test tone */ - amps->test_phaseshift65536 = 65536.0 / ((double)amps->sender.samplerate / 1000.0); - PDEBUG(DDSP, DEBUG_DEBUG, "test_phaseshift65536 = %.4f\n", amps->test_phaseshift65536); - /* be more tolerant when syncing */ amps->fsk_rx_sync_tolerant = tolerant; @@ -468,26 +462,8 @@ static void sat_encode(amps_t *amps, sample_t *samples, int length) amps->sat_phase65536 = phase; } -static void test_tone_encode(amps_t *amps, sample_t *samples, int length) -{ - double phaseshift, phase; - int i; - - phaseshift = amps->test_phaseshift65536; - phase = amps->test_phase65536; - - for (i = 0; i < length; i++) { - *samples++ = dsp_sine_test[(uint16_t)phase]; - phase += phaseshift; - if (phase >= 65536) - phase -= 65536; - } - - amps->test_phase65536 = phase; -} - /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, sample_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length) { amps_t *amps = (amps_t *) sender; int count; @@ -495,10 +471,11 @@ void sender_send(sender_t *sender, sample_t *samples, int length) again: switch (amps->dsp_mode) { case DSP_MODE_OFF: - /* test tone, if transmitter is off */ - test_tone_encode(amps, samples, length); + memset(power, 0, length); + memset(samples, 0, sizeof(*samples) * length); break; case DSP_MODE_AUDIO_RX_AUDIO_TX: + memset(power, 1, length); jitter_load(&s->sender.dejitter, samples, length); /* pre-emphasis */ if (amps->pre_emphasis) @@ -511,7 +488,9 @@ again: /* Encode frame into audio stream. If frames have * stopped, process again for rest of stream. */ count = fsk_frame(amps, samples, length); + memset(power, 1, count); samples += count; + power += count; length -= count; if (length) goto again; diff --git a/src/anetz/dsp.c b/src/anetz/dsp.c index 65db940..f133aa0 100644 --- a/src/anetz/dsp.c +++ b/src/anetz/dsp.c @@ -339,10 +339,12 @@ static void fsk_tone(anetz_t *anetz, sample_t *samples, int length) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, sample_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length) { anetz_t *anetz = (anetz_t *) sender; + memset(power, 1, length); + switch (anetz->dsp_mode) { case DSP_MODE_SILENCE: memset(samples, 0, length * sizeof(*samples)); diff --git a/src/bnetz/dsp.c b/src/bnetz/dsp.c index bc2d500..e8b4a2d 100644 --- a/src/bnetz/dsp.c +++ b/src/bnetz/dsp.c @@ -301,11 +301,13 @@ static void metering_tone(bnetz_t *bnetz, sample_t *samples, int length) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, sample_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length) { bnetz_t *bnetz = (bnetz_t *) sender; int count; + memset(power, 1, length); + again: switch (bnetz->dsp_mode) { case DSP_MODE_SILENCE: diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c index 2c2ca4e..f34b798 100644 --- a/src/cnetz/dsp.c +++ b/src/cnetz/dsp.c @@ -250,39 +250,6 @@ void calc_clock_speed(cnetz_t *cnetz, double samples, int tx, int result) PDEBUG_CHAN(DDSP, DEBUG_NOTICE, "Clock: RX=%.3f TX=%.3f; Signal: RX=%.3f TX=%.3f ppm\n", speed_ppm_avg[0], speed_ppm_avg[1], speed_ppm_avg[2], speed_ppm_avg[3]); } -static int fsk_testtone_encode(cnetz_t *cnetz) -{ - sample_t *spl; - double phase, bitstep; - int i, count; - - spl = cnetz->fsk_tx_buffer; - phase = cnetz->fsk_tx_phase; - bitstep = cnetz->fsk_tx_bitstep * 256.0; - - /* add 198 bits of test tone */ - for (i = 0; i < 99; i++) { - do { - *spl++ = ramp_up[(uint8_t)phase]; - phase += bitstep; - } while (phase < 256.0); - phase -= 256.0; - do { - *spl++ = ramp_down[(uint8_t)phase]; - phase += bitstep; - } while (phase < 256.0); - phase -= 256.0; - } - - /* depending on the number of samples, return the number */ - count = ((uintptr_t)spl - (uintptr_t)cnetz->fsk_tx_buffer) / sizeof(*spl); - - cnetz->fsk_tx_phase = phase; - cnetz->fsk_tx_buffer_length = count; - - return count; -} - static int fsk_nothing_encode(cnetz_t *cnetz) { sample_t *spl; @@ -293,10 +260,10 @@ static int fsk_nothing_encode(cnetz_t *cnetz) phase = cnetz->fsk_tx_phase; bitstep = cnetz->fsk_tx_bitstep * 256.0; - /* add 198 bits of silence */ + /* add 198 bits of no power (silence) */ for (i = 0; i < 198; i++) { do { - *spl++ = 0; + *spl++ = -10.0; /* marker for power off */ phase += bitstep; } while (phase < 256.0); phase -= 256.0; @@ -315,7 +282,7 @@ static int fsk_nothing_encode(cnetz_t *cnetz) * input: 184 data bits (including barker code) * output: samples * return number of samples */ -static int fsk_block_encode(cnetz_t *cnetz, const char *bits) +static int fsk_block_encode(cnetz_t *cnetz, const char *bits, int ogk) { /* alloc samples, add 1 in case there is a rest */ sample_t *spl; @@ -331,7 +298,7 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits) /* add 7 bits of pause */ for (i = 0; i < 7; i++) { do { - *spl++ = 0; + *spl++ = 0.0; phase += bitstep; } while (phase < 256.0); phase -= 256.0; @@ -411,10 +378,18 @@ static int fsk_block_encode(cnetz_t *cnetz, const char *bits) phase -= 256.0; } for (i = 1; i < 7; i++) { - do { - *spl++ = 0; - phase += bitstep; - } while (phase < 256.0); + /* turn off power for OgK */ + if (ogk) { + do { + *spl++ = -10.0; /* marker for power off */ + phase += bitstep; + } while (phase < 256.0); + } else { + do { + *spl++ = 0.0; + phase += bitstep; + } while (phase < 256.0); + } phase -= 256.0; } @@ -618,7 +593,7 @@ static int shrink_speech(cnetz_t *cnetz, sample_t *speech_buffer) return speech_length; } -static int fsk_telegramm(cnetz_t *cnetz, sample_t *samples, int length) +static int fsk_telegramm(cnetz_t *cnetz, sample_t *samples, uint8_t *power, int length) { int count = 0, pos, copy, i, speech_length, speech_pos; sample_t *spl, *speech_buffer; @@ -693,7 +668,7 @@ again: PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Meldeblock' at timeslot %d\n", cnetz->sched_ts); bits = cnetz_encode_telegramm(cnetz); } - fsk_block_encode(cnetz, bits); + fsk_block_encode(cnetz, bits, 1); } else { fsk_nothing_encode(cnetz); } @@ -701,7 +676,7 @@ again: case DSP_MODE_SPK_K: PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Konzentrierte Signalisierung'\n"); bits = cnetz_encode_telegramm(cnetz); - fsk_block_encode(cnetz, bits); + fsk_block_encode(cnetz, bits, 0); break; case DSP_MODE_SPK_V: PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Transmitting 'Verteilte Signalisierung'\n"); @@ -710,7 +685,7 @@ again: break; case DSP_MODE_OFF: default: - fsk_testtone_encode(cnetz); + fsk_nothing_encode(cnetz); } if (cnetz->dsp_mode == DSP_MODE_SPK_V) { @@ -733,7 +708,7 @@ again: if (length - count < copy) copy = length - count; for (i = 0; i < copy; i++) { - if (*spl > 5.0) { /* marker found */ + if (*spl > 5.0) { /* speech marker found */ int begin, end, j; /* correct marker (not the best way) */ *spl -= 10.0; @@ -760,12 +735,19 @@ again: speech_length += begin; /* add one bit duration after speech */ speech_pos = 0; } + if (*spl < -5.0) { /* power off marker found */ + /* correct marker (not the best way) */ + *spl += 10.0; + *power = 0; + } else + *power = 1; /* add speech as long as we have something left in buffer */ if (speech_pos < speech_length) *samples++ = *spl + speech_buffer[speech_pos++]; else *samples++ = *spl; spl++; + power++; } cnetz->dsp_speech_length = speech_length; cnetz->dsp_speech_pos = speech_pos; @@ -783,7 +765,7 @@ again: } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, sample_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length) { cnetz_t *cnetz = (cnetz_t *) sender; int count; @@ -797,7 +779,7 @@ void sender_send(sender_t *sender, sample_t *samples, int length) return; #endif - count = fsk_telegramm(cnetz, samples, length); + count = fsk_telegramm(cnetz, samples, power, length); if (count < length) { printf("length=%d < count=%d\n", length, count); printf("this shall not happen, so please fix!\n"); diff --git a/src/common/call.c b/src/common/call.c index b7294ab..54e52d5 100644 --- a/src/common/call.c +++ b/src/common/call.c @@ -690,6 +690,7 @@ void process_call(int c) /* handle audio, if sound device is used */ sample_t samples[call.latspl + 10], *samples_list[1]; + uint8_t *power_list[1]; int count; int rc; @@ -725,7 +726,8 @@ void process_call(int c) jitter_load(&call.dejitter, samples, count); } samples_list[0] = samples; - rc = sound_write(call.sound, samples_list, count, NULL, NULL, 1); + power_list[0] = NULL; + rc = sound_write(call.sound, samples_list, power_list, count, NULL, NULL, 1); if (rc < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to sound device (rc = %d)\n", rc); if (rc == -EPIPE) diff --git a/src/common/fm_modulation.c b/src/common/fm_modulation.c index 2aa688a..93621c8 100644 --- a/src/common/fm_modulation.c +++ b/src/common/fm_modulation.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "sample.h" #include "fm_modulation.h" @@ -30,17 +31,30 @@ /* init FM modulator */ int fm_mod_init(fm_mod_t *mod, double samplerate, double offset, double amplitude) { + int i; + memset(mod, 0, sizeof(*mod)); mod->samplerate = samplerate; mod->offset = offset; mod->amplitude = amplitude; -#ifdef FAST_SINE - int i; + mod->ramp_length = samplerate * 0.001; + mod->ramp_tab = calloc(mod->ramp_length, sizeof(*mod->ramp_tab)); + if (!mod->ramp_tab) { + fprintf(stderr, "No mem!\n"); + return -ENOMEM; + } + mod->state = MOD_STATE_OFF; + /* generate ramp up with ramp_length */ + for (i = 0; i < mod->ramp_length; i++) + mod->ramp_tab[i] = 0.5 - cos(M_PI * i / mod->ramp_length) / 2.0; + +#ifdef FAST_SINE mod->sin_tab = calloc(65536+16384, sizeof(*mod->sin_tab)); if (!mod->sin_tab) { fprintf(stderr, "No mem!\n"); + fm_mod_exit(mod); return -ENOMEM; } @@ -54,6 +68,10 @@ int fm_mod_init(fm_mod_t *mod, double samplerate, double offset, double amplitud void fm_mod_exit(fm_mod_t *mod) { + if (mod->ramp_tab) { + free(mod->ramp_tab); + mod->ramp_tab = NULL; + } if (mod->sin_tab) { free(mod->sin_tab); mod->sin_tab = NULL; @@ -61,10 +79,11 @@ void fm_mod_exit(fm_mod_t *mod) } /* do frequency modulation of samples and add them to existing baseband */ -void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, int length, float *baseband) +void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, uint8_t *power, int length, float *baseband) { double dev, rate, phase, offset; - int s, ss; + int ramp, ramp_length; + double *ramp_tab; #ifdef FAST_SINE double *sin_tab, *cos_tab; #else @@ -74,6 +93,9 @@ void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, int length, float * rate = mod->samplerate; phase = mod->phase; offset = mod->offset; + ramp = mod->ramp; + ramp_length = mod->ramp_length; + ramp_tab = mod->ramp_tab; #ifdef FAST_SINE sin_tab = mod->sin_tab; cos_tab = mod->sin_tab + 16384; @@ -81,30 +103,127 @@ void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, int length, float * amplitude = mod->amplitude; #endif - /* modulate */ - for (s = 0, ss = 0; s < length; s++) { - /* deviation is defined by the frequency value and the offset */ - dev = offset + frequency[s]; +again: + switch (mod->state) { + case MOD_STATE_ON: + /* modulate */ + while (length) { + /* is power is not set, ramp down */ + if (!(*power)) { + mod->state = MOD_STATE_RAMP_DOWN; + break; + } + /* deviation is defined by the frequency value and the offset */ + dev = offset + *frequency++; + power++; + length--; #ifdef FAST_SINE - phase += 65536.0 * dev / rate; - if (phase < 0.0) - phase += 65536.0; - else if (phase >= 65536.0) - phase -= 65536.0; - baseband[ss++] += cos_tab[(uint16_t)phase]; - baseband[ss++] += sin_tab[(uint16_t)phase]; + phase += 65536.0 * dev / rate; + if (phase < 0.0) + phase += 65536.0; + else if (phase >= 65536.0) + phase -= 65536.0; + *baseband++ += cos_tab[(uint16_t)phase]; + *baseband++ += sin_tab[(uint16_t)phase]; #else - phase += 2.0 * M_PI * dev / rate; - if (phase < 0.0) - phase += 2.0 * M_PI; - else if (phase >= 2.0 * M_PI) - phase -= 2.0 * M_PI; - baseband[ss++] += cos(phase) * amplitude; - baseband[ss++] += sin(phase) * amplitude; + phase += 2.0 * M_PI * dev / rate; + if (phase < 0.0) + phase += 2.0 * M_PI; + else if (phase >= 2.0 * M_PI) + phase -= 2.0 * M_PI; + *baseband++ += cos(phase) * amplitude; + *baseband++ += sin(phase) * amplitude; +#endif + } + break; + case MOD_STATE_RAMP_DOWN: + while (length) { + /* if power is set, ramp up */ + if (*power) { + mod->state = MOD_STATE_RAMP_UP; + break; + } + if (ramp == 0) { + mod->state = MOD_STATE_OFF; + break; + } + dev = offset + *frequency++; + power++; + length--; +#ifdef FAST_SINE + phase += 65536.0 * dev / rate; + if (phase < 0.0) + phase += 65536.0; + else if (phase >= 65536.0) + phase -= 65536.0; + *baseband++ += cos_tab[(uint16_t)phase] * ramp_tab[ramp]; + *baseband++ += sin_tab[(uint16_t)phase] * ramp_tab[ramp]; +#else + phase += 2.0 * M_PI * dev / rate; + if (phase < 0.0) + phase += 2.0 * M_PI; + else if (phase >= 2.0 * M_PI) + phase -= 2.0 * M_PI; + *baseband++ += cos(phase) * amplitude * ramp_tab[ramp]; + *baseband++ += sin(phase) * amplitude * ramp_tab[ramp]; +#endif + ramp--; + } + break; + case MOD_STATE_OFF: + while (length) { + /* if power is set, ramp up */ + if (*power) { + mod->state = MOD_STATE_RAMP_UP; + break; + } + frequency++; + power++; + length--; + baseband += 2; + } + break; + case MOD_STATE_RAMP_UP: + while (length) { + /* is power is not set, ramp down */ + if (!(*power)) { + mod->state = MOD_STATE_RAMP_DOWN; + break; + } + if (ramp == ramp_length - 1) { + mod->state = MOD_STATE_ON; + break; + } + /* deviation is defined by the frequency value and the offset */ + dev = offset + *frequency++; + power++; + length--; +#ifdef FAST_SINE + phase += 65536.0 * dev / rate; + if (phase < 0.0) + phase += 65536.0; + else if (phase >= 65536.0) + phase -= 65536.0; + *baseband++ += cos_tab[(uint16_t)phase] * ramp_tab[ramp]; + *baseband++ += sin_tab[(uint16_t)phase] * ramp_tab[ramp]; +#else + phase += 2.0 * M_PI * dev / rate; + if (phase < 0.0) + phase += 2.0 * M_PI; + else if (phase >= 2.0 * M_PI) + phase -= 2.0 * M_PI; + *baseband++ += cos(phase) * amplitude * ramp_tab[ramp]; + *baseband++ += sin(phase) * amplitude * ramp_tab[ramp]; #endif + ramp++; + } + break; } + if (length) + goto again; mod->phase = phase; + mod->ramp = ramp; } /* init FM demodulator */ diff --git a/src/common/fm_modulation.h b/src/common/fm_modulation.h index 83e7db4..d0bdaa1 100644 --- a/src/common/fm_modulation.h +++ b/src/common/fm_modulation.h @@ -1,16 +1,27 @@ #include "../common/iir_filter.h" +enum fm_mod_state { + MOD_STATE_OFF, /* transmitter off, no IQ vector */ + MOD_STATE_ON, /* transmitter on, FM modulated IQ vector */ + MOD_STATE_RAMP_UP, /* use half cos to ramp up IQ vector */ + MOD_STATE_RAMP_DOWN, /* use half cos to ramp down IQ vector */ +}; + typedef struct fm_mod { double samplerate; /* sample rate of in and out */ double offset; /* offset to calculated center frequency */ double amplitude; /* how much amplitude to add to the buff */ double phase; /* current phase of FM (used to shift and modulate ) */ double *sin_tab; /* sine/cosine table for modulation */ + enum fm_mod_state state;/* state of transmit power */ + double *ramp_tab; /* half cosine ramp up */ + int ramp; /* current ramp position */ + int ramp_length; /* number of values in ramp */ } fm_mod_t; int fm_mod_init(fm_mod_t *mod, double samplerate, double offset, double amplitude); void fm_mod_exit(fm_mod_t *mod); -void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, int num, float *baseband); +void fm_modulate_complex(fm_mod_t *mod, sample_t *frequency, uint8_t *power, int num, float *baseband); typedef struct fm_demod { double samplerate; /* sample rate of in and out */ diff --git a/src/common/sdr.c b/src/common/sdr.c index 3560466..ea873c1 100644 --- a/src/common/sdr.c +++ b/src/common/sdr.c @@ -557,7 +557,7 @@ void sdr_close(void *inst) } } -int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels) +int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal __attribute__((unused)) *paging_signal, int *on, int channels) { sdr_t *sdr = (sdr_t *)inst; float buffer[num * 2], *buff = NULL; @@ -576,9 +576,9 @@ int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal __attr for (c = 0; c < channels; c++) { /* switch to paging channel, if requested */ if (on[c] && sdr->paging_channel) - fm_modulate_complex(&sdr->chan[sdr->paging_channel].mod, samples[c], num, buff); + fm_modulate_complex(&sdr->chan[sdr->paging_channel].mod, samples[c], power[c], num, buff); else - fm_modulate_complex(&sdr->chan[c].mod, samples[c], num, buff); + fm_modulate_complex(&sdr->chan[c].mod, samples[c], power[c], num, buff); } } else { buff = (float *)samples; diff --git a/src/common/sdr.h b/src/common/sdr.h index 12a3e02..dc95bc9 100644 --- a/src/common/sdr.h +++ b/src/common/sdr.h @@ -3,7 +3,7 @@ int sdr_init(int sdr_uhd, int sdr_soapy, int channel, const char *device_args, c int sdr_start(void *inst); void *sdr_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); void sdr_close(void *inst); -int sdr_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); +int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal *paging_signal, int *on, int channels); int sdr_read(void *inst, sample_t **samples, int num, int channels); int sdr_get_tosend(void *inst, int latspl); diff --git a/src/common/sender.c b/src/common/sender.c index e9d0690..823fd5c 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -298,10 +298,12 @@ void process_sender_audio(sender_t *sender, int *quit, int latspl) /* count instances for audio channel */ for (num_chan = 0, inst = sender; inst; num_chan++, inst = inst->slave); sample_t buff[num_chan][latspl], *samples[num_chan]; + uint8_t pbuff[num_chan][latspl], *power[num_chan]; enum paging_signal paging_signal[num_chan]; int on[num_chan]; for (i = 0; i < num_chan; i++) { samples[i] = buff[i]; + power[i] = pbuff[i]; } #ifdef DEBUG_TIME_CONSUMPTION @@ -334,7 +336,7 @@ cant_recover: if (inst->loopback == 3) jitter_load(&inst->dejitter, samples[i], count); else - sender_send(inst, samples[i], count); + sender_send(inst, samples[i], power[i], count); /* internal loopback: loop back TX audio to RX */ if (inst->loopback == 1) { display_wave(inst, samples[i], count, inst->max_display); @@ -358,7 +360,7 @@ cant_recover: if (sender->wave_tx_play.fp) wave_read(&sender->wave_tx_play, samples, count); - rc = sender->audio_write(sender->audio, samples, count, paging_signal, on, num_chan); + rc = sender->audio_write(sender->audio, samples, power, count, paging_signal, on, num_chan); if (rc < 0) { PDEBUG(DSENDER, DEBUG_ERROR, "Failed to write TX data to audio device (rc = %d)\n", rc); if (rc == -EPIPE) { diff --git a/src/common/sender.h b/src/common/sender.h index 6871fd2..2cd0b9e 100644 --- a/src/common/sender.h +++ b/src/common/sender.h @@ -44,7 +44,7 @@ typedef struct sender { void *(*audio_open)(const char *, double *, double *, int, double, int, double, double); int (*audio_start)(void *); void (*audio_close)(void *); - int (*audio_write)(void *, sample_t **, int, enum paging_signal *, int *, int); + int (*audio_write)(void *, sample_t **, uint8_t **, int, enum paging_signal *, int *, int); int (*audio_read)(void *, sample_t **, int, int); int (*audio_get_tosend)(void *, int); int samplerate; @@ -96,7 +96,7 @@ void sender_set_fm(sender_t *sender, double max_deviation, double max_modulation int sender_open_audio(void); int sender_start_audio(void); void process_sender_audio(sender_t *sender, int *quit, int latspl); -void sender_send(sender_t *sender, sample_t *samples, int count); +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int count); void sender_receive(sender_t *sender, sample_t *samples, int count); void sender_paging(sender_t *sender, int on); diff --git a/src/common/sound.h b/src/common/sound.h index 1054eb4..40c813f 100644 --- a/src/common/sound.h +++ b/src/common/sound.h @@ -4,7 +4,7 @@ enum paging_signal; void *sound_open(const char *audiodev, double *tx_frequency, double *rx_frequency, int channels, double paging_frequency, int samplerate, double bandwidth, double sample_deviation); int sound_start(void *inst); void sound_close(void *inst); -int sound_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels); +int sound_write(void *inst, sample_t **samples, uint8_t **power, int num, enum paging_signal *paging_signal, int *on, int channels); int sound_read(void *inst, sample_t **samples, int num, int channels); int sound_get_tosend(void *inst, int latspl); diff --git a/src/common/sound_alsa.c b/src/common/sound_alsa.c index 752f82f..ca71551 100644 --- a/src/common/sound_alsa.c +++ b/src/common/sound_alsa.c @@ -259,7 +259,7 @@ static void gen_paging_tone(sound_t *sound, int16_t *samples, int length, enum p } } -int sound_write(void *inst, sample_t **samples, int num, enum paging_signal *paging_signal, int *on, int channels) +int sound_write(void *inst, sample_t **samples, uint8_t __attribute__((unused)) **power, int num, enum paging_signal *paging_signal, int *on, int channels) { sound_t *sound = (sound_t *)inst; double spl_deviation = sound->spl_deviation; diff --git a/src/nmt/dsp.c b/src/nmt/dsp.c index d0063a8..6086d62 100644 --- a/src/nmt/dsp.c +++ b/src/nmt/dsp.c @@ -417,11 +417,13 @@ static void dial_tone(nmt_t *nmt, sample_t *samples, int length) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, sample_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length) { nmt_t *nmt = (nmt_t *) sender; int count; + memset(power, 1, length); + again: switch (nmt->dsp_mode) { case DSP_MODE_AUDIO: diff --git a/src/r2000/dsp.c b/src/r2000/dsp.c index 73a6d95..10b3a97 100644 --- a/src/r2000/dsp.c +++ b/src/r2000/dsp.c @@ -309,7 +309,7 @@ static int super_send_bit(void *inst) } /* Provide stream of audio toward radio unit */ -void sender_send(sender_t *sender, sample_t *samples, int length) +void sender_send(sender_t *sender, sample_t *samples, uint8_t *power, int length) { r2000_t *r2000 = (r2000_t *) sender; int count; @@ -317,10 +317,12 @@ void sender_send(sender_t *sender, sample_t *samples, int length) again: switch (r2000->dsp_mode) { case DSP_MODE_OFF: + memset(power, 0, length); memset(samples, 0, sizeof(*samples) * length); break; case DSP_MODE_AUDIO_TX: case DSP_MODE_AUDIO_TX_RX: + memset(power, 1, length); jitter_load(&r2000->sender.dejitter, samples, length); iir_process(&r2000->super_tx_hp, samples, length); /* do pre-emphasis */ @@ -341,7 +343,9 @@ again: /* add supervisory to sample buffer */ fsk_send(&r2000->super_fsk, samples, count, 1); } + memset(power, 1, count); samples += count; + power += count; length -= count; if (length) goto again; diff --git a/src/test/test_performance.c b/src/test/test_performance.c index 577fc05..dbc6b5c 100644 --- a/src/test/test_performance.c +++ b/src/test/test_performance.c @@ -30,6 +30,7 @@ int tot_samples; #define SAMPLES 1000 sample_t samples[SAMPLES], I[SAMPLES], Q[SAMPLES]; +uint8_t power[SAMPLES]; float buff[SAMPLES * 2]; fm_mod_t mod; fm_demod_t demod; @@ -37,9 +38,10 @@ iir_filter_t lp; int main(void) { + memset(power, 1, sizeof(power)); fm_mod_init(&mod, 50000, 0, 0.333); T_START() - fm_modulate_complex(&mod, samples, SAMPLES, buff); + fm_modulate_complex(&mod, samples, power, SAMPLES, buff); T_STOP("FM modulate", SAMPLES) fm_demod_init(&demod, 50000, 0, 10000.0); -- cgit v1.2.3