Krotos Modules 3
Loading...
Searching...
No Matches
SampleEngine.cpp
Go to the documentation of this file.
1#include "SampleEngine.h"
2namespace krotos
3{
5 {
6 int polycount = 0;
7 for (auto& grain : m_grainArray)
8 {
9 if (grain.isPlaying)
10 {
11 polycount++;
12 }
13 }
14 m_currentPolyphony = polycount;
15 }
16
18 {
19 bool ret = false;
20 for (auto& grain : m_grainArray)
21 {
22 if (grain.isPlaying)
23 {
24 ret = true;
25 break;
26 }
27 }
28 return ret;
29 }
30
32 {
33 Grain* retVal = nullptr;
34
35 if (m_currentPolyphony >= m_grainLimit) // If we have reached the grain limit, we wont return a grain slot ...
36 {
37 // ... however we still have to update m_currentPolyphony or it will get stuck failing
39 return retVal;
40 }
41
42 int i = 0;
43 for (; i < MAX_NUM_GRAINS; i++)
44 {
45 if (!m_grainArray[i].isPlaying) // Find a grain slot that's not playing
46 {
47 m_grainArray[i].isPlaying = true; // Switch it on
48 retVal = &m_grainArray[i];
49 break;
50 }
51 }
52 int polycount = i;
53 for (; i < MAX_NUM_GRAINS; i++)
54 {
55 if (m_grainArray[i].isPlaying) // Count the remaining grain slots which are playing
56 {
57 polycount++;
58 }
59 }
60 m_currentPolyphony = polycount;
61 return retVal;
62 }
63
64 void SampleEngine::setGrainLimit(int newLimit) { m_grainLimit = newLimit; }
65
67 {
68 jassert(grain->isPlaying);
69 grain->isPlaying = false;
71 }
72
74
76 {
77 for (int i = 0; i < MAX_NUM_GRAINS; i++)
78 {
79 m_grainArray[i].isPlaying = false;
80 }
82 }
83
85 void SampleEngine::setIndicator1(float newVal) { m_indicator1Value = newVal; }
86
88 void SampleEngine::setIndicator2(float newVal) { m_indicator2Value = newVal; }
89
91 void SampleEngine::setIndicatorRPM(float newVal) { m_indicatorRPMValue = newVal; }
92
95
96 std::vector<Range<int>> SampleEngine::getSelectionRanges()
97 {
98 std::vector<Range<int>> ranges;
99 for (int segmentIndex = 0; segmentIndex < getNumAudioSegments(); segmentIndex++)
100 {
101 ranges.push_back(getAudioSelectionRangeRelative(segmentIndex));
102 }
103 return ranges;
104 }
105
106 void SampleEngine::setSelectionRanges(const std::vector<Range<int>>& ranges)
107 {
108 jassert(ranges.size() == getNumAudioSegments());
109 for (int i = 0; i < jmin(getNumAudioSegments(), (int)ranges.size()); i++)
110 {
111 if (!ranges[i].isEmpty())
112 {
113 setAudioSelectionRangeRelative(i, ranges[i]);
114 }
115 }
116 }
117
118 void SampleEngine::setAudioSegmentStartPosition(int segmentIndex, int startPosition)
119 {
120 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
121 m_audioSegments.data()[segmentIndex].segmentStartPosition = startPosition;
122 }
123
124 void SampleEngine::setAudioSegmentLength(int segmentIndex, int length)
125 {
126 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
127 m_audioSegments.data()[segmentIndex].segmentLength = length;
128 }
129
130 void SampleEngine::setAudioSegmentRange(int segmentIndex, Range<int> range)
131 {
132 setAudioSegmentStartPosition(segmentIndex, range.getStart());
133 setAudioSegmentLength(segmentIndex, range.getLength());
134 }
135
137 {
138 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
139 return static_cast<float>(m_audioSegments[segmentIndex].segmentStartPosition) / static_cast<float>(size());
140 }
141
143 {
144 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
145 return static_cast<float>(m_audioSegments[segmentIndex].segmentStartPosition +
146 m_audioSegments[segmentIndex].segmentLength) /
147 static_cast<float>(size());
148 }
149
150 Range<int> SampleEngine::getAudioSelectionRange(int segmentIndex)
151 {
152 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
153 return Range<int>(m_audioSegments[segmentIndex].selectionStartPosition,
154 m_audioSegments[segmentIndex].selectionStartPosition +
155 m_audioSegments[segmentIndex].selectionLength);
156 }
157
159 {
160 int segmentStart = getAudioSegmentRange(segmentIndex).getStart();
161 return getAudioSelectionRange(segmentIndex) - segmentStart;
162 }
163
164 const String& SampleEngine::getAudioSegmentName(int segmentIndex) const
165 {
166 return m_audioSegments[segmentIndex].name;
167 }
168
170 {
171 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
172 return static_cast<float>(m_audioSegments[segmentIndex].selectionStartPosition) / static_cast<float>(size());
173 }
174
176 {
177 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
178 return static_cast<float>(m_audioSegments[segmentIndex].selectionStartPosition +
179 m_audioSegments[segmentIndex].selectionLength) /
180 static_cast<float>(size());
181 }
182
183 void SampleEngine::setAudioSelectionRangeAbsolute(int segmentIndex, Range<int> range)
184 {
185 setAudioSelectionStartPositionAbsolute(segmentIndex, range.getStart());
186 setAudioSelectionLength(segmentIndex, range.getLength());
187 }
188
189 void SampleEngine::setAudioSelectionRangeRelative(int segmentIndex, Range<int> range)
190 {
191 // Because the selection range is passed in relative to the segment
192 // we first offset it so it is relative to the start of the audio buffer
193 range = range + getAudioSegmentStartPosition(segmentIndex);
194 auto limits = getAudioSegmentRange(segmentIndex);
195 auto constrained = limits.constrainRange(range); // Constrain inputRange to the segment
196 jassert(range == constrained); // Assert if inputRange was not entirely inside the segment
197 setAudioSelectionRangeAbsolute(segmentIndex, constrained);
198 }
199
200 void SampleEngine::setAudioSelectionStartPositionAbsolute(int segmentIndex, int startPosition)
201 {
202 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
203 m_audioSegments.data()[segmentIndex].selectionStartPosition = startPosition;
204 }
205
206 void SampleEngine::setAudioSelectionLength(int segmentIndex, int length)
207 {
208 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
209 m_audioSegments.data()[segmentIndex].selectionLength = length;
210 }
211
213 {
214 String filePathsAsCSV;
215
216 bool firstTime = true;
217 for (auto& segment : m_audioSegments)
218 {
219 if (firstTime)
220 {
221 firstTime = false;
222 }
223 else
224 {
225 filePathsAsCSV += ",";
226 }
227 filePathsAsCSV += segment.path;
228 }
229
230 return filePathsAsCSV;
231 }
232
234 {
235 StringArray names;
236 for (auto& segment : m_audioSegments)
237 {
238 names.add(segment.name);
239 }
240 return names;
241 }
242
244 {
245 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
246 return m_audioSegments[segmentIndex].selectionStartPosition;
247 }
248
250 {
251 int numSegments = m_audioSegments.size();
252 if (numSegments)
253 {
254 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
255 return m_audioSegments[segmentIndex].selectionLength;
256 }
257 else
258 {
259 return 0;
260 }
261 }
262
264 {
265 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
266 return m_audioSegments[segmentIndex].segmentStartPosition;
267 }
268
270 {
271 int numSegments = m_audioSegments.size();
272 if (numSegments)
273 {
274 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
275 return m_audioSegments[segmentIndex].segmentLength;
276 }
277 else
278 {
279 return 0;
280 }
281 }
282
283 Range<int> SampleEngine::getAudioSegmentRange(int segmentIndex)
284 {
285 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
286 return Range<int>(m_audioSegments[segmentIndex].segmentStartPosition,
287 m_audioSegments[segmentIndex].segmentStartPosition +
288 m_audioSegments[segmentIndex].segmentLength);
289 }
290
292 {
293 const int segmentCount = std::distance(m_audioSegments.begin(), m_audioSegments.end());
294
295 if (segmentCount <= segmentIndex || segmentIndex < 0)
296 {
297 jassertfalse; // Segment index out of range
298 return;
299 }
300
301 if (m_audioSegments.data()[segmentIndex].muted)
302 {
303 // Won't cue a muted sample
304 return;
305 }
306
307 m_segmentRoundRobinIndex = segmentIndex;
308 }
309
310 void SampleEngine::removeSegment(int segmentIndex)
311 {
312 jassert(segmentIndex >= 0 && segmentIndex < m_audioSegments.size());
313 m_audioSegments.remove(segmentIndex);
314
315 // Update allSegmentsMuted flag in case this leaves all segments muted..
317 }
318
320 {
322
323 int oldSegmentRoundRobinIndex = m_segmentRoundRobinIndex;
324
325 if (m_audioSegments.size() <= 1)
326 {
328 }
329 else if (sequential)
330 {
332 if (m_segmentRoundRobinIndex >= static_cast<int>(m_audioSegments.size()))
333 {
335 }
336 }
337 else
338 {
339 if (m_audioSegments.size() > 1)
340 {
341 do
342 {
344 juce::Random::getSystemRandom().nextInt(static_cast<int>(m_audioSegments.size()));
345 } while (m_segmentRoundRobinIndex == oldSegmentRoundRobinIndex);
346 }
347 else
348 {
350 }
351 }
352
353 if (m_segmentRoundRobinIndex < static_cast<int>(m_audioSegments.size()) &&
355 {
356 prepareNextSegmentIndex(sequential);
357 }
358 }
359
361 {
362 for (auto& segment : m_audioSegments)
363 {
364 if (!segment.muted)
365 {
366 return false;
367 }
368 }
369 return true;
370 }
371
372 void SampleEngine::setSegmentMuted(int segmentIndex, bool isMuted)
373 {
374 const int segmentCount = std::distance(m_audioSegments.begin(), m_audioSegments.end());
375
376 if (segmentCount <= segmentIndex || segmentIndex < 0)
377 {
378 jassertfalse; // Segment index out of range
379 return;
380 }
381
382 if (!m_audioSegments.data()[segmentIndex].solo.getValue())
383 {
384 m_audioSegments.data()[segmentIndex].muted = isMuted;
385 }
386
388
389 if (m_segmentRoundRobinIndex >= 0 && m_segmentRoundRobinIndex < segmentCount)
390 {
391 // Recalculate the segment index if the next sample to play has been muted
393 {
396 }
397 }
398
399 if (m_skippedSegmentIndex >= 0 && m_skippedSegmentIndex < segmentCount)
400 {
401 // If the last cued sample was skipped because it was muted, and has since been unmuted, re-cue it
402 if (segmentIndex == m_skippedSegmentIndex && !isMuted &&
404 {
407 }
408 }
409 }
410
412
415
416 Value& SampleEngine::getSoloValue(int index) { return m_audioSegments.data()[index].solo; }
417} // namespace krotos
Definition OscillatorUtils.h:39
bool isPlaying
Definition OscillatorUtils.h:73
int size()
Definition KrotosAudioBufferDSP.h:394
void setAudioSelectionRangeAbsolute(int segmentIndex, Range< int > range)
Sets the absolute selection range of an audio segment relative to the audio buffer start.
Definition SampleEngine.cpp:183
int getAudioSegmentLengthInSamples(int segmentIndex)
Returns the length of an audio segment.
Definition SampleEngine.cpp:269
void setGrainLimit(int newLimit)
Definition SampleEngine.cpp:64
float getIndicator2()
Definition SampleEngine.cpp:87
int m_grainLimit
Definition SampleEngine.h:355
void flushGrains()
Definition SampleEngine.cpp:75
float getAudioSelectionStartPositionPercent(int segmentIndex)
Returns the start position of an audio segment selection as a fraction of the audio buffer length.
Definition SampleEngine.cpp:169
int getAudioSelectionStartPosition(int segmentIndex)
Returns the start of the selected section of an audio segment.
Definition SampleEngine.cpp:243
void setAudioSelectionStartPositionAbsolute(int segmentIndex, int startPosition)
Sets the absolute start of an audio segment selection relative to the audio buffer start.
Definition SampleEngine.cpp:200
void setSegmentMuted(int segmentIndex, bool isMuted)
'Mutes' an audio segment in the sampler. In effect, this just means the sample is skipped in the roun...
Definition SampleEngine.cpp:372
bool allSegmentsMuted()
Definition SampleEngine.cpp:360
const String & getAudioSegmentName(int segmentIndex) const
Returns the name of an audio segment.
Definition SampleEngine.cpp:164
Range< int > getAudioSelectionRange(int segmentIndex)
Returns the start and end position of an audio segment selection as a Range.
Definition SampleEngine.cpp:150
void setSelectionRanges(const std::vector< Range< int > > &selectionRanges)
Sets the selection ranges of the audio segments.
Definition SampleEngine.cpp:106
void freeGrain(Grain *grain)
Definition SampleEngine.cpp:66
juce::String getGetLoadedFilePathsAsCSV()
Definition SampleEngine.cpp:212
Grain * allocateGrain()
Definition SampleEngine.cpp:31
float getIndicatorRPM()
Definition SampleEngine.cpp:90
void setAudioSelectionLength(int segmentIndex, int length)
Sets the length of an audio segment selection.
Definition SampleEngine.cpp:206
float getAudioSegmentEndPositionPercent(int segmentIndex)
Returns the end position of an audio segment as a fraction of the audio buffer length.
Definition SampleEngine.cpp:142
bool m_allSegmentsMuted
Definition SampleEngine.h:366
volatile float m_indicator2Value
Definition SampleEngine.h:358
static const int MAX_NUM_GRAINS
Definition SampleEngine.h:88
float getAudioSelectionEndPositionPercent(int segmentIndex)
Returns the end position of an audio segment selection as a fraction of the audio buffer length.
Definition SampleEngine.cpp:175
void setAudioSelectionRangeRelative(int segmentIndex, Range< int > range)
Sets the selection range of an audio segment relative to the segment.
Definition SampleEngine.cpp:189
int m_lastSegmentRoundRobinIndex
Definition SampleEngine.h:364
void prepareNextSegmentIndex(bool sequential=true)
Calculate the next segment to be played back.
Definition SampleEngine.cpp:319
void setNextSegmentIndex(int index)
Sets the next segment index to be picked.
Definition SampleEngine.cpp:291
float getIndicator1()
Definition SampleEngine.cpp:84
Grain m_grainArray[MAX_NUM_GRAINS]
Definition SampleEngine.h:354
int getAudioSelectionLengthInSamples(int segmentIndex)
Returns the length of the selected section of an audio segment.
Definition SampleEngine.cpp:249
const int getNextSegmentIndex() const
Returns the index of the next segment to be played.
Definition SampleEngine.cpp:413
Array< AudioSegment > m_audioSegments
Definition SampleEngine.h:361
volatile float m_indicator1Value
Definition SampleEngine.h:357
int getNumAudioSegments()
Definition SampleEngine.h:161
void setIndicator1(float newVal)
Definition SampleEngine.cpp:85
std::vector< Range< int > > getSelectionRanges()
Returns an array of segment selection ranges.
Definition SampleEngine.cpp:96
String getNextCuedSegmentName() const
Returns the next cued segment name TODO: Update this to return actual cued segment....
Definition SampleEngine.cpp:411
const int getLastSegmentIndex() const
Returns the index of the previous segment that was played.
Definition SampleEngine.cpp:414
bool isPlaying()
returns true if any grains are active
Definition SampleEngine.cpp:17
volatile float m_indicatorRPMValue
Definition SampleEngine.h:359
void clearAudioSegments()
Definition SampleEngine.cpp:93
void setIndicatorRPM(float newVal)
Definition SampleEngine.cpp:91
Range< int > getAudioSelectionRangeRelative(int segmentIndex)
Returns the selection range of an audio segment relative to the segment's start position.
Definition SampleEngine.cpp:158
int m_segmentRoundRobinIndex
Definition SampleEngine.h:363
void calculatePolyphonyCount()
Definition SampleEngine.cpp:4
Range< int > getAudioSegmentRange(int segmentIndex)
Returns the start and end positions of an audio segment as a Range.
Definition SampleEngine.cpp:283
Value & getSoloValue(int index)
Returns a reference to the 'solo' Value of an audio segment. You can use Value::referTo to have the s...
Definition SampleEngine.cpp:416
void addAudioSegment(AudioSegment &seg)
Definition SampleEngine.cpp:94
int getAudioSegmentStartPosition(int segmentIndex)
Returns the start of an audio segment.
Definition SampleEngine.cpp:263
float getAudioSegmentStartPositionPercent(int segmentIndex)
Returns the start position of an audio segment as a fraction of the audio buffer length.
Definition SampleEngine.cpp:136
Grain * getGrainArray()
Definition SampleEngine.cpp:73
void setIndicator2(float newVal)
Definition SampleEngine.cpp:88
StringArray getAudioSegmentNames() const
Returns a StringArray of audio segment names loaded in the engine.
Definition SampleEngine.cpp:233
int m_skippedSegmentIndex
Definition SampleEngine.h:367
int m_currentPolyphony
Definition SampleEngine.h:353
void setAudioSegmentStartPosition(int segmentIndex, int startPosition)
Sets the start of an audio segment relative to the audio buffer start.
Definition SampleEngine.cpp:118
void setAudioSegmentRange(int segmentIndex, Range< int > range)
Sets the start and end of an audio segment relative to the audio buffer start.
Definition SampleEngine.cpp:130
void setAudioSegmentLength(int segmentIndex, int length)
Sets the length an audio segment.
Definition SampleEngine.cpp:124
void removeSegment(int segmentIndex)
Remove a segment from the sample engine.
Definition SampleEngine.cpp:310
Definition AirAbsorptionFilter.cpp:2
A struct to describe an audio sample (as appears in the waveform view)
Definition SampleEngine.h:24