Add power control to AM (power on/off per sample)
This commit is contained in:
parent
150a77b69d
commit
4af2dca10d
|
@ -91,7 +91,7 @@ void am_mod_exit(am_mod_t __attribute__((unused)) *mod)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void am_modulate_complex(am_mod_t *mod, sample_t *amplitude, int num, float *baseband)
|
void am_modulate_complex(am_mod_t *mod, sample_t *amplitude, uint8_t *power, int num, float *baseband)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
double vector;
|
double vector;
|
||||||
|
@ -101,7 +101,10 @@ void am_modulate_complex(am_mod_t *mod, sample_t *amplitude, int num, float *bas
|
||||||
double bias = mod->bias;
|
double bias = mod->bias;
|
||||||
|
|
||||||
for (s = 0; s < num; s++) {
|
for (s = 0; s < num; s++) {
|
||||||
|
if (*power++)
|
||||||
vector = *amplitude++ * gain + bias;
|
vector = *amplitude++ * gain + bias;
|
||||||
|
else
|
||||||
|
vector = 0.0;
|
||||||
if (fast_math) {
|
if (fast_math) {
|
||||||
*baseband++ += cos_tab[(uint16_t)phase] * vector;
|
*baseband++ += cos_tab[(uint16_t)phase] * vector;
|
||||||
*baseband++ += sin_tab[(uint16_t)phase] * vector;
|
*baseband++ += sin_tab[(uint16_t)phase] * vector;
|
||||||
|
|
|
@ -12,7 +12,7 @@ typedef struct am_mod {
|
||||||
|
|
||||||
int am_mod_init(am_mod_t *mod, double samplerate, double offset, double gain, double bias);
|
int am_mod_init(am_mod_t *mod, double samplerate, double offset, double gain, double bias);
|
||||||
void am_mod_exit(am_mod_t *mod);
|
void am_mod_exit(am_mod_t *mod);
|
||||||
void am_modulate_complex(am_mod_t *mod, sample_t *amplitude, int num, float *baseband);
|
void am_modulate_complex(am_mod_t *mod, sample_t *amplitude, uint8_t *power, int num, float *baseband);
|
||||||
|
|
||||||
typedef struct am_demod {
|
typedef struct am_demod {
|
||||||
double rot; /* angle to rotate vector per sample */
|
double rot; /* angle to rotate vector per sample */
|
||||||
|
|
|
@ -775,8 +775,7 @@ int sdr_write(void *inst, sample_t **samples, uint8_t **power, int num, enum pag
|
||||||
if (on[c] && sdr->paging_channel)
|
if (on[c] && sdr->paging_channel)
|
||||||
fm_modulate_complex(&sdr->chan[sdr->paging_channel].fm_mod, samples[c], power[c], num, buff);
|
fm_modulate_complex(&sdr->chan[sdr->paging_channel].fm_mod, samples[c], power[c], num, buff);
|
||||||
else if (sdr->chan[c].am) {
|
else if (sdr->chan[c].am) {
|
||||||
if (power[c][0])
|
am_modulate_complex(&sdr->chan[c].am_mod, samples[c], power[c], num, buff);
|
||||||
am_modulate_complex(&sdr->chan[c].am_mod, samples[c], num, buff);
|
|
||||||
} else
|
} else
|
||||||
fm_modulate_complex(&sdr->chan[c].fm_mod, samples[c], power[c], num, buff);
|
fm_modulate_complex(&sdr->chan[c].fm_mod, samples[c], power[c], num, buff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -546,12 +546,12 @@ int radio_tx(radio_t *radio, float *baseband, int signal_num)
|
||||||
|
|
||||||
/* prepare baseband */
|
/* prepare baseband */
|
||||||
memset(baseband, 0, sizeof(float) * 2 * signal_num);
|
memset(baseband, 0, sizeof(float) * 2 * signal_num);
|
||||||
|
memset(signal_power, 1, signal_num);
|
||||||
|
|
||||||
/* filter audio (remove DC, remove high frequencies, pre-emphasis)
|
/* filter audio (remove DC, remove high frequencies, pre-emphasis)
|
||||||
* and modulate */
|
* and modulate */
|
||||||
switch (radio->modulation) {
|
switch (radio->modulation) {
|
||||||
case MODULATION_FM:
|
case MODULATION_FM:
|
||||||
memset(signal_power, 1, signal_num);
|
|
||||||
pre_emphasis(&radio->fm_emphasis[0], signal_samples[0], signal_num);
|
pre_emphasis(&radio->fm_emphasis[0], signal_samples[0], signal_num);
|
||||||
clipper_process(signal_samples[0], signal_num);
|
clipper_process(signal_samples[0], signal_num);
|
||||||
if (radio->stereo) {
|
if (radio->stereo) {
|
||||||
|
@ -577,14 +577,14 @@ int radio_tx(radio_t *radio, float *baseband, int signal_num)
|
||||||
/* also clip to prevent overshooting after audio filtering */
|
/* also clip to prevent overshooting after audio filtering */
|
||||||
clipper_process(signal_samples[0], signal_num);
|
clipper_process(signal_samples[0], signal_num);
|
||||||
iir_process(&radio->tx_am_bw_limit, signal_samples[0], signal_num);
|
iir_process(&radio->tx_am_bw_limit, signal_samples[0], signal_num);
|
||||||
am_modulate_complex(&radio->am_mod, signal_samples[0], signal_num, baseband);
|
am_modulate_complex(&radio->am_mod, signal_samples[0], signal_power, signal_num, baseband);
|
||||||
break;
|
break;
|
||||||
case MODULATION_AM_USB:
|
case MODULATION_AM_USB:
|
||||||
case MODULATION_AM_LSB:
|
case MODULATION_AM_LSB:
|
||||||
/* also clip to prevent overshooting after audio filtering */
|
/* also clip to prevent overshooting after audio filtering */
|
||||||
clipper_process(signal_samples[0], signal_num);
|
clipper_process(signal_samples[0], signal_num);
|
||||||
iir_process(&radio->tx_am_bw_limit, signal_samples[0], signal_num);
|
iir_process(&radio->tx_am_bw_limit, signal_samples[0], signal_num);
|
||||||
am_modulate_complex(&radio->am_mod, signal_samples[0], signal_num, baseband);
|
am_modulate_complex(&radio->am_mod, signal_samples[0], signal_power, signal_num, baseband);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue