aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2017-08-19 12:27:05 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2017-09-01 18:42:46 +0200
commit743d147d1672837595ae1d6aa024522f4a011614 (patch)
tree50c44e565e00700d90338835e681cbb1dccf8e9b /src
parent1c2e9180a2db989f26c5cff01eaa6ef12bb45011 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/amps/amps.h2
-rw-r--r--src/amps/dsp.c33
-rw-r--r--src/anetz/dsp.c4
-rw-r--r--src/bnetz/dsp.c4
-rw-r--r--src/cnetz/dsp.c78
-rw-r--r--src/common/call.c4
-rw-r--r--src/common/fm_modulation.c163
-rw-r--r--src/common/fm_modulation.h13
-rw-r--r--src/common/sdr.c6
-rw-r--r--src/common/sdr.h2
-rw-r--r--src/common/sender.c6
-rw-r--r--src/common/sender.h4
-rw-r--r--src/common/sound.h2
-rw-r--r--src/common/sound_alsa.c2
-rw-r--r--src/nmt/dsp.c4
-rw-r--r--src/r2000/dsp.c6
-rw-r--r--src/test/test_performance.c4
17 files changed, 221 insertions, 116 deletions
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(&amps->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(&amps->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 <stdlib.h>
#include <stdint.h>
#include <string.h>
+#include <errno.h>
#include <math.h>
#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);