aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2017-02-24 16:00:54 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2017-02-24 16:00:54 +0100
commitc2863cf4bee6459f1bb72c73bcf83596051cf96d (patch)
treeb336b0894c21d620fbbf95294dddab831ce6b3cd /src
parent89715eaa5e02c852e26caaa1854902335cbba794 (diff)
downloadODR-AudioEnc-c2863cf4bee6459f1bb72c73bcf83596051cf96d.tar.gz
ODR-AudioEnc-c2863cf4bee6459f1bb72c73bcf83596051cf96d.tar.bz2
ODR-AudioEnc-c2863cf4bee6459f1bb72c73bcf83596051cf96d.zip
Improve VLC samplerate conversion by asking float samples
Asking floats from VLC instead of signed 16-bit samples allows VLC to use the libsamplerate resampler instead of the ugly_resampler. Otherwise it might convert to s16l first, and refuse to use libsamplerate which is unable to work with that data format.
Diffstat (limited to 'src')
-rw-r--r--src/VLCInput.cpp46
-rw-r--r--src/VLCInput.h4
2 files changed, 36 insertions, 14 deletions
diff --git a/src/VLCInput.cpp b/src/VLCInput.cpp
index e7dfa21..302877b 100644
--- a/src/VLCInput.cpp
+++ b/src/VLCInput.cpp
@@ -20,7 +20,7 @@
#include <string>
#include <cstring>
#include <chrono>
-#include <functional>
+#include <algorithm>
#include "VLCInput.h"
@@ -28,6 +28,8 @@
#if HAVE_VLC
+const size_t bytes_per_float_sample = sizeof(float);
+
#include <sys/time.h>
int check_vlc_uses_size_t();
@@ -76,7 +78,7 @@ void handleStream_size_t(
assert(channels == in->getChannels());
assert(rate == in->getRate());
- assert(bits_per_sample == 8*BYTES_PER_SAMPLE);
+ assert(bits_per_sample == 8*bytes_per_float_sample);
// This assumes VLC always gives back the full
// buffer it asked for. According to VLC code
@@ -143,11 +145,11 @@ int VLCInput::prepare()
// VLC options
std::stringstream transcode_options_ss;
- transcode_options_ss << "samplerate=" << m_rate;
+ transcode_options_ss << "acodec=fl32";
+ transcode_options_ss << ",samplerate=" << m_rate;
if (not m_gain.empty()) {
transcode_options_ss << ",afilter=compressor";
}
- transcode_options_ss << ",acodec=s16l";
string transcode_options = transcode_options_ss.str();
char smem_options[512];
@@ -250,8 +252,8 @@ void VLCInput::preRender_cb(uint8_t** pp_pcm_buffer, size_t size)
std::lock_guard<std::mutex> lock(m_queue_mutex);
if (m_queue.size() < max_length) {
- m_current_buf.resize(size);
- *pp_pcm_buffer = &m_current_buf[0];
+ m_current_buf.resize(size / sizeof(float));
+ *pp_pcm_buffer = reinterpret_cast<uint8_t*>(&m_current_buf[0]);
return;
}
}
@@ -304,12 +306,32 @@ ssize_t VLCInput::m_read(uint8_t* buf, size_t length)
{
std::lock_guard<std::mutex> lock(m_queue_mutex);
- if (m_queue.size() >= length) {
- std::copy(m_queue.begin(), m_queue.begin() + length, buf);
-
- m_queue.erase(m_queue.begin(), m_queue.begin() + length);
-
- return length;
+ assert((length % sizeof(int16_t)) == 0);
+ const size_t num_samples_requested = length / sizeof(int16_t);
+
+ // The queue contains float samples.
+ // buf has to contain signed 16-bit samples.
+ if (m_queue.size() >= num_samples_requested) {
+ int16_t* buffer = reinterpret_cast<int16_t*>(buf);
+
+ for (size_t i = 0; i < num_samples_requested; i++) {
+ const auto in = m_queue[i];
+ if (in <= -1.0f) {
+ buffer[i] = INT16_MAX;
+ }
+ else if (in >= 1.0f) {
+ buffer[i] = INT16_MIN;
+ }
+ else {
+ buffer[i] = (int16_t)lrintf(in * 32768.0f);
+ }
+ }
+
+ m_queue.erase(
+ m_queue.begin(),
+ m_queue.begin() + num_samples_requested);
+
+ return num_samples_requested * sizeof(int16_t);
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
diff --git a/src/VLCInput.h b/src/VLCInput.h
index 5ef970b..16c6cbf 100644
--- a/src/VLCInput.h
+++ b/src/VLCInput.h
@@ -163,12 +163,12 @@ class VLCInput
ssize_t m_read(uint8_t* buf, size_t length);
/*! Buffer used in the callback functions for VLC */
- std::vector<uint8_t> m_current_buf;
+ std::vector<float> m_current_buf;
std::mutex m_queue_mutex;
/*! Buffer containing all available samples from VLC */
- std::deque<uint8_t> m_queue;
+ std::deque<float> m_queue;
std::string m_uri;
unsigned m_verbosity;