2#include "AudioTools/CoreAudio/AudioBasic/Collections/Vector.h"
3#include "AudioTools/CoreAudio/Buffers.h"
30 int size = vectorSize();
56 if (step >= 1.0f)
return false;
69 float valueExt(
float* y,
float xf) {
74 operator bool()
const {
76 if (step_copy >= 1.0)
return false;
74 operator bool()
const {
…}
98 virtual int vectorSize() = 0;
106 virtual float value(
float* y,
float xf) = 0;
125 if (xf == 0.0f)
return y[0];
126 if (xf == 1.0f)
return y[1];
130 return y[x] + dx * (y[x + 1] - y[x]);
153 float ym1py1 = y[x] + y[x + 2];
154 float c0 = 1.0f / 6.0f * ym1py1 + 2.0f / 3.0f * y[x + 1];
155 float c1 = 1.0f / 2.0f * (y[x + 2] - y[x]);
156 float c2 = 1.0f / 2.0f * ym1py1 - y[x + 1];
158 1.0f / 2.0f * (y[x + 1] - y[x + 2]) + 1.0f / 6.0f * (y[x + 3] - y[x]);
159 return ((c3 * dx + c2) * dx + c1) * dx + c0;
183 float c1 = y[x + 2] - 1.0f / 3.0f * y[x] - 1.0f / 2.0f * y[x + 1] -
184 1.0f / 6.0f * y[x + 3];
185 float c2 = 1.0f / 2.0f * (y[x] + y[x + 2]) - y[x + 1];
187 1.0f / 6.0f * (y[x + 3] - y[x]) + 1.0f / 2.0f * (y[x + 1] - y[x + 2]);
188 return ((c3 * dx + c2) * dx + c1) * dx + c0;
212 float c1 = 1.0f / 2.0f * (y[x + 2] - y[x]);
213 float c2 = y[x] - 5.0f / 2.0f * y[x + 1] + 2.0f * y[x + 2] -
214 1.0f / 2.0f * y[x + 3];
216 1.0f / 2.0f * (y[x + 3] - y[x]) + 3.0f / 2.0f * (y[x + 1] - y[x + 2]);
217 return ((c3 * dx + c2) * dx + c1) * dx + c0;
240 float y1mym1 = y[x + 2] - y[x];
241 float c0 = 1.0f / 2.0f * y[x + 1] + 1.0f / 4.0f * (y[x] + y[x + 2]);
242 float c1 = 1.0f / 2.0f * y1mym1;
243 float c2 = 1.0f / 4.0f * (y[x + 3] - y[x + 1] - y1mym1);
244 return (c2 * dx + c1) * dx + c0;
254template <
class TInterpolator>
263 for (
int i = 0; i < _channels; ++i) {
264 _resamplers[i].begin();
273 for (
int i = 0; i < _channels; ++i) {
274 _resamplers[i].setStepSize(step);
283 for (
int i = 0; i < _channels; ++i) {
284 _resamplers[i].addValue(values[i]);
288 void addValue(
float value,
int channel) {
289 if (channel < 0 || channel >= _channels) {
290 LOGE(
"Invalid channel index: %d", channel);
293 _resamplers[channel].addValue(value);
303 for (
int i = 0; i < _channels; ++i) {
304 ok &= _resamplers[i].getValue(out[i]);
309 operator bool()
const {
310 if (_channels <= 0)
return false;
311 return _resamplers[0] &&
static_cast<bool>(_resamplers[0]);
329template <
class TInterpolator>
385 cfg.step_size = step;
395 cfg.step_size =
static_cast<float>(cfg.
sample_rate) /
399 cfg.step_size = 1.0f;
411 cfg.step_size = step;
412 _resampler.setStepSize(step);
430 }
else if (cfg.step_size != 1.0f) {
439 size_t write(
const uint8_t* data,
size_t len)
override {
440 LOGD(
"ResampleStreamT::write: %d", (
int)len);
445 writeT<int16_t>(p_print, data, len, written);
448 writeT<int24_t>(p_print, data, len, written);
451 writeT<int32_t>(p_print, data, len, written);
439 size_t write(
const uint8_t* data,
size_t len)
override {
…}
466 _resampler.setChannels(newInfo.
channels);
471 cfg.step_size =
static_cast<float>(cfg.
sample_rate) /
477 float getByteFactor()
override {
return 1.0f / cfg.step_size; }
479 ResampleConfig defaultConfig() {
480 ResampleConfig result;
485 MultiChannelResampler<TInterpolator> _resampler;
489 template <
typename T>
492 if (p_out ==
nullptr)
return 0;
495 if (cfg.step_size == 1.0f) {
496 return p_out->write(buffer, bytes);
501 T* data = (T*)buffer;
502 float frame[channels];
503 size_t frames = bytes / (
sizeof(T) * channels);
504 size_t frames_written = 0;
505 for (
size_t i = 0; i < frames; ++i) {
507 for (
int ch = 0; ch < channels; ++ch) {
508 frame[ch] =
static_cast<float>(data[i * channels + ch]);
512 _resampler.addValues(frame);
515 float result[channels];
516 while (_resampler.getValues(result)) {
519 for (
int ch = 0; ch < channels; ++ch) {
520 resultT[ch] = NumberConverter::clipT<T>(result[ch]);
524 size_t to_write =
sizeof(T) * channels;
525 size_t written = p_out->write((
const uint8_t*)resultT, to_write);
526 if (written != to_write) {
527 LOGE(
"write error %zu -> %zu", to_write, written);
533 return frames_written *
sizeof(T) * channels;