aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2022-09-06 13:48:40 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2022-09-06 13:48:40 +0200
commitf828749c289bad5978ff3e7a8100c9a5c65b8970 (patch)
treef4c1ab0c788f940b0422dabb5b95d535de299837
parent7544d1eca9f33f450d2bf3e36b9df298cd7c23d9 (diff)
downloadODR-AudioEnc-f828749c289bad5978ff3e7a8100c9a5c65b8970.tar.gz
ODR-AudioEnc-f828749c289bad5978ff3e7a8100c9a5c65b8970.tar.bz2
ODR-AudioEnc-f828749c289bad5978ff3e7a8100c9a5c65b8970.zip
Replace libvlc compressor gain by internal gain calculation
-rw-r--r--README.md5
-rw-r--r--src/VLCInput.cpp9
-rw-r--r--src/VLCInput.h9
-rw-r--r--src/odr-audioenc.cpp36
4 files changed, 29 insertions, 30 deletions
diff --git a/README.md b/README.md
index 6095af1..0449898 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ therefore also webstreams and other network sources.
The GStreamer input is an alternative to read from various sources.
-The ALSA and libVLC inputs support sound card clock drift
+The ALSA, libVLC and GStreamer inputs support sound card clock drift
compensation, that can compensate for imprecise sound card clocks.
The JACK input does not automatically connect to anything. The encoder runs
@@ -293,9 +293,6 @@ in a future version.
## Known Limitations
-The gain option for libVLC enables the VLC audio compressor with default
-settings. This has more impact than just changing the volume of the audio.
-
Some receivers did not decode audio anymore between v0.3.0 and v0.5.0, because of
a change implemented to get PAD to work. The change was subsequently reverted in
v0.5.1 because it was deemed essential that audio decoding works on all receivers.
diff --git a/src/VLCInput.cpp b/src/VLCInput.cpp
index 0547696..ca44f04 100644
--- a/src/VLCInput.cpp
+++ b/src/VLCInput.cpp
@@ -1,5 +1,5 @@
/* ------------------------------------------------------------------
- * Copyright (C) 2018 Matthias P. Braendli
+ * Copyright (C) 2022 Matthias P. Braendli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -169,10 +169,6 @@ void VLCInput::prepare()
vlc_args.push_back("--network-caching=" + m_cache);
}
- if (not m_gain.empty()) {
- vlc_args.push_back("--compressor-makeup=" + m_gain);
- }
-
copy(m_additional_opts.begin(), m_additional_opts.end(),
back_inserter(vlc_args));
@@ -204,9 +200,6 @@ void VLCInput::prepare()
std::stringstream transcode_options_ss;
transcode_options_ss << "acodec=fl32";
transcode_options_ss << ",samplerate=" << m_rate;
- if (not m_gain.empty()) {
- transcode_options_ss << ",afilter=compressor";
- }
string transcode_options = transcode_options_ss.str();
char smem_options[512];
diff --git a/src/VLCInput.h b/src/VLCInput.h
index 47a9cdd..ed1a682 100644
--- a/src/VLCInput.h
+++ b/src/VLCInput.h
@@ -1,5 +1,5 @@
/* ------------------------------------------------------------------
- * Copyright (C) 2017 Matthias P. Braendli
+ * Copyright (C) 2022 Matthias P. Braendli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,7 +54,6 @@ class VLCInput : public InputInterface
int rate,
unsigned channels,
unsigned verbosity,
- std::string& gain,
std::string& cache,
std::vector<std::string>& additional_opts,
SampleQueue<uint8_t>& queue) :
@@ -64,7 +63,6 @@ class VLCInput : public InputInterface
m_rate(rate),
m_cache(cache),
m_additional_opts(additional_opts),
- m_gain(gain),
m_vlc(nullptr),
m_mp(nullptr),
m_fault(false),
@@ -136,11 +134,6 @@ class VLCInput : public InputInterface
//! Given as-is to libvlc, useful for additional arguments
std::vector<std::string> m_additional_opts;
- /*! value for the VLC compressor filter --compressor-makeup
- * setting. Many more compressor settings could be set.
- */
- std::string m_gain;
-
/*! VLC can give us the ICY-Text from an Icecast stream,
* which we optionally write into a text file for ODR-PadEnc
*/
diff --git a/src/odr-audioenc.cpp b/src/odr-audioenc.cpp
index 068c8a3..68a99a1 100644
--- a/src/odr-audioenc.cpp
+++ b/src/odr-audioenc.cpp
@@ -1,6 +1,6 @@
/* ------------------------------------------------------------------
* Copyright (C) 2011 Martin Storsjo
- * Copyright (C) 2021 Matthias P. Braendli
+ * Copyright (C) 2022 Matthias P. Braendli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -152,9 +152,6 @@ static void usage(const char* name)
#if HAVE_VLC
" -v, --vlc-uri=uri Enable VLC input and use the URI given as source\n"
" -C, --vlc-cache=ms Specify VLC network cache length.\n"
- " -g, --vlc-gain=db Enable VLC audio compressor, with given compressor-makeup value.\n"
- " Use this as a workaround to correct the gain for streams that are\n"
- " much too loud.\n"
" -V Increase the VLC verbosity by one (can be given \n"
" multiple times)\n"
" -L OPTION Give an additional options to VLC (can be given\n"
@@ -176,6 +173,9 @@ static void usage(const char* name)
" -b, --bitrate={ 8, 16, ..., 192 } Output bitrate in kbps. Must be a multiple of 8.\n"
" -c, --channels={ 1, 2 } Nb of input channels (default: 2).\n"
" -r, --rate={ 24000, 32000, 48000 } Input sample rate (default: 48000).\n"
+ " -g, --audio-gain=dB Apply audio gain correction in dB to source, negative values allowed.\n"
+ " Use this as a workaround to correct the gain for streams that are\n"
+ " much too loud.\n"
" DAB specific options\n"
" -a, --dab Encode in DAB and not in DAB+.\n"
" --dabmode=MODE Channel mode: s/d/j/m\n"
@@ -405,6 +405,7 @@ struct AudioEnc {
public:
int sample_rate=48000;
int channels=2;
+ double gain_dB = 0.0;
string icytext_file;
bool icytext_dlplus = false;
@@ -420,7 +421,6 @@ public:
// For the VLC input
string vlc_uri;
- string vlc_gain;
string vlc_cache;
vector<string> vlc_additional_opts;
unsigned verbosity = 0;
@@ -1009,13 +1009,29 @@ int AudioEnc::run()
* channels, and is formally wrong in mono, but still gives
* numbers one can use.
*
+ * At the same time, we apply gain correction.
+ *
* \todo fix level measurement in mono
*/
int16_t peak_left = 0;
int16_t peak_right = 0;
+
+ const double linear_gain_correction = pow(10.0, gain_dB / 20.0);
+
for (int i = 0; i < read_bytes; i+=4) {
int16_t l = input_buf[i] | (input_buf[i+1] << 8);
int16_t r = input_buf[i+2] | (input_buf[i+3] << 8);
+
+ if (linear_gain_correction != 1.0) {
+ l *= linear_gain_correction;
+ r *= linear_gain_correction;
+
+ input_buf[i] = l & 0x00FF;
+ input_buf[i+1] = (l & 0xFF00) >> 8;
+ input_buf[i+2] = r & 0x00FF;
+ input_buf[i+3] = (r & 0xFF00) >> 8;
+ }
+
peak_left = std::max(peak_left, l);
peak_right = std::max(peak_right, r);
}
@@ -1322,7 +1338,7 @@ shared_ptr<InputInterface> AudioEnc::initialise_input()
#if HAVE_VLC
else if (not vlc_uri.empty()) {
input = make_shared<VLCInput>(vlc_uri, sample_rate, channels, verbosity,
- vlc_gain, vlc_cache, vlc_additional_opts, queue);
+ vlc_cache, vlc_additional_opts, queue);
}
#endif
#if HAVE_GST
@@ -1353,6 +1369,7 @@ int main(int argc, char *argv[])
const struct option longopts[] = {
{"bitrate", required_argument, 0, 'b'},
{"bandwidth", required_argument, 0, 'B'},
+ {"audio-gain", required_argument, 0, 'g'},
{"channels", required_argument, 0, 'c'},
{"dabmode", required_argument, 0, 4 },
{"dabpsy", required_argument, 0, 5 },
@@ -1375,7 +1392,6 @@ int main(int argc, char *argv[])
{"startup-check", required_argument, 0, 9 },
{"stats", required_argument, 0, 'S'},
{"vlc-cache", required_argument, 0, 'C'},
- {"vlc-gain", required_argument, 0, 'g'},
{"vlc-uri", required_argument, 0, 'v'},
{"vlc-opt", required_argument, 0, 'L'},
{"write-icy-text", required_argument, 0, 'w'},
@@ -1516,6 +1532,9 @@ int main(int argc, char *argv[])
return 1;
}
break;
+ case 'g':
+ audio_enc.gain_dB = std::stod(optarg);
+ break;
#ifdef HAVE_GST
case 'G':
audio_enc.gst_uri = optarg;
@@ -1577,9 +1596,6 @@ int main(int argc, char *argv[])
case 'v':
audio_enc.vlc_uri = optarg;
break;
- case 'g':
- audio_enc.vlc_gain = optarg;
- break;
case 'C':
audio_enc.vlc_cache = optarg;
break;