summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-08 11:36:10 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-08 11:36:10 +1000
commit6c99f9f2fee0928987fe944c8ed29878064df87a (patch)
tree644c89eb56881e29bbe5627b0e0842b3adfedca4
parent49f82d2f3d31f5ecb26f1f45d091e346da515314 (diff)
downloadtangara-fw-6c99f9f2fee0928987fe944c8ed29878064df87a.tar.gz
Fix resampler issue, do a little performance tuning
-rw-r--r--src/audio/fatfs_audio_input.cpp9
-rw-r--r--src/audio/i2s_audio_output.cpp12
-rw-r--r--src/audio/resample.cpp33
-rw-r--r--src/audio/sink_mixer.cpp2
4 files changed, 34 insertions, 22 deletions
diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp
index 0c3ef20d..73586f09 100644
--- a/src/audio/fatfs_audio_input.cpp
+++ b/src/audio/fatfs_audio_input.cpp
@@ -30,6 +30,7 @@
#include "freertos/portmacro.h"
#include "freertos/projdefs.h"
#include "future_fetcher.hpp"
+#include "idf_additions.h"
#include "span.hpp"
#include "stream_info.hpp"
#include "tag_parser.hpp"
@@ -40,8 +41,8 @@ static const char* kTag = "SRC";
namespace audio {
-static constexpr UINT kFileBufferSize = 4096 * 2;
-static constexpr UINT kStreamerBufferSize = 4096;
+static constexpr UINT kFileBufferSize = 8 * 1024;
+static constexpr UINT kStreamerBufferSize = 64 * 1024;
static StreamBufferHandle_t sForwardDest = nullptr;
@@ -143,7 +144,9 @@ FatfsAudioInput::FatfsAudioInput(
: IAudioSource(),
tag_parser_(tag_parser),
has_data_(xSemaphoreCreateBinary()),
- streamer_buffer_(xStreamBufferCreate(kStreamerBufferSize, 1)),
+ streamer_buffer_(xStreamBufferCreateWithCaps(kStreamerBufferSize,
+ 1,
+ MALLOC_CAP_SPIRAM)),
streamer_(new FileStreamer(streamer_buffer_, has_data_)),
input_buffer_(new RawStream(kFileBufferSize)),
source_mutex_(),
diff --git a/src/audio/i2s_audio_output.cpp b/src/audio/i2s_audio_output.cpp
index e8aa8975..e53dbe2a 100644
--- a/src/audio/i2s_audio_output.cpp
+++ b/src/audio/i2s_audio_output.cpp
@@ -117,18 +117,10 @@ auto I2SAudioOutput::AdjustVolumeDown() -> bool {
auto I2SAudioOutput::PrepareFormat(const StreamInfo::Pcm& orig)
-> StreamInfo::Pcm {
- /*
-return StreamInfo::Pcm{
- .channels = std::min<uint8_t>(orig.channels, 2),
- .bits_per_sample = std::clamp<uint8_t>(orig.bits_per_sample, 16, 32),
- .sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
-};
- */
return StreamInfo::Pcm{
.channels = std::min<uint8_t>(orig.channels, 2),
- .bits_per_sample = 16,
- //.sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
- .sample_rate = 44100,
+ .bits_per_sample = std::clamp<uint8_t>(orig.bits_per_sample, 16, 32),
+ .sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
};
}
diff --git a/src/audio/resample.cpp b/src/audio/resample.cpp
index aa4c8f2a..7accd0a1 100644
--- a/src/audio/resample.cpp
+++ b/src/audio/resample.cpp
@@ -17,8 +17,8 @@ namespace audio {
static constexpr char kTag[] = "resample";
static constexpr double kLowPassRatio = 0.5;
-static constexpr size_t kNumFilters = 8;
-static constexpr size_t kTapsPerFilter = 8;
+static constexpr size_t kNumFilters = 64;
+static constexpr size_t kTapsPerFilter = 16;
typedef std::array<float, kTapsPerFilter> Filter;
static std::array<Filter, kNumFilters + 1> sFilters{};
@@ -64,12 +64,15 @@ auto Resampler::Process(cpp::span<const sample::Sample> input,
size_t input_frames = input.size() / num_channels_;
size_t output_frames = output.size() / num_channels_;
- int half_taps = kTapsPerFilter / 2, i;
+ int half_taps = kTapsPerFilter / 2;
while (output_frames > 0) {
if (output_offset_ >= input_index_ - half_taps) {
if (input_frames > 0) {
+ // Check whether the channel buffers will overflow with the addition of
+ // this sample. If so, we need to move the remaining contents back to
+ // the beginning of the buffer.
if (input_index_ == channel_buffer_size_) {
- for (i = 0; i < num_channels_; ++i) {
+ for (int i = 0; i < num_channels_; ++i) {
memmove(channel_buffers_[i],
channel_buffers_[i] + channel_buffer_size_ - kTapsPerFilter,
kTapsPerFilter * sizeof(float));
@@ -79,21 +82,23 @@ auto Resampler::Process(cpp::span<const sample::Sample> input,
input_index_ -= channel_buffer_size_ - kTapsPerFilter;
}
- for (i = 0; i < num_channels_; ++i) {
+ for (int i = 0; i < num_channels_; ++i) {
channel_buffers_[i][input_index_] =
sample::ToFloat(input[samples_used++]);
}
input_index_++;
input_frames--;
- } else
+ } else {
break;
+ }
} else {
- for (i = 0; i < num_channels_; i++) {
+ for (int i = 0; i < num_channels_; i++) {
output[samples_produced++] = sample::FromFloat(Subsample(i));
}
output_offset_ += (1.0f / factor_);
+ output_frames--;
}
}
@@ -160,8 +165,20 @@ auto Resampler::Subsample(int channel) -> float {
source = source.subspan(offset_integral);
float offset_fractional = output_offset_ - offset_integral;
- int filter_index = offset_fractional * kNumFilters;
+ /*
+// no interpolate
+size_t filter_index = std::floor(offset_fractional * kNumFilters + 0.5f);
+//ESP_LOGI(kTag, "selected filter %u of %u", filter_index, kNumFilters);
+int start_offset = kTapsPerFilter / 2 + 1;
+//ESP_LOGI(kTag, "using offset of %i, length %u", start_offset, kTapsPerFilter);
+
+return ApplyFilter(
+ sFilters[filter_index],
+ {source.data() - start_offset, kTapsPerFilter});
+ */
+
offset_fractional *= kNumFilters;
+ int filter_index = std::floor(offset_fractional);
sum1 = ApplyFilter(sFilters[filter_index],
{source.data() - kTapsPerFilter / 2 + 1, kTapsPerFilter});
diff --git a/src/audio/sink_mixer.cpp b/src/audio/sink_mixer.cpp
index a2bf229b..5a5a8616 100644
--- a/src/audio/sink_mixer.cpp
+++ b/src/audio/sink_mixer.cpp
@@ -195,7 +195,7 @@ auto SinkMixer::Resample(InputStream& in, OutputStream& out) -> bool {
out.data_as<sample::Sample>(), false);
in.consume(res.first * sizeof(sample::Sample));
- out.add(res.first * sizeof(sample::Sample));
+ out.add(res.second * sizeof(sample::Sample));
return res.first == 0 && res.second == 0;
}