summaryrefslogtreecommitdiff
path: root/src/audio/sink_mixer.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-10 19:12:38 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-10 19:12:38 +1000
commit958160aa545e3d91b2a4f1a367817e73d298e8a9 (patch)
tree190e6591a6dda1f0d9651c7e127666ead2a3373b /src/audio/sink_mixer.cpp
parentd8fc77101dcf80a3643a00b3446dca1e390ce997 (diff)
downloadtangara-fw-958160aa545e3d91b2a4f1a367817e73d298e8a9.tar.gz
Use the libspeexdsp resampler
AFAICT it runs a little slower? but it's fixed point, and has much better understood audio characteristics.
Diffstat (limited to 'src/audio/sink_mixer.cpp')
-rw-r--r--src/audio/sink_mixer.cpp41
1 files changed, 21 insertions, 20 deletions
diff --git a/src/audio/sink_mixer.cpp b/src/audio/sink_mixer.cpp
index 9f973d4b..5e712582 100644
--- a/src/audio/sink_mixer.cpp
+++ b/src/audio/sink_mixer.cpp
@@ -47,10 +47,7 @@ SinkMixer::SinkMixer(IAudioSink* sink)
kSampleBufferLength, sizeof(sample::Sample), MALLOC_CAP_SPIRAM)),
kSampleBufferLength};
- // Pin to CORE0 because we need the FPU.
- // FIXME: A fixed point implementation could run freely on either core,
- // which should lead to a big performance increase.
- tasks::StartPersistent<tasks::Type::kMixer>(0, [&]() { Main(); });
+ tasks::StartPersistent<tasks::Type::kMixer>([&]() { Main(); });
}
SinkMixer::~SinkMixer() {
@@ -100,7 +97,6 @@ auto SinkMixer::Main() -> void {
vTaskDelay(pdMS_TO_TICKS(10));
}
- ESP_LOGI(kTag, "configuring sink");
sink_->Configure(new_target);
}
target_format_ = new_target;
@@ -136,6 +132,7 @@ auto SinkMixer::Main() -> void {
// bytes we read were half a frame. Either way, we need to calculate the
// size of the remainder in bytes.
size_t bytes_used = samples_used * sizeof(sample::Sample);
+ assert(bytes_used <= bytes_in_buffer);
leftover_bytes_ = bytes_in_buffer - bytes_used;
if (leftover_bytes_ == 0) {
leftover_offset_ = 0;
@@ -157,20 +154,22 @@ auto SinkMixer::HandleSamples(cpp::span<sample::Sample> input, bool is_eos)
}
size_t samples_used = 0;
- while (input.size() < samples_used) {
+ while (samples_used < input.size()) {
cpp::span<sample::Sample> output_source;
if (source_format_.sample_rate != target_format_.sample_rate) {
if (resampler_ == nullptr) {
- ESP_LOGI(kTag, "creating new resampler");
+ ESP_LOGI(kTag, "creating new resampler for %lu -> %lu",
+ source_format_.sample_rate, target_format_.sample_rate);
resampler_.reset(new Resampler(source_format_.sample_rate,
target_format_.sample_rate,
source_format_.num_channels));
}
size_t read, written;
- std::tie(read, written) =
- resampler_->Process(input, resampled_buffer_, is_eos);
+ std::tie(read, written) = resampler_->Process(input.subspan(samples_used),
+ resampled_buffer_, is_eos);
samples_used += read;
+
if (read == 0 && written == 0) {
// Zero samples used or written. We need more input.
break;
@@ -181,20 +180,22 @@ auto SinkMixer::HandleSamples(cpp::span<sample::Sample> input, bool is_eos)
samples_used = input.size();
}
- if (target_format_.bits_per_sample == 16) {
- // FIXME: The source should have some kind of hint indicating whether it
- // needs dither, since some codecs (e.g. opus) apply their own dither.
- ApplyDither(output_source, 16);
-
- cpp::span<int16_t> dest{reinterpret_cast<int16_t*>(output_source.data()),
- output_source.size()};
- for (size_t i = 0; i < output_source.size(); i++) {
- dest[i] = sample::ToSigned16Bit(output_source[i]);
- }
+ /*
+ if (target_format_.bits_per_sample == 16) {
+ // FIXME: The source should have some kind of hint indicating whether it
+ // needs dither, since some codecs (e.g. opus) apply their own dither.
+ ApplyDither(output_source, 16);
- output_source = output_source.first(output_source.size() / 2);
+ cpp::span<int16_t> dest{reinterpret_cast<int16_t*>(output_source.data()),
+ output_source.size()};
+ for (size_t i = 0; i < output_source.size(); i++) {
+ dest[i] = sample::ToSigned16Bit(output_source[i]);
}
+ output_source = output_source.first(output_source.size() / 2);
+ }
+ */
+
size_t bytes_sent = 0;
size_t bytes_to_send = output_source.size_bytes();
while (bytes_sent < bytes_to_send) {