Krotos Modules 3
Loading...
Searching...
No Matches
KwidgetProcessor_Reformer.cpp
Go to the documentation of this file.
1namespace krotos
2{
4 : KwidgetProcessor(owner), m_soSound(sound), m_attachmentCache(RGParam::NUM_PARAMS)
5 {
6 addParameterAttachments({{Parameters::Start, nullptr, -1}, {Parameters::PuckX, nullptr, -1},
7 {Parameters::PuckY, nullptr, -1}, {Parameters::Nearest, nullptr, -1},
8 {Parameters::Size, nullptr, -1}, {Parameters::Rate, nullptr, -1},
9 {Parameters::Pitch, nullptr, -1}, {Parameters::PitchMod, nullptr, -1},
10 {Parameters::Width, nullptr, -1}, {Parameters::Pan, nullptr, -1},
11 {Parameters::Level, nullptr, -1}, {Parameters::GranularLevel, nullptr, -1},
12 {Parameters::LevelMod, nullptr, -1}, {Parameters::StartRand, nullptr, -1},
13 {Parameters::SizeRand, nullptr, -1}, {Parameters::RateRand, nullptr, -1},
14 {Parameters::PitchRand, nullptr, -1}, {Parameters::WidthRand, nullptr, -1},
15 {Parameters::PanRand, nullptr, -1}, {Parameters::LevelRand, nullptr, -1},
16 {Parameters::Popcorn, nullptr, -1}, {Parameters::Quench, nullptr, -1},
17 {Parameters::Robin, nullptr, -1}, {Parameters::SALoop, nullptr, -1},
18 {Parameters::Normalise, nullptr, -1}, {Parameters::Autoplay, nullptr, -1},
19 {Parameters::Shape, nullptr, -1}, {Parameters::GrainMax, nullptr, -1},
20 {Parameters::Segmentation, nullptr, -1}, {Parameters::FeatureExtr, nullptr, -1},
21 {Parameters::Mute, nullptr, -1}, {Parameters::Solo, nullptr, -1},
22 {Parameters::MIDIMode, nullptr, -1}, {Parameters::Tracking, nullptr, -1},
23 {Parameters::Coeff0, nullptr, -1}, {Parameters::Coeff1, nullptr, -1},
24 {Parameters::Coeff2, nullptr, -1}, {Parameters::Coeff3, nullptr, -1},
25 {Parameters::Coeff4, nullptr, -1}, {Parameters::Coeff5, nullptr, -1},
26 {Parameters::Coeff6, nullptr, -1}, {Parameters::Coeff7, nullptr, -1},
27 {Parameters::SelectX, nullptr, -1}, {Parameters::SelectY, nullptr, -1},
28 {Parameters::SelectZ, nullptr, -1}, {Parameters::Proximity, nullptr, -1},
29 {Parameters::Radius, nullptr, -1}});
30
31 // Set up KAttachment* cache
65
67 }
68
69 void KwidgetProcessor_Reformer::prepare(double sampleRate, int samplesPerBlock)
70 {
71 m_soSound.Prepare(30, static_cast<float>(sampleRate));
72 m_oscillator.setSampleRate(sampleRate);
73 m_oscillator.setBlockSize(static_cast<size_t>(samplesPerBlock));
74 }
75
76 void KwidgetProcessor_Reformer::process(AudioBuffer<float>& buffer)
77 {
78 String accessID = "Reformer::process::" + getKwidgetID();
79 if (m_soSound.requestAccess(accessID))
80 {
82
84 }
85 else
86 {
87 auto numSamples = buffer.getNumSamples();
88 nextBlock(numSamples);
89 }
90 }
91
93 {
94 // We always return active so we can hold onto the voice even
95 // when playing grains sparsely (ie there is silence between grains)
96 // In addition, in popcorn mode grains may stop playing when the user
97 // stops moving the puck, so we need to hold onto the voice so that
98 // playing can resume if the user resumes moving the puck
99 // The voice will ultimately be terminated in these cases when the
100 // child kwidget ADSR times out at the end of its cycle
101 return true;
102 }
103
104 void KwidgetProcessor_Reformer::processBlockInternal(AudioBuffer<float>& buffer)
105 {
106 auto numSamples = buffer.getNumSamples();
107 auto numChannels = buffer.getNumChannels();
108 auto bufferPtr = const_cast<float**>(buffer.getArrayOfWritePointers());
109
110 nextBlock(numSamples);
111
112 m_oscillator.setGranularParameter(RGParam::Start, m_attachmentCache[RGParam::Start]->data());
113 m_oscillator.setGranularParameter(RGParam::PuckX, m_attachmentCache[RGParam::PuckX]->data());
114 m_oscillator.setGranularParameter(RGParam::PuckY, m_attachmentCache[RGParam::PuckY]->data());
115 m_oscillator.setGranularParameter(RGParam::Nearest, m_attachmentCache[RGParam::Nearest]->data());
116 m_oscillator.setGranularParameter(RGParam::StartRand, m_attachmentCache[RGParam::StartRand]->data());
117 m_oscillator.setGranularParameter(RGParam::Size, m_attachmentCache[RGParam::Size]->data());
118 m_oscillator.setGranularParameter(RGParam::SizeRand, m_attachmentCache[RGParam::SizeRand]->data());
119 m_oscillator.setGranularParameter(RGParam::Rate, m_attachmentCache[RGParam::Rate]->data());
120 m_oscillator.setGranularParameter(RGParam::RateRand, m_attachmentCache[RGParam::RateRand]->data());
121 m_oscillator.setGranularParameter(RGParam::Width, m_attachmentCache[RGParam::Width]->data());
122 m_oscillator.setGranularParameter(RGParam::WidthRand, m_attachmentCache[RGParam::WidthRand]->data());
123 m_oscillator.setGranularParameter(RGParam::Pan, m_attachmentCache[RGParam::Pan]->data());
124 m_oscillator.setGranularParameter(RGParam::PanRand, m_attachmentCache[RGParam::PanRand]->data());
125 m_oscillator.setGranularParameter(RGParam::Detune, m_attachmentCache[RGParam::Detune]->data());
126 m_oscillator.setGranularParameter(RGParam::DetuneMod, m_attachmentCache[RGParam::DetuneMod]->data());
127 m_oscillator.setGranularParameter(RGParam::DetuneRand, m_attachmentCache[RGParam::DetuneRand]->data());
128 m_oscillator.setGranularParameter(RGParam::Level, m_attachmentCache[RGParam::Level]->data());
129 m_oscillator.setGranularParameter(RGParam::GranularLevel, m_attachmentCache[RGParam::GranularLevel]->data());
130 m_oscillator.setGranularParameter(RGParam::LevelMod, m_attachmentCache[RGParam::LevelMod]->data());
131 m_oscillator.setGranularParameter(RGParam::LevelRand, m_attachmentCache[RGParam::LevelRand]->data());
132 m_oscillator.setGranularParameter(RGParam::Popcorn, m_attachmentCache[RGParam::Popcorn]->data());
133 m_oscillator.setGranularParameter(RGParam::Quench, m_attachmentCache[RGParam::Quench]->data());
134 m_oscillator.setGranularParameter(RGParam::Robin, m_attachmentCache[RGParam::Robin]->data());
135 m_oscillator.setGranularParameter(RGParam::SALoop, m_attachmentCache[RGParam::SALoop]->data());
136 m_oscillator.setGranularParameter(RGParam::Shape, m_attachmentCache[RGParam::Shape]->data());
137 m_oscillator.setGranularParameter(RGParam::GrainLim, m_attachmentCache[RGParam::GrainLim]->data());
138 m_oscillator.setGranularParameter(RGParam::Tracking, m_attachmentCache[RGParam::Tracking]->data());
139 m_oscillator.setGranularParameter(RGParam::Normalise, m_attachmentCache[RGParam::Normalise]->data());
140 m_oscillator.setGranularParameter(RGParam::Mute, m_attachmentCache[RGParam::Mute]->data());
141 m_oscillator.setGranularParameter(RGParam::Solo, m_attachmentCache[RGParam::Solo]->data());
142 m_oscillator.setGranularParameter(RGParam::Autoplay, m_attachmentCache[RGParam::Autoplay]->data());
143 m_oscillator.setGranularParameter(RGParam::Proximity, m_attachmentCache[RGParam::Proximity]->data());
144 m_oscillator.setGranularParameter(RGParam::Radius, m_attachmentCache[RGParam::Radius]->data());
145
146 Point<float> puckPosition(m_attachmentCache[RGParam::PuckX]->data()[0],
147 m_attachmentCache[RGParam::PuckY]->data()[0]);
149
150 float velocity = m_oscillator.getVelocity();
151
152 // Get current Mute Param value
153 float muteValue = m_attachmentCache[RGParam::Mute]->data()[0];
154
155 if (numChannels == 1) // mono
156 {
157 for (size_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
158 {
159 nextSample();
160 auto samp = m_oscillator.getNextStereoSample(sampleIndex) * velocity;
161 bufferPtr[0][sampleIndex] = (samp.left + samp.right) * 0.5f;
162 }
163 }
164 else // stereo
165 {
166 processMuteStereo(muteValue, numSamples, velocity, bufferPtr);
167 }
168
169 // Update former mute value
170 m_formerMuteVal = muteValue;
171 }
172
173 void KwidgetProcessor_Reformer::processMuteStereo(float currentMuteValue, int numSamples, float velocity,
174 float** bufferPtr)
175 {
176 if (currentMuteValue == 1.0f) // mute activated
177 {
178 if (m_formerMuteVal < currentMuteValue && m_formerMuteVal > 0.0f) // we just changed to mute
179 {
180 // do ramping down to 0
181 for (size_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
182 {
183 nextSample();
184 float ramp = sampleIndex / (numSamples - 1.0f);
185 float atten = 1.0f - ramp;
186 auto samp = (m_oscillator.getNextStereoSample(sampleIndex) * velocity) * atten;
187 bufferPtr[0][sampleIndex] = samp.left;
188 bufferPtr[1][sampleIndex] = samp.right;
189 }
190 }
191 else // we were in mute
192 {
193 // just zero
194 for (size_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
195 {
196 nextSample();
197 auto samp = m_oscillator.getNextStereoSample(sampleIndex) * velocity * 0.0f;
198 bufferPtr[0][sampleIndex] = samp.left;
199 bufferPtr[1][sampleIndex] = samp.right;
200 }
201 }
202 }
203 else // mute not activated
204 {
205 if (m_formerMuteVal > currentMuteValue && currentMuteValue > 0.5f) // we just unmuted
206 {
207 for (size_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
208 {
209 nextSample();
210 float ramp = sampleIndex / (numSamples - 1.0f);
211 auto samp = (m_oscillator.getNextStereoSample(sampleIndex) * velocity) * ramp;
212 bufferPtr[0][sampleIndex] = samp.left;
213 bufferPtr[1][sampleIndex] = samp.right;
214 }
215 }
216 else // we were unmuted
217 {
218 for (size_t sampleIndex = 0; sampleIndex < numSamples; sampleIndex++)
219 {
220 nextSample();
221 auto samp = m_oscillator.getNextStereoSample(sampleIndex) * velocity;
222 bufferPtr[0][sampleIndex] = samp.left;
223 bufferPtr[1][sampleIndex] = samp.right;
224 }
225 }
226 }
227 }
228
229 void KwidgetProcessor_Reformer::noteOn(int midiNote, float velocity, int voiceIndex)
230 {
232 m_attachmentCache[RGParam::Autoplay]->data());
233 m_oscillator.startNote(midiNote, velocity, voiceIndex);
234 }
235
237
239} // namespace krotos
Definition KrotosSynthesiserSound.h:19
SampleEngine * getSampleEngine() override
Definition KrotosSynthesiserSound.h:44
void Prepare(int midiNoteForNormalPitch, float dawSampleRate)
Definition KrotosSynthesiserSound.cpp:39
Definition Kwidget.h:8
void noteCleared() override
Definition KwidgetProcessor_Reformer.cpp:238
ReformerOscillator m_oscillator
Definition KwidgetProcessor_Reformer.h:35
KrotosSampleOscillatorSound & m_soSound
Definition KwidgetProcessor_Reformer.h:34
void process(AudioBuffer< float > &buffer) override
Definition KwidgetProcessor_Reformer.cpp:76
KwidgetProcessor_Reformer(Kwidget &owner, KrotosSampleOscillatorSound &sound)
Definition KwidgetProcessor_Reformer.cpp:3
void processBlockInternal(AudioBuffer< float > &buffer)
Definition KwidgetProcessor_Reformer.cpp:104
void noteOff(float) override
Definition KwidgetProcessor_Reformer.cpp:236
std::vector< std::shared_ptr< KAttachment > > m_attachmentCache
Definition KwidgetProcessor_Reformer.h:37
void prepare(double sampleRate, int samplesPerBlock) override
Definition KwidgetProcessor_Reformer.cpp:69
void processMuteStereo(float currentMuteValue, int numSamples, float velocity, float **bufferPtr)
Definition KwidgetProcessor_Reformer.cpp:173
void noteOn(int midiNote, float velocity, int) override
Definition KwidgetProcessor_Reformer.cpp:229
float m_formerMuteVal
Definition KwidgetProcessor_Reformer.h:40
bool isActive() override
Definition KwidgetProcessor_Reformer.cpp:92
An interface for an audio processor designed for modular use.
Definition KwidgetProcessor.h:8
std::shared_ptr< KAttachment > getAttachment(const String &paramID)
Definition KwidgetProcessor.cpp:26
void nextBlock(int numSamples)
Definition KwidgetProcessor.cpp:50
void addParameterAttachments(std::vector< AttachmentInfo >)
Definition KwidgetProcessor.cpp:65
void nextSample()
Definition KwidgetProcessor.cpp:59
const String & getKwidgetID() const
Definition KwidgetProcessor.cpp:42
void stopNote()
Signals the oscillator to begin key up behaviour, usually called by key up event The oscillator may c...
Definition ReformerOscillator.cpp:92
StereoSample getNextStereoSample(size_t sampleIndex) override
Updates the granular engine and returns the next audio value.
Definition ReformerOscillator.cpp:232
void startNote(int midiNote, float velocity, int voiceIndex)
Starts the oscillator playing, usually called by key down event.
Definition ReformerOscillator.cpp:76
void setSampleData(SampleEngine *sampleEngine)
Sets the oscillator's internal reference to the SampleEngine structure it is to use.
Definition ReformerOscillator.cpp:38
void setBlockSize(size_t blockSize)
Definition ReformerOscillator.h:41
void setGranularParameter(size_t paramIndex, const float *newValue)
Updates the granular engine and returns the next audio value.
Definition ReformerOscillator.cpp:16
void setSampleRate(double sampleRate) override
Sets the sample rate which the granular oscillator uses to calculate its output.
Definition ReformerOscillator.cpp:28
const float getVelocity()
Returns the value of the velocity as a float in [0...1].
Definition ReformerOscillator.cpp:94
void clearNote()
Signals the oscillator to stop immediately, and return any grains to pool.
Definition ReformerOscillator.cpp:96
GranularParam
Definition ReformerOscillator.h:125
@ Autoplay
Definition ReformerOscillator.h:151
bool requestAccess(const StringRef id)
Called by a client to request access to the resource.
Definition ResourceLock.cpp:5
void finishedAccessing(const StringRef id)
Called by a client to inform the resource that it no longer needs access.
Definition ResourceLock.cpp:35
void setPuckPosition(Point< float > position)
Definition SampleEngine.h:127
float left
Definition KrotosAudioBuffer.h:107
Definition AirAbsorptionFilter.cpp:2
static const String SizeRand
Definition Kwidget_Reformer.h:37
static const String PuckY
Definition Kwidget_Reformer.h:25
static const String Rate
Definition Kwidget_Reformer.h:28
static const String MIDIMode
Definition Kwidget_Reformer.h:60
static const String SelectZ
Definition Kwidget_Reformer.h:72
static const String Start
Definition Kwidget_Reformer.h:23
static const String PanRand
Definition Kwidget_Reformer.h:41
static const String Autoplay
Definition Kwidget_Reformer.h:50
static const String SelectY
Definition Kwidget_Reformer.h:71
static const String Width
Definition Kwidget_Reformer.h:31
static const String Quench
Definition Kwidget_Reformer.h:46
static const String Pitch
Definition Kwidget_Reformer.h:29
static const String Nearest
Definition Kwidget_Reformer.h:26
static const String WidthRand
Definition Kwidget_Reformer.h:40
static const String RateRand
Definition Kwidget_Reformer.h:38
static const String Coeff2
Definition Kwidget_Reformer.h:64
static const String Radius
Definition Kwidget_Reformer.h:45
static const String Coeff7
Definition Kwidget_Reformer.h:69
static const String GranularLevel
Definition Kwidget_Reformer.h:34
static const String Size
Definition Kwidget_Reformer.h:27
static const String StartRand
Definition Kwidget_Reformer.h:36
static const String LevelRand
Definition Kwidget_Reformer.h:42
static const String Coeff5
Definition Kwidget_Reformer.h:67
static const String PitchMod
Definition Kwidget_Reformer.h:30
static const String Coeff6
Definition Kwidget_Reformer.h:68
static const String FeatureExtr
Definition Kwidget_Reformer.h:54
static const String Tracking
Definition Kwidget_Reformer.h:61
static const String SALoop
Definition Kwidget_Reformer.h:48
static const String Proximity
Definition Kwidget_Reformer.h:44
static const String Robin
Definition Kwidget_Reformer.h:47
static const String Pan
Definition Kwidget_Reformer.h:32
static const String Coeff4
Definition Kwidget_Reformer.h:66
static const String Mute
Definition Kwidget_Reformer.h:58
static const String LevelMod
Definition Kwidget_Reformer.h:35
static const String GrainMax
Definition Kwidget_Reformer.h:52
static const String Level
Definition Kwidget_Reformer.h:33
static const String Coeff3
Definition Kwidget_Reformer.h:65
static const String SelectX
Definition Kwidget_Reformer.h:70
static const String Normalise
Definition Kwidget_Reformer.h:49
static const String Popcorn
Definition Kwidget_Reformer.h:43
static const String Coeff1
Definition Kwidget_Reformer.h:63
static const String PitchRand
Definition Kwidget_Reformer.h:39
static const String Solo
Definition Kwidget_Reformer.h:59
static const String Segmentation
Definition Kwidget_Reformer.h:53
static const String Coeff0
Definition Kwidget_Reformer.h:62
static const String PuckX
Definition Kwidget_Reformer.h:24
static const String Shape
Definition Kwidget_Reformer.h:51