diff --git a/src/radio/main.c b/src/radio/main.c index acc430e..4f87fea 100644 --- a/src/radio/main.c +++ b/src/radio/main.c @@ -63,6 +63,7 @@ static double bandwidth = 0.0; static double deviation = 75000.0; static double modulation_index = 1.0; static double time_constant_us = 50.0; +static double volume = 1.0; static int stereo = 0; static int rds = 0; static int rds2 = 0; @@ -138,6 +139,8 @@ void print_help(const char *arg0) printf(" modulation. Give 0 to disbale. (default = %.0f uS)\n", time_constant_us); printf(" VHF broadcast 50 uS in Europe and 75 uS in the United States.\n"); printf(" Other radio FM should use 530 uS, to cover complete speech spectrum.\n"); + printf(" -V --volume %.3f\n", volume); + printf(" Change volume of radio side. (Gains transmission, dampens reception)\n"); printf(" -S --stereo\n"); printf(" Enables stereo carrier for frequency modulated UHF broadcast.\n"); printf(" It uses the 'Pilot-tone' system.\n"); @@ -169,6 +172,7 @@ static void add_options(void) option_add('D', "deviation", 1); option_add('I', "modulation-index", 1); option_add('E', "emphasis", 1); + option_add('V', "volume", 1); option_add('S', "stereo", 0); option_add(OPT_FAST_MATH, "fast-math", 0); option_add(OPT_LIMESDR, "limesdr", 0); @@ -238,6 +242,9 @@ static int handle_options(int short_option, int argi, char **argv) case 'E': time_constant_us = atof(argv[argi]); break; + case 'V': + volume = atof(argv[argi]); + break; case 'S': stereo = 1; break; @@ -348,7 +355,7 @@ int main(int argc, char *argv[]) /* now we have latency and sample rate */ latspl = samplerate * latency / 1000; - rc = radio_init(&radio, latspl, samplerate, tx_wave_file, rx_wave_file, (tx) ? tx_audiodev : NULL, (rx) ? rx_audiodev : NULL, modulation, bandwidth, deviation, modulation_index, time_constant_us, stereo, rds, rds2); + rc = radio_init(&radio, latspl, samplerate, tx_wave_file, rx_wave_file, (tx) ? tx_audiodev : NULL, (rx) ? rx_audiodev : NULL, modulation, bandwidth, deviation, modulation_index, time_constant_us, volume, stereo, rds, rds2); if (rc < 0) { fprintf(stderr, "Failed to initialize radio with given options, exitting!\n"); exit(0); diff --git a/src/radio/radio.c b/src/radio/radio.c index 2466364..4131ccc 100644 --- a/src/radio/radio.c +++ b/src/radio/radio.c @@ -36,7 +36,7 @@ #define PILOT_FREQ 19000.0 #define PILOT_BW 5.0 -int radio_init(radio_t *radio, int latspl, int samplerate, const char *tx_wave_file, const char *rx_wave_file, const char *tx_audiodev, const char *rx_audiodev, enum modulation modulation, double bandwidth, double deviation, double modulation_index, double time_constant_us, int stereo, int rds, int rds2) +int radio_init(radio_t *radio, int latspl, int samplerate, const char *tx_wave_file, const char *rx_wave_file, const char *tx_audiodev, const char *rx_audiodev, enum modulation modulation, double bandwidth, double deviation, double modulation_index, double time_constant_us, double volume, int stereo, int rds, int rds2) { int rc = -EINVAL; @@ -44,6 +44,7 @@ int radio_init(radio_t *radio, int latspl, int samplerate, const char *tx_wave_f memset(radio, 0, sizeof(*radio)); radio->latspl = latspl; + radio->volume = volume; radio->stereo = stereo; radio->rds = rds; radio->rds2 = rds2; @@ -457,6 +458,7 @@ int radio_tx(radio_t *radio, float *baseband, int signal_num) switch (radio->tx_audio_mode) { case AUDIO_MODE_WAVEFILE: wave_read(&radio->wave_tx_play, audio_samples, audio_num); + if (!radio->wave_tx_play.left) { int rc; int _samplerate = 0; @@ -527,6 +529,16 @@ int radio_tx(radio_t *radio, float *baseband, int signal_num) if (radio->stereo) iir_process(&radio->tx_dc_removal[1], audio_samples[1], audio_num); + /* gain volume */ + if (radio->volume != 1.0) { + for (i = 0; i < audio_num; i++) + audio_samples[0][i] *= radio->volume; + if (radio->stereo) { + for (i = 0; i < audio_num; i++) + audio_samples[1][i] *= radio->volume; + } + } + /* upsample */ signal_num = samplerate_upsample(&radio->tx_resampler[0], audio_samples[0], audio_num, signal_samples[0]); if (radio->stereo) @@ -654,6 +666,16 @@ int radio_rx(radio_t *radio, float *baseband, int signal_num) if (radio->stereo) samplerate_downsample(&radio->rx_resampler[1], samples[1], signal_num); + /* dampen volume */ + if (radio->volume != 1.0) { + for (i = 0; i < audio_num; i++) + samples[0][i] /= radio->volume; + if (radio->stereo) { + for (i = 0; i < audio_num; i++) + samples[1][i] /= radio->volume; + } + } + /* convert mono/stereo, (from differential signal) */ if (radio->stereo && radio->rx_audio_channels == 1) { /* stereo to mono */ diff --git a/src/radio/radio.h b/src/radio/radio.h index 5bb5239..6af8890 100644 --- a/src/radio/radio.h +++ b/src/radio/radio.h @@ -27,6 +27,7 @@ typedef struct radio { enum modulation modulation; /* modulation type */ enum audio_mode tx_audio_mode; /* mode for audio source */ enum audio_mode rx_audio_mode; /* mode for audio sink */ + double volume; /* volume change (gain/dampen) */ int stereo; /* use stere FM */ int rds, rds2; /* use RDS */ /* audio stage */ @@ -77,7 +78,7 @@ typedef struct radio { sample_t *carrier_buffer; } radio_t; -int radio_init(radio_t *radio, int latspl, int samplerate, const char *tx_wave_file, const char *rx_wave_file, const char *tx_audiodev, const char *rx_audiodev, enum modulation modulation, double bandwidth, double deviation, double modulation_index, double time_constant, int stereo, int rds, int rds2); +int radio_init(radio_t *radio, int latspl, int samplerate, const char *tx_wave_file, const char *rx_wave_file, const char *tx_audiodev, const char *rx_audiodev, enum modulation modulation, double bandwidth, double deviation, double modulation_index, double time_constant, double volume, int stereo, int rds, int rds2); void radio_exit(radio_t *radio); int radio_start(radio_t *radio); int radio_tx(radio_t *radio, float *baseband, int num);