iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
ControlRamp.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9 */
10
11#pragma once
12
18#include <array>
19#include <functional>
20#include <iostream>
21#include <utility>
22
23BEGIN_IPLUG_NAMESPACE
24
33{
34 double startValue;
35 double endValue;
36 int transitionStart;
37 int transitionEnd;
38
39 void Clear()
40 {
41 startValue = endValue = 0.;
42 transitionStart = transitionEnd = 0;
43 }
44
45 bool IsNonzero() const
46 {
47 return (startValue != 0.) || (endValue != 0.);
48 }
49
54 void Write(float* buffer, int startIdx, int nFrames)
55 {
56 float val = static_cast<float>(startValue);
57 float dv = static_cast<float>((endValue - startValue)/(transitionEnd - transitionStart));
58
59 for(int i=startIdx; i<startIdx + transitionStart; ++i)
60 {
61 buffer[i] = val;
62 }
63 for(int i=startIdx + transitionStart; i<startIdx + transitionEnd; ++i)
64 {
65 val += dv;
66 buffer[i] = val;
67 }
68 for(int i=startIdx + transitionEnd; i<startIdx + nFrames; ++i)
69 {
70 buffer[i] = val;
71 }
72 }
73
74 template<size_t N>
75 using RampArray = std::array<ControlRamp, N>;
76};
77
79{
80public:
81
82 template<size_t N>
83 using RampArray = ControlRamp::RampArray<N>;
84
85 template<size_t N>
86 using ProcessorArray = std::array<ControlRampProcessor, N>;
87
88 ControlRampProcessor(ControlRamp& output) : mpOutput(output) {}
90 ControlRampProcessor& operator=(const ControlRampProcessor&) = delete;
92 ControlRampProcessor& operator=(ControlRampProcessor&&) = delete;
93
94 // process the glide and write changes to the output ramp.
95 void Process(int blockSize)
96 {
97 // always connect with previous block
98 mpOutput.startValue = mpOutput.endValue;
99
100 if(mSamplesRemaining)
101 {
102 if(mSamplesRemaining == mGlideSamples)
103 {
104 // start glide
105 if(mSamplesRemaining > blockSize)
106 {
107 // start with ramp to block end
108 int glideStartSamples = blockSize - mStartOffset;
109 mpOutput.endValue = mpOutput.startValue + glideStartSamples*mChangePerSample;
110 mpOutput.transitionStart = mStartOffset;
111 mpOutput.transitionEnd = blockSize;
112 mSamplesRemaining -= glideStartSamples;
113 }
114 else
115 {
116 // glide starts and finishes within block
117 mpOutput.endValue = mTargetValue;
118 mpOutput.transitionStart = mStartOffset;
119 mpOutput.transitionEnd = mStartOffset + mGlideSamples;
120 mSamplesRemaining = 0;
121 }
122 }
123 else if(mSamplesRemaining > blockSize)
124 {
125 // continue glide
126 mpOutput.endValue = mpOutput.startValue + mChangePerSample*blockSize;
127 mpOutput.transitionStart = 0;
128 mpOutput.transitionEnd = blockSize;
129 mSamplesRemaining -= blockSize;
130 }
131 else
132 {
133 // finish glide
134 mpOutput.endValue = mTargetValue;
135 mpOutput.transitionStart = 0;
136 mpOutput.transitionEnd = mSamplesRemaining;
137 mSamplesRemaining = 0;
138 }
139 }
140 }
141
142 // set the next target for the glide without writing directly to the ramp.
143 void SetTarget(double targetValue, int startOffset, int glideSamples, int blockSize)
144 {
145 mTargetValue = targetValue;
146 if(glideSamples < 1) glideSamples = 1;
147 mGlideSamples = glideSamples;
148 mSamplesRemaining = glideSamples;
149 mChangePerSample = (targetValue - mpOutput.endValue)/glideSamples;
150 mStartOffset = startOffset;
151 }
152
153 // create an array of processors for an array of ramps
154 template<size_t N>
155 static ProcessorArray<N>* Create(RampArray<N>& inputs)
156 {
157 return CreateImpl<N>(inputs, std::make_index_sequence<N>());
158 }
159
160private:
161
162 template<size_t N, size_t ...Is>
163 static ProcessorArray<N>* CreateImpl(RampArray<N>& inputs, std::index_sequence<Is...>)
164 {
165 return new ProcessorArray<N>{std::ref(inputs[Is]).get()...};
166 }
167
168 ControlRamp& mpOutput;
169 double mTargetValue {0.};
170 double mChangePerSample {0.};
171 int mGlideSamples {0};
172 int mSamplesRemaining {0};
173 int mStartOffset {0};
174};
175
176END_IPLUG_NAMESPACE
A ControlRamp describes one value changing over time.
Definition: ControlRamp.h:33
void Write(float *buffer, int startIdx, int nFrames)
Writes the ramp signal to an output buffer.
Definition: ControlRamp.h:54