11static const uint32_t READ_WRITE_TIMEOUT_MS = 20;
14 : input_buffer_size_(input_buffer_size), output_buffer_size_(output_buffer_size) {
23 return ESP_ERR_INVALID_STATE;
33 return ESP_ERR_NO_MEM;
42 return ESP_ERR_NO_MEM;
47 uint16_t number_of_taps, uint16_t number_of_filters) {
52 return ESP_ERR_NO_MEM;
57 return ESP_ERR_NOT_SUPPORTED;
64 return ESP_ERR_NOT_SUPPORTED;
69 this->
resampler_ = make_unique<esp_audio_libs::resampler::Resampler>(
76 esp_audio_libs::resampler::ResamplerConfiguration resample_config = {
77 .source_sample_rate =
static_cast<float>(input_stream_info.
get_sample_rate()),
78 .target_sample_rate =
static_cast<float>(output_stream_info.
get_sample_rate()),
82 .use_pre_or_post_filter = use_pre_filter,
83 .subsample_interpolate =
false,
84 .number_of_taps = number_of_taps,
85 .number_of_filters = number_of_filters,
88 if (!this->
resampler_->initialize(resample_config)) {
90 return ESP_ERR_NO_MEM;
110 static_cast<uint8_t
>(bytes_per_frame));
117 if (stop_gracefully) {
118 if (!this->
audio_source_->has_buffered_data() && (this->output_transfer_buffer_->available() == 0)) {
129 delay(READ_WRITE_TIMEOUT_MS);
134 this->
audio_source_->fill(pdMS_TO_TICKS(READ_WRITE_TIMEOUT_MS),
false);
144 const size_t bytes_available = this->
audio_source_->available();
148 (this->input_stream_info_.get_bits_per_sample() != this->output_stream_info_.get_bits_per_sample())) {
150 esp_audio_libs::resampler::ResamplerResults results =
152 frames_available, frames_free, -3);
164 const int32_t used_ms =
166 const int32_t generated_ms =
169 *ms_differential = used_ms - generated_ms;
173 *ms_differential = 0;
176 this->input_stream_info_.frames_to_bytes(frames_available));
178 std::memcpy((
void *) this->
output_transfer_buffer_->get_buffer_end(), (
const void *) this->audio_source_->data(),
AudioResamplerState resample(bool stop_gracefully, int32_t *ms_differential)
Resamples audio from the ring buffer source and writes to the sink.
size_t input_buffer_size_
std::shared_ptr< ring_buffer::RingBuffer > source_ring_buffer_
AudioStreamInfo input_stream_info_
std::unique_ptr< esp_audio_libs::resampler::Resampler > resampler_
uint32_t accumulated_frames_generated_
esp_err_t add_source(std::weak_ptr< ring_buffer::RingBuffer > &input_ring_buffer)
Sets the ring buffer the audio is read from and takes shared ownership of it.
std::unique_ptr< AudioSinkTransferBuffer > output_transfer_buffer_
esp_err_t add_sink(std::weak_ptr< ring_buffer::RingBuffer > &output_ring_buffer)
Adds a sink ring buffer for resampled audio.
AudioResampler(size_t input_buffer_size, size_t output_buffer_size)
Allocates the output transfer buffer.
esp_err_t start(AudioStreamInfo &input_stream_info, AudioStreamInfo &output_stream_info, uint16_t number_of_taps, uint16_t number_of_filters)
Sets up the class to resample.
uint32_t accumulated_frames_used_
AudioStreamInfo output_stream_info_
std::unique_ptr< RingBufferAudioSource > audio_source_
static std::unique_ptr< AudioSinkTransferBuffer > create(size_t buffer_size)
Creates a new sink transfer buffer.
size_t frames_to_bytes(uint32_t frames) const
Converts frames to bytes.
uint8_t get_bits_per_sample() const
uint32_t bytes_to_frames(size_t bytes) const
Convert bytes to frames.
uint8_t get_channels() const
uint32_t frames_to_milliseconds_with_remainder(uint32_t *frames) const
Computes the duration, in milliseconds, the given amount of frames represents.
uint32_t get_sample_rate() const
uint32_t bytes_to_samples(size_t bytes) const
Convert bytes to samples.
static constexpr size_t MAX_ALIGNMENT_BYTES
Maximum supported alignment. Sized to cover 32-bit samples across up to 2 channels (8 bytes).
static std::unique_ptr< RingBufferAudioSource > create(std::shared_ptr< ring_buffer::RingBuffer > ring_buffer, size_t max_fill_bytes, uint8_t alignment_bytes=1)
Creates a new ring-buffer-backed audio source after validating its parameters.
void HOT delay(uint32_t ms)