tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_ModifierInternal.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
14namespace PredefinedWavetable
15{
16 static inline float getSinSample (float phase)
17 {
18 return (std::sin (phase * juce::MathConstants<float>::pi * 2.0f) + 1.0f) / 2.0f;
19 }
20
21 static inline float getTriangleSample (float phase)
22 {
23 return (phase < 0.5f) ? (2.0f * phase) : (-2.0f * phase + 2.0f);
24 }
25
26 static inline float getSawUpSample (float phase)
27 {
28 return phase;
29 }
30
31 static inline float getSawDownSample (float phase)
32 {
33 return 1.0f - phase;
34 }
35
36 static inline float getSquareSample (float phase)
37 {
38 return phase < 0.5f ? 1.0f : 0.0f;
39 }
40
41 static inline float getStepsUpSample (float phase, int totalNumSteps)
42 {
43 jassert (totalNumSteps > 1);
44 const float stageAmmount = 1.0f / (totalNumSteps - 1);
45
46 const int stage = juce::jlimit (0, totalNumSteps - 1, (int) std::floor (phase * totalNumSteps));
47
48 return stageAmmount * stage;
49 }
50
51 static inline float getStepsDownSample (float phase, int totalNumStages)
52 {
53 return getStepsUpSample (1.0f - phase, totalNumStages);
54 }
55}
56
58struct Ramp
59{
60 Ramp() = default;
61
62 void setDuration (float newDuration) noexcept
63 {
64 jassert (newDuration > 0.0f);
65 rampDuration = newDuration;
66 process (0.0f); // Re-sync ramp pos
67 }
68
69 void setPosition (float newPosition) noexcept
70 {
71 jassert (juce::isPositiveAndBelow (newPosition, rampDuration));
72 rampPos = juce::jlimit (0.0f, rampDuration, newPosition) / rampDuration;
73 }
74
75 void process (float duration) noexcept
76 {
77 rampPos += (duration / rampDuration);
78
79 while (rampPos > 1.0f)
80 rampPos -= 1.0f;
81 }
82
83 float getPosition() const noexcept
84 {
85 return rampPos * rampDuration;
86 }
87
88 float getProportion() const noexcept
89 {
90 return rampPos;
91 }
92
93private:
94 float rampPos = 0.0f, rampDuration = 1.0f;
95};
96
97//==============================================================================
98namespace modifier
99{
100 inline juce::StringArray getEnabledNames()
101 {
102 return { NEEDS_TRANS("Disabled"),
103 NEEDS_TRANS("Enabled") };
104 }
105}
106
107//==============================================================================
109{
111 const juce::String& name,
112 AutomatableEditItem& owner,
113 juce::Range<float> valueRangeToUse,
114 int numStatesToUse = 0,
115 juce::StringArray labelsToUse = {})
116 : AutomatableParameter (xmlTag, name, owner, valueRangeToUse),
117 numStates (numStatesToUse), labels (labelsToUse)
118 {
119 jassert (labels.isEmpty() || labels.size() == numStates);
120 }
121
123 {
124 notifyListenersOfDeletion();
125 }
126
127 bool isDiscrete() const override { return numStates != 0; }
128 int getNumberOfStates() const override { return numStates; }
129
130 float getValueForState (int i) const override
131 {
132 if (numStates == 0)
133 return 0.0;
134
135 return juce::jmap ((float) i, 0.0f, float (numStates - 1), valueRange.start, valueRange.end);
136 }
137
138 int getStateForValue (float value) const override
139 {
140 if (numStates == 0)
141 return 0;
142
143 return juce::roundToInt (juce::jmap (value, valueRange.start, valueRange.end, 0.0f, float (numStates - 1)));
144 }
145
146 bool hasLabels() const override { return labels.size() > 0; }
147 juce::StringArray getAllLabels() const override { return labels; }
148
149 juce::String getLabelForValue (float val) const override
150 {
151 const int s = getStateForValue (val);
152
153 return juce::isPositiveAndBelow (s, getNumberOfStates()) ? labels[s] : juce::String();
154 }
155
156 float snapToState (float val) const override
157 {
158 return getValueForState (juce::jlimit (0, getNumberOfStates() - 1, juce::roundToInt (val)));
159 }
160
161private:
162 const int numStates = 0;
163 const juce::StringArray labels;
164
166};
167
168//==============================================================================
170{
171 SuffixedParameter (const juce::String& xmlTag, const juce::String& name,
173 juce::String suffixToUse = {})
174 : AutomatableParameter (xmlTag, name, owner, valueRangeToUse),
175 suffix (suffixToUse)
176 {
177 }
178
179 ~SuffixedParameter() override
180 {
181 notifyListenersOfDeletion();
182 }
183
184 juce::String valueToString (float value) override
185 {
186 if (valueRange.interval == 1.0f)
187 return juce::String (juce::roundToInt (value));
188
189 return AutomatableParameter::valueToString (value);
190 }
191
192 juce::String getLabel() override { return suffix; }
193
194 const juce::String suffix;
195
197};
198
199//==============================================================================
200//==============================================================================
201static inline AutomatableParameter* createDiscreteParameter (AutomatableEditItem& item,
202 const juce::String& paramID, const juce::String& name,
203 juce::Range<float> valueRange,
205 const juce::StringArray& labels)
206{
207 auto p = new DiscreteLabelledParameter (paramID, name, item, valueRange, labels.size(), labels);
208 p->attachToCurrentValue (val);
209
210 return p;
211}
212
213static inline AutomatableParameter* createSuffixedParameter (AutomatableEditItem& item,
214 const juce::String& paramID, const juce::String& name,
215 juce::NormalisableRange<float> valueRange, float centreVal,
217 const juce::String& suffix)
218{
219 valueRange.setSkewForCentre (centreVal);
220 auto p = new SuffixedParameter (paramID, name, item, valueRange, suffix);
221 p->attachToCurrentValue (val);
222
223 return p;
224}
225
226}} // namespace tracktion { inline namespace engine
void setSkewForCentre(ValueType centrePointValue) noexcept
int size() const noexcept
bool isEmpty() const noexcept
Base class for elements that have some kind of automatable parameters.
T floor(T... args)
#define NEEDS_TRANS(stringLiteral)
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
typedef float
constexpr Type jmap(Type value0To1, Type targetRangeMin, Type targetRangeMax)
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
int roundToInt(const FloatType value) noexcept
T sin(T... args)
A ramp which goes between 0 and 1 over a set duration.