arduino-audio-tools
Loading...
Searching...
No Matches
AdaptiveResamplingStream.h
1#pragma once
2
3#include "AudioTools/CoreAudio/AudioBasic/KalmanFilter.h"
4#include "AudioTools/CoreAudio/AudioBasic/PIDController.h"
5#include "AudioTools/CoreAudio/AudioStreams.h"
6#include "AudioTools/CoreAudio/ResampleStream.h"
7
8namespace audio_tools {
9
25 public:
33 float stepRangePercent = 5.0f) {
34 p_buffer = &buffer;
35 setStepRangePercent(stepRangePercent);
36 addNotifyAudioChange(resample_stream);
37 }
38
44 bool begin() {
45 if (p_buffer == nullptr) return false;
46 queue_stream.setBuffer(*p_buffer);
47 queue_stream.begin();
48 resample_stream.setAudioInfo(audioInfo());
49 resample_stream.setStream(queue_stream);
50 resample_stream.begin(audioInfo());
51 float from_step = 1.0 - resample_range;
52 float to_step = 1.0 + resample_range;
53 return pid.begin(1.0, from_step, to_step, p, i, d);
54 }
55
63 size_t write(const uint8_t* data, size_t len) override {
64 if (p_buffer == nullptr) return 0;
65 size_t result = p_buffer->writeArray(data, len);
67 return result;
68 }
69
73 void end() {
74 queue_stream.end();
75 resample_stream.end();
76 read_count = 0;
77 }
78
86 size_t readBytes(uint8_t* data, size_t len) override {
87 if (p_buffer == nullptr) return 0;
88
89 return resample_stream.readBytes(data, len);
90 }
91
97 float recalculate() {
98 if (p_buffer == nullptr) return step_size;
99
100 // calculate new resampling step size
101 level_percent = p_buffer->levelPercent();
102 kalman_filter.addMeasurement(level_percent);
103 step_size = pid.calculate(50.0, kalman_filter.calculate());
104
105 // log step size every 100th read
106 if (read_count++ % 100 == 0) {
107 LOGI("step_size: %f", step_size);
108 }
109
110 // return resampled result
111 resample_stream.setStepSize(step_size);
112 return step_size;
113 }
114
120 void setStepRangePercent(float rangePercent) {
121 resample_range = rangePercent / 100.0;
122 }
123
130 if (p_buffer == nullptr) return 0.0f;
131 return p_buffer->levelPercent();
132 }
133
139 float levelPercent() { return level_percent; }
140
147 void setKalmanParameters(float process_noise, float measurement_noise) {
148 kalman_filter.begin(process_noise, measurement_noise);
149 }
150
158 void setPIDParameters(float p_value, float i_value, float d_value) {
159 p = p_value;
160 i = i_value;
161 d = d_value;
162 }
163
164protected:
165 PIDController pid; // PID controller for adaptive resampling step size (p=0.005, i=0.00005, d=0.0001)
166 QueueStream<uint8_t> queue_stream; // Internal queue stream for buffering audio data
167 BaseBuffer<uint8_t>* p_buffer = nullptr; // Pointer to the user-provided buffer
168 ResampleStream resample_stream; // Resample stream for adjusting playback rate
169 KalmanFilter kalman_filter{0.01f, 0.1f}; // Kalman filter for smoothing buffer fill level
170 float step_size = 1.0; // Current resampling step size
171 float resample_range = 0; // Allowed resampling range (fraction)
172 float p = 0.005; // PID proportional gain
173 float i = 0.00005; // PID integral gain
174 float d = 0.0001; // PID derivative gain
175 float level_percent = 0.0; // Last calculated buffer fill level (percent)
176 uint32_t read_count = 0; // Read operation counter
177};
178
179} // namespace audio_tools
An Audio Stream backed by a buffer (queue) which tries to correct jitter and automatically adjusts fo...
Definition AdaptiveResamplingStream.h:24
void setStepRangePercent(float rangePercent)
Set the allowed resampling range as a percent.
Definition AdaptiveResamplingStream.h:120
void setPIDParameters(float p_value, float i_value, float d_value)
Set the PID controller parameters.
Definition AdaptiveResamplingStream.h:158
size_t readBytes(uint8_t *data, size_t len) override
Read resampled audio data from the buffer.
Definition AdaptiveResamplingStream.h:86
bool begin()
Initialize the stream and internal components.
Definition AdaptiveResamplingStream.h:44
AdaptiveResamplingStream(BaseBuffer< uint8_t > &buffer, float stepRangePercent=5.0f)
Construct a new AdaptiveResamplingStream object.
Definition AdaptiveResamplingStream.h:32
size_t write(const uint8_t *data, size_t len) override
Write audio data to the buffer.
Definition AdaptiveResamplingStream.h:63
float levelPercent()
Get the fill level at the last calculation in percent.
Definition AdaptiveResamplingStream.h:139
void end()
End the stream and release resources.
Definition AdaptiveResamplingStream.h:73
void setKalmanParameters(float process_noise, float measurement_noise)
Set the Kalman filter parameters.
Definition AdaptiveResamplingStream.h:147
float levelPercentActual()
Get the current actual buffer fill level in percent.
Definition AdaptiveResamplingStream.h:129
float recalculate()
Recalculate the resampling step size based on buffer fill level.
Definition AdaptiveResamplingStream.h:97
virtual void addNotifyAudioChange(AudioInfoSupport &bi)
Adds target to be notified about audio changes.
Definition AudioTypes.h:153
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:122
virtual AudioInfo audioInfo() override
provides the actual input AudioInfo
Definition BaseStream.h:153
Shared functionality of all buffers.
Definition Buffers.h:22
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:55
virtual float levelPercent()
Returns the level of the buffer in %.
Definition Buffers.h:109
Simple 1D Kalman Filter for smoothing measurements.
Definition KalmanFilter.h:27
float calculate()
Returns the current estimated value.
Definition KalmanFilter.h:102
bool begin(float process_noise, float measurement_noise)
reset the filter with new parameters
Definition KalmanFilter.h:56
void addMeasurement(float measurement)
Updates the filter with a new measurement and returns the filtered value.
Definition KalmanFilter.h:87
A simple header only PID Controller.
Definition PIDController.h:15
Stream class which stores the data in a temporary queue buffer. The queue can be consumed e....
Definition BaseStream.h:311
virtual bool begin() override
Activates the output.
Definition BaseStream.h:339
virtual void end() override
stops the processing
Definition BaseStream.h:358
virtual void setStream(Stream &stream) override
Defines/Changes the input & output.
Definition AudioIO.h:158
Dynamic Resampling. We can use a variable factor to speed up or slow down the playback.
Definition ResampleStream.h:33
void setAudioInfo(AudioInfo newInfo) override
Defines the input AudioInfo.
Definition ResampleStream.h:123
void setStepSize(float step)
influence the sample rate
Definition ResampleStream.h:144
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10