commit 55fd028c525746baa2c0aed9dd761e2e9c7975b4
parent ccf9c8adb24a6c90d02ecf1dc3be8bec73f9c04c
Author: Matt Demanett <matt@demanett.net>
Date: Sat, 28 Dec 2019 19:10:21 -0600
ARP: add shuffle mode.
Diffstat:
4 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/res-src/Arp-src.svg b/res-src/Arp-src.svg
@@ -112,7 +112,11 @@
<use id="RANDOM_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
<text font-size="5pt" letter-spacing="1px" transform="translate(8 5.7)">RD</text>
</g>
- <use id="MODE_PARAM" xlink:href="#button-small" transform="translate(15 40)" />
+ <g transform="translate(0 40)">
+ <use id="SHUFFLE_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
+ <text font-size="5pt" letter-spacing="1px" transform="translate(8 5.7)">SH</text>
+ </g>
+ <use id="MODE_PARAM" xlink:href="#button-small" transform="translate(21 39)" />
</g>
<g transform="translate(2.5 78.5)">
diff --git a/res/Arp.svg b/res/Arp.svg
Binary files differ.
diff --git a/src/Arp.cpp b/src/Arp.cpp
@@ -88,10 +88,32 @@ bool Arp::NoteSet::nextPitch(Mode mode, float& pitchOut) {
pitchOut = _notesAsPlayed[random::u32() % _noteCount].pitch;
return true;
}
+
+ case SHUFFLE_MODE: {
+ _playIndex = (_playIndex + 1) % _noteCount;
+ if (_playIndex == 0) {
+ std::fill(_shuffleMask, _shuffleMask + maxChannels, false);
+ }
+ _syncNext = _syncTo && _playIndex == _noteCount - 1;
+
+ int n = random::u32() % (_noteCount - _playIndex);
+ int i = 0;
+ for (; i < _noteCount; ++i) {
+ if (!_shuffleMask[i]) {
+ if (n < 1) {
+ _shuffleMask[i] = true;
+ break;
+ }
+ --n;
+ }
+ }
+ pitchOut = _notesAsPlayed[i].pitch;
+ return true;
+ }
}
assert(false);
- return 0.0f;
+ return false;
}
void Arp::NoteSet::reset() {
@@ -247,6 +269,7 @@ void Arp::processAll(const ProcessArgs& args) {
lights[UP_DOWN_REPEAT_LIGHT].value = _mode == UP_DOWN_REPEAT_MODE;
lights[IN_ORDER_LIGHT].value = _mode == IN_ORDER_MODE;
lights[RANDOM_LIGHT].value = _mode == RANDOM_MODE;
+ lights[SHUFFLE_LIGHT].value = _mode == SHUFFLE_MODE;
if (_resetTrigger.process(inputs[RESET_INPUT].getVoltage())) {
_currentNotes->resetSequence();
@@ -329,7 +352,7 @@ struct ArpWidget : ModuleWidget {
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365)));
// generated by svg_widgets.rb
- auto modeParamPosition = Vec(18.0, 58.0);
+ auto modeParamPosition = Vec(24.0, 57.0);
auto gateLengthParamPosition = Vec(14.5, 87.5);
auto holdParamPosition = Vec(29.0, 114.0);
@@ -347,6 +370,7 @@ struct ArpWidget : ModuleWidget {
auto upDownRepeatLightPosition = Vec(24.0, 38.0);
auto inOrderLightPosition = Vec(3.0, 48.0);
auto randomLightPosition = Vec(24.0, 48.0);
+ auto shuffleLightPosition = Vec(3.0, 58.0);
// end generated by svg_widgets.rb
addParam(createParam<StatefulButton9>(modeParamPosition, module, Arp::MODE_PARAM));
@@ -367,6 +391,7 @@ struct ArpWidget : ModuleWidget {
addChild(createLight<SmallLight<GreenLight>>(upDownRepeatLightPosition, module, Arp::UP_DOWN_REPEAT_LIGHT));
addChild(createLight<SmallLight<GreenLight>>(inOrderLightPosition, module, Arp::IN_ORDER_LIGHT));
addChild(createLight<SmallLight<GreenLight>>(randomLightPosition, module, Arp::RANDOM_LIGHT));
+ addChild(createLight<SmallLight<GreenLight>>(shuffleLightPosition, module, Arp::SHUFFLE_LIGHT));
}
void appendContextMenu(Menu* menu) override {
diff --git a/src/Arp.hpp b/src/Arp.hpp
@@ -35,6 +35,7 @@ struct Arp : BGModule {
UP_DOWN_REPEAT_LIGHT,
IN_ORDER_LIGHT,
RANDOM_LIGHT,
+ SHUFFLE_LIGHT,
NUM_LIGHTS
};
@@ -44,7 +45,8 @@ struct Arp : BGModule {
UP_DOWN_MODE,
UP_DOWN_REPEAT_MODE,
IN_ORDER_MODE,
- RANDOM_MODE
+ RANDOM_MODE,
+ SHUFFLE_MODE
};
struct NoteSet {
@@ -67,6 +69,7 @@ struct Arp : BGModule {
bool _notesDirty = false;
int _playIndex = -1;
bool _up = true;
+ bool _shuffleMask[maxChannels] {};
NoteSet* _syncTo;
bool _syncNext = true;
@@ -102,7 +105,7 @@ struct Arp : BGModule {
Arp() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam(MODE_PARAM, 0.0f, 5.0f, 0.0f, "Playback mode");
+ configParam(MODE_PARAM, 0.0f, 6.0f, 0.0f, "Playback mode");
configParam(GATE_LENGTH_PARAM, 0.0f, 1.0f, 0.5f, "Gate length", "%", 0.0f, 100.0f);
configParam(HOLD_PARAM, 0.0f, 1.0f, 0.0f, "Hold/latch");