diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-08-10 19:12:38 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-08-10 19:12:38 +1000 |
| commit | 958160aa545e3d91b2a4f1a367817e73d298e8a9 (patch) | |
| tree | 190e6591a6dda1f0d9651c7e127666ead2a3373b /src/audio/sink_mixer.cpp | |
| parent | d8fc77101dcf80a3643a00b3446dca1e390ce997 (diff) | |
| download | tangara-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.cpp | 41 |
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) { |
