LMMS
Loading...
Searching...
No Matches
juce_GenericInterpolator.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
39template <class InterpolatorTraits, int memorySize>
41{
42public:
44
47
54 {
55 return InterpolatorTraits::algorithmicLatency;
56 }
57
63 {
64 indexBuffer = 0;
65 subSamplePos = 1.0;
66 std::fill (std::begin (lastInputSamples), std::end (lastInputSamples), 0.0f);
67 }
68
79 int process (double speedRatio,
80 const float* inputSamples,
81 float* outputSamples,
82 int numOutputSamplesToProduce) noexcept
83 {
84 return interpolate (speedRatio, inputSamples, outputSamples, numOutputSamplesToProduce);
85 }
86
102 int process (double speedRatio,
103 const float* inputSamples,
104 float* outputSamples,
105 int numOutputSamplesToProduce,
106 int numInputSamplesAvailable,
107 int wrapAround) noexcept
108 {
109 return interpolate (speedRatio, inputSamples, outputSamples,
110 numOutputSamplesToProduce, numInputSamplesAvailable, wrapAround);
111 }
112
128 int processAdding (double speedRatio,
129 const float* inputSamples,
130 float* outputSamples,
131 int numOutputSamplesToProduce,
132 float gain) noexcept
133 {
134 return interpolateAdding (speedRatio, inputSamples, outputSamples, numOutputSamplesToProduce, gain);
135 }
136
157 int processAdding (double speedRatio,
158 const float* inputSamples,
159 float* outputSamples,
160 int numOutputSamplesToProduce,
161 int numInputSamplesAvailable,
162 int wrapAround,
163 float gain) noexcept
164 {
165 return interpolateAdding (speedRatio, inputSamples, outputSamples,
166 numOutputSamplesToProduce, numInputSamplesAvailable, wrapAround, gain);
167 }
168
169private:
170 //==============================================================================
171 forcedinline void pushInterpolationSample (float newValue) noexcept
172 {
173 lastInputSamples[indexBuffer] = newValue;
174
175 if (++indexBuffer == memorySize)
176 indexBuffer = 0;
177 }
178
179 forcedinline void pushInterpolationSamples (const float* input,
180 int numOutputSamplesToProduce) noexcept
181 {
182 if (numOutputSamplesToProduce >= memorySize)
183 {
184 const auto* const offsetInput = input + (numOutputSamplesToProduce - memorySize);
185
186 for (int i = 0; i < memorySize; ++i)
187 pushInterpolationSample (offsetInput[i]);
188 }
189 else
190 {
191 for (int i = 0; i < numOutputSamplesToProduce; ++i)
192 pushInterpolationSample (input[i]);
193 }
194 }
195
196 forcedinline void pushInterpolationSamples (const float* input,
197 int numOutputSamplesToProduce,
198 int numInputSamplesAvailable,
199 int wrapAround) noexcept
200 {
201 if (numOutputSamplesToProduce >= memorySize)
202 {
203 if (numInputSamplesAvailable >= memorySize)
204 {
206 numOutputSamplesToProduce);
207 }
208 else
209 {
210 pushInterpolationSamples (input + ((numOutputSamplesToProduce - numInputSamplesAvailable) - 1),
211 numInputSamplesAvailable);
212
213 if (wrapAround > 0)
214 {
215 numOutputSamplesToProduce -= wrapAround;
216
217 pushInterpolationSamples (input + ((numOutputSamplesToProduce - (memorySize - numInputSamplesAvailable)) - 1),
218 memorySize - numInputSamplesAvailable);
219 }
220 else
221 {
222 for (int i = numInputSamplesAvailable; i < memorySize; ++i)
224 }
225 }
226 }
227 else
228 {
229 if (numOutputSamplesToProduce > numInputSamplesAvailable)
230 {
231 for (int i = 0; i < numInputSamplesAvailable; ++i)
232 pushInterpolationSample (input[i]);
233
234 const auto extraSamples = numOutputSamplesToProduce - numInputSamplesAvailable;
235
236 if (wrapAround > 0)
237 {
238 const auto* const offsetInput = input + (numInputSamplesAvailable - wrapAround);
239
240 for (int i = 0; i < extraSamples; ++i)
241 pushInterpolationSample (offsetInput[i]);
242 }
243 else
244 {
245 for (int i = 0; i < extraSamples; ++i)
247 }
248 }
249 else
250 {
251 for (int i = 0; i < numOutputSamplesToProduce; ++i)
252 pushInterpolationSample (input[i]);
253 }
254 }
255 }
256
257 //==============================================================================
258 int interpolate (double speedRatio,
259 const float* input,
260 float* output,
261 int numOutputSamplesToProduce) noexcept
262 {
263 auto pos = subSamplePos;
264 int numUsed = 0;
265
266 while (numOutputSamplesToProduce > 0)
267 {
268 while (pos >= 1.0)
269 {
270 pushInterpolationSample (input[numUsed++]);
271 pos -= 1.0;
272 }
273
274 *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer);
275 pos += speedRatio;
276 --numOutputSamplesToProduce;
277 }
278
279 subSamplePos = pos;
280 return numUsed;
281 }
282
283 int interpolate (double speedRatio,
284 const float* input, float* output,
285 int numOutputSamplesToProduce,
286 int numInputSamplesAvailable,
287 int wrap) noexcept
288 {
289 auto originalIn = input;
290 auto pos = subSamplePos;
291 bool exceeded = false;
292
293 if (speedRatio < 1.0)
294 {
295 for (int i = numOutputSamplesToProduce; --i >= 0;)
296 {
297 if (pos >= 1.0)
298 {
299 if (exceeded)
300 {
302 }
303 else
304 {
305 pushInterpolationSample (*input++);
306
307 if (--numInputSamplesAvailable <= 0)
308 {
309 if (wrap > 0)
310 {
311 input -= wrap;
312 numInputSamplesAvailable += wrap;
313 }
314 else
315 {
316 exceeded = true;
317 }
318 }
319 }
320
321 pos -= 1.0;
322 }
323
324 *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer);
325 pos += speedRatio;
326 }
327 }
328 else
329 {
330 for (int i = numOutputSamplesToProduce; --i >= 0;)
331 {
332 while (pos < speedRatio)
333 {
334 if (exceeded)
335 {
337 }
338 else
339 {
340 pushInterpolationSample (*input++);
341
342 if (--numInputSamplesAvailable <= 0)
343 {
344 if (wrap > 0)
345 {
346 input -= wrap;
347 numInputSamplesAvailable += wrap;
348 }
349 else
350 {
351 exceeded = true;
352 }
353 }
354 }
355
356 pos += 1.0;
357 }
358
359 pos -= speedRatio;
360 *output++ = InterpolatorTraits::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos), indexBuffer);
361 }
362 }
363
364 subSamplePos = pos;
365
366 if (wrap == 0)
367 return (int) (input - originalIn);
368
369 return ((int) (input - originalIn) + wrap) % wrap;
370 }
371
372 int interpolateAdding (double speedRatio,
373 const float* input,
374 float* output,
375 int numOutputSamplesToProduce,
376 int numInputSamplesAvailable,
377 int wrap,
378 float gain) noexcept
379 {
380 auto originalIn = input;
381 auto pos = subSamplePos;
382 bool exceeded = false;
383
384 if (speedRatio < 1.0)
385 {
386 for (int i = numOutputSamplesToProduce; --i >= 0;)
387 {
388 if (pos >= 1.0)
389 {
390 if (exceeded)
391 {
393 }
394 else
395 {
396 pushInterpolationSample (*input++);
397
398 if (--numInputSamplesAvailable <= 0)
399 {
400 if (wrap > 0)
401 {
402 input -= wrap;
403 numInputSamplesAvailable += wrap;
404 }
405 else
406 {
407 numInputSamplesAvailable = true;
408 }
409 }
410 }
411
412 pos -= 1.0;
413 }
414
415 *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer);
416 pos += speedRatio;
417 }
418 }
419 else
420 {
421 for (int i = numOutputSamplesToProduce; --i >= 0;)
422 {
423 while (pos < speedRatio)
424 {
425 if (exceeded)
426 {
428 }
429 else
430 {
431 pushInterpolationSample (*input++);
432
433 if (--numInputSamplesAvailable <= 0)
434 {
435 if (wrap > 0)
436 {
437 input -= wrap;
438 numInputSamplesAvailable += wrap;
439 }
440 else
441 {
442 exceeded = true;
443 }
444 }
445 }
446
447 pos += 1.0;
448 }
449
450 pos -= speedRatio;
451 *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos), indexBuffer);
452 }
453 }
454
455 subSamplePos = pos;
456
457 if (wrap == 0)
458 return (int) (input - originalIn);
459
460 return ((int) (input - originalIn) + wrap) % wrap;
461 }
462
463 int interpolateAdding (double speedRatio,
464 const float* input,
465 float* output,
466 int numOutputSamplesToProduce,
467 float gain) noexcept
468 {
469 auto pos = subSamplePos;
470 int numUsed = 0;
471
472 while (numOutputSamplesToProduce > 0)
473 {
474 while (pos >= 1.0)
475 {
476 pushInterpolationSample (input[numUsed++]);
477 pos -= 1.0;
478 }
479
480 *output++ += gain * InterpolatorTraits::valueAtOffset (lastInputSamples, (float) pos, indexBuffer);
481 pos += speedRatio;
482 --numOutputSamplesToProduce;
483 }
484
485 subSamplePos = pos;
486 return numUsed;
487 }
488
489 //==============================================================================
490 float lastInputSamples[(size_t) memorySize];
491 double subSamplePos = 1.0;
492 int indexBuffer = 0;
493
495};
496
497} // namespace juce
#define constexpr
Definition CarlaDefines.h:94
#define noexcept
Definition DistrhoDefines.h:72
float interpolate(const float *data, size_t len, float pos)
Definition Util.cpp:215
double subSamplePos
Definition juce_GenericInterpolator.h:491
int process(double speedRatio, const float *inputSamples, float *outputSamples, int numOutputSamplesToProduce, int numInputSamplesAvailable, int wrapAround) noexcept
Definition juce_GenericInterpolator.h:102
forcedinline void pushInterpolationSample(float newValue) noexcept
Definition juce_GenericInterpolator.h:171
int process(double speedRatio, const float *inputSamples, float *outputSamples, int numOutputSamplesToProduce) noexcept
Definition juce_GenericInterpolator.h:79
GenericInterpolator(GenericInterpolator &&) noexcept=default
int indexBuffer
Definition juce_GenericInterpolator.h:492
forcedinline void pushInterpolationSamples(const float *input, int numOutputSamplesToProduce, int numInputSamplesAvailable, int wrapAround) noexcept
Definition juce_GenericInterpolator.h:196
int interpolateAdding(double speedRatio, const float *input, float *output, int numOutputSamplesToProduce, float gain) noexcept
Definition juce_GenericInterpolator.h:463
int processAdding(double speedRatio, const float *inputSamples, float *outputSamples, int numOutputSamplesToProduce, int numInputSamplesAvailable, int wrapAround, float gain) noexcept
Definition juce_GenericInterpolator.h:157
GenericInterpolator() noexcept
Definition juce_GenericInterpolator.h:43
float lastInputSamples[(size_t) memorySize]
Definition juce_GenericInterpolator.h:490
int interpolate(double speedRatio, const float *input, float *output, int numOutputSamplesToProduce, int numInputSamplesAvailable, int wrap) noexcept
Definition juce_GenericInterpolator.h:283
void reset() noexcept
Definition juce_GenericInterpolator.h:62
int processAdding(double speedRatio, const float *inputSamples, float *outputSamples, int numOutputSamplesToProduce, float gain) noexcept
Definition juce_GenericInterpolator.h:128
int interpolateAdding(double speedRatio, const float *input, float *output, int numOutputSamplesToProduce, int numInputSamplesAvailable, int wrap, float gain) noexcept
Definition juce_GenericInterpolator.h:372
forcedinline void pushInterpolationSamples(const float *input, int numOutputSamplesToProduce) noexcept
Definition juce_GenericInterpolator.h:179
int interpolate(double speedRatio, const float *input, float *output, int numOutputSamplesToProduce) noexcept
Definition juce_GenericInterpolator.h:258
static constexpr float getBaseLatency() noexcept
Definition juce_GenericInterpolator.h:53
register unsigned i
Definition inflate.c:1575
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
#define forcedinline
#define JUCE_API
Definition juce_StandardHeader.h:152
Definition carla_juce.cpp:31
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94