1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2017 - ROLI Ltd.
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 
23 namespace juce
24 {
25 
26 /**
27     Interpolator for resampling a stream of floats using Catmull-Rom interpolation.
28 
29     Note that the resampler is stateful, so when there's a break in the continuity
30     of the input stream you're feeding it, you should call reset() before feeding
31     it any new data. And like with any other stateful filter, if you're resampling
32     multiple channels, make sure each one uses its own CatmullRomInterpolator
33     object.
34 
35     @see LagrangeInterpolator
36 
37     @tags{Audio}
38 */
39 class JUCE_API  CatmullRomInterpolator
40 {
41 public:
42     CatmullRomInterpolator() noexcept;
43     ~CatmullRomInterpolator() noexcept;
44 
45     CatmullRomInterpolator (CatmullRomInterpolator&&) noexcept = default;
46     CatmullRomInterpolator& operator= (CatmullRomInterpolator&&) noexcept = default;
47 
48     /** Resets the state of the interpolator.
49         Call this when there's a break in the continuity of the input data stream.
50     */
51     void reset() noexcept;
52 
53     /** Resamples a stream of samples.
54 
55         @param speedRatio       the number of input samples to use for each output sample
56         @param inputSamples     the source data to read from. This must contain at
57                                 least (speedRatio * numOutputSamplesToProduce) samples.
58         @param outputSamples    the buffer to write the results into
59         @param numOutputSamplesToProduce    the number of output samples that should be created
60 
61         @returns the actual number of input samples that were used
62     */
63     int process (double speedRatio,
64                  const float* inputSamples,
65                  float* outputSamples,
66                  int numOutputSamplesToProduce) noexcept;
67 
68     /** Resamples a stream of samples.
69 
70         @param speedRatio       the number of input samples to use for each output sample
71         @param inputSamples     the source data to read from. This must contain at
72                                 least (speedRatio * numOutputSamplesToProduce) samples.
73         @param outputSamples    the buffer to write the results into
74         @param numOutputSamplesToProduce    the number of output samples that should be created
75         @param available        the number of available input samples. If it needs more samples
76                                 than available, it either wraps back for wrapAround samples, or
77                                 it feeds zeroes
78         @param wrapAround       if the stream exceeds available samples, it wraps back for
79                                 wrapAround samples. If wrapAround is set to 0, it will feed zeroes.
80 
81         @returns the actual number of input samples that were used
82     */
83     int process (double speedRatio,
84                  const float* inputSamples,
85                  float* outputSamples,
86                  int numOutputSamplesToProduce,
87                  int available,
88                  int wrapAround) noexcept;
89 
90     /** Resamples a stream of samples, adding the results to the output data
91         with a gain.
92 
93         @param speedRatio       the number of input samples to use for each output sample
94         @param inputSamples     the source data to read from. This must contain at
95                                 least (speedRatio * numOutputSamplesToProduce) samples.
96         @param outputSamples    the buffer to write the results to - the result values will be added
97                                 to any pre-existing data in this buffer after being multiplied by
98                                 the gain factor
99         @param numOutputSamplesToProduce    the number of output samples that should be created
100         @param gain             a gain factor to multiply the resulting samples by before
101                                 adding them to the destination buffer
102 
103         @returns the actual number of input samples that were used
104     */
105     int processAdding (double speedRatio,
106                        const float* inputSamples,
107                        float* outputSamples,
108                        int numOutputSamplesToProduce,
109                        float gain) noexcept;
110 
111     /** Resamples a stream of samples, adding the results to the output data
112         with a gain.
113 
114         @param speedRatio       the number of input samples to use for each output sample
115         @param inputSamples     the source data to read from. This must contain at
116                                 least (speedRatio * numOutputSamplesToProduce) samples.
117         @param outputSamples    the buffer to write the results to - the result values will be added
118                                 to any pre-existing data in this buffer after being multiplied by
119                                 the gain factor
120         @param numOutputSamplesToProduce    the number of output samples that should be created
121         @param available        the number of available input samples. If it needs more samples
122                                 than available, it either wraps back for wrapAround samples, or
123                                 it feeds zeroes
124         @param wrapAround       if the stream exceeds available samples, it wraps back for
125                                 wrapAround samples. If wrapAround is set to 0, it will feed zeroes.
126         @param gain             a gain factor to multiply the resulting samples by before
127                                 adding them to the destination buffer
128 
129         @returns the actual number of input samples that were used
130     */
131     int processAdding (double speedRatio,
132                        const float* inputSamples,
133                        float* outputSamples,
134                        int numOutputSamplesToProduce,
135                        int available,
136                        int wrapAround,
137                        float gain) noexcept;
138 
139 private:
140     float lastInputSamples[5];
141     double subSamplePos;
142 
143     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator)
144 };
145 
146 } // namespace juce
147