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:
31 addNotifyAudioChange(resample_stream);
32 }
40 float stepRangePercent = 5.0f) {
41 setBuffer(buffer);
42 setStepRangePercent(stepRangePercent);
43 addNotifyAudioChange(resample_stream);
44 }
45
52 p_buffer = &buffer;
53 }
54
60 bool begin() {
61 if (p_buffer == nullptr) return false;
62 queue_stream.setBuffer(*p_buffer);
63 queue_stream.begin();
64 resample_stream.setAudioInfo(audioInfo());
65 resample_stream.setStream(queue_stream);
66 resample_stream.begin(audioInfo());
67 float from_step = 1.0 - resample_range;
68 float to_step = 1.0 + resample_range;
69 return pid.begin(1.0, from_step, to_step, p, i, d);
70 }
71
79 size_t write(const uint8_t* data, size_t len) override {
80 if (p_buffer == nullptr) return 0;
81 size_t result = p_buffer->writeArray(data, len);
83 return result;
84 }
85
89 void end() {
90 queue_stream.end();
91 resample_stream.end();
92 read_count = 0;
93 }
94
102 size_t readBytes(uint8_t* data, size_t len) override {
103 if (p_buffer == nullptr) return 0;
104
105 return resample_stream.readBytes(data, len);
106 }
107
113 float recalculate() {
114 if (p_buffer == nullptr) return step_size;
115
116 // calculate new resampling step size
117 level_percent = p_buffer->levelPercent();
118 kalman_filter.addMeasurement(level_percent);
119 step_size = pid.calculate(50.0, kalman_filter.calculate());
120
121 // log step size every 100th read
122 if (read_count++ % 100 == 0) {
123 LOGI("step_size: %f", step_size);
124 }
125
126 // return resampled result
127 resample_stream.setStepSize(step_size);
128 return step_size;
129 }
130
136 void setStepRangePercent(float rangePercent) {
137 resample_range = rangePercent / 100.0;
138 }
139
146 if (p_buffer == nullptr) return 0.0f;
147 return p_buffer->levelPercent();
148 }
149
155 float levelPercent() { return level_percent; }
156
163 void setKalmanParameters(float process_noise, float measurement_noise) {
164 kalman_filter.begin(process_noise, measurement_noise);
165 }
166
174 void setPIDParameters(float p_value, float i_value, float d_value) {
175 p = p_value;
176 i = i_value;
177 d = d_value;
178 }
179
180protected:
181 PIDController pid; // PID controller for adaptive resampling step size (p=0.005, i=0.00005, d=0.0001)
182 QueueStream<uint8_t> queue_stream; // Internal queue stream for buffering audio data
183 BaseBuffer<uint8_t>* p_buffer = nullptr; // Pointer to the user-provided buffer
184 ResampleStream resample_stream; // Resample stream for adjusting playback rate
185 KalmanFilter kalman_filter{0.01f, 0.1f}; // Kalman filter for smoothing buffer fill level
186 float step_size = 1.0; // Current resampling step size
187 float resample_range = 0; // Allowed resampling range (fraction)
188 float p = 0.00001; // PID proportional gain
189 float i = 0.00000001; // PID integral gain
190 float d = 0.0; // PID derivative gain
191 float level_percent = 0.0; // Last calculated buffer fill level (percent)
192 uint32_t read_count = 0; // Read operation counter
193};
194
195} // 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:136
void setBuffer(BaseBuffer< uint8_t > &buffer)
Set the buffer used for audio data.
Definition AdaptiveResamplingStream.h:51
void setPIDParameters(float p_value, float i_value, float d_value)
Set the PID controller parameters.
Definition AdaptiveResamplingStream.h:174
AdaptiveResamplingStream()
Construct a new AdaptiveResamplingStream object You need to call setBuffer() and setStepRangePercent(...
Definition AdaptiveResamplingStream.h:30
size_t readBytes(uint8_t *data, size_t len) override
Read resampled audio data from the buffer.
Definition AdaptiveResamplingStream.h:102
bool begin()
Initialize the stream and internal components.
Definition AdaptiveResamplingStream.h:60
AdaptiveResamplingStream(BaseBuffer< uint8_t > &buffer, float stepRangePercent=5.0f)
Construct a new AdaptiveResamplingStream object.
Definition AdaptiveResamplingStream.h:39
size_t write(const uint8_t *data, size_t len) override
Write audio data to the buffer.
Definition AdaptiveResamplingStream.h:79
float levelPercent()
Get the fill level at the last calculation in percent.
Definition AdaptiveResamplingStream.h:155
void end()
End the stream and release resources.
Definition AdaptiveResamplingStream.h:89
void setKalmanParameters(float process_noise, float measurement_noise)
Set the Kalman filter parameters.
Definition AdaptiveResamplingStream.h:163
float levelPercentActual()
Get the current actual buffer fill level in percent.
Definition AdaptiveResamplingStream.h:145
float recalculate()
Recalculate the resampling step size based on buffer fill level.
Definition AdaptiveResamplingStream.h:113
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