|
- //***********************************************************************************************
- //Impromptu Modular: Modules for VCV Rack by Marc Boulé
- //***********************************************************************************************
-
-
- #include "FoundrySequencer.hpp"
-
- namespace rack_plugin_ImpromptuModular {
-
- void Sequencer::construct(bool* _holdTiedNotesPtr, int* _velocityModePtr) {// don't want regaular constructor mechanism
- velocityModePtr = _velocityModePtr;
- sek[0].construct(0, nullptr, _holdTiedNotesPtr);
- for (int trkn = 1; trkn < NUM_TRACKS; trkn++)
- sek[trkn].construct(trkn, &sek[0], _holdTiedNotesPtr);
- }
-
-
- void Sequencer::setVelocityVal(int trkn, int intVel, int multiStepsCount, bool multiTracks) {
- sek[trkn].setVelocityVal(seqIndexEdit, stepIndexEdit, intVel, multiStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trkn) continue;
- sek[i].setVelocityVal(seqIndexEdit, stepIndexEdit, intVel, multiStepsCount);
- }
- }
- }
- void Sequencer::setLength(int length, bool multiTracks) {
- sek[trackIndexEdit].setLength(seqIndexEdit, length);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setLength(seqIndexEdit, length);
- }
- }
- }
- void Sequencer::setBegin(bool multiTracks) {
- sek[trackIndexEdit].setBegin(phraseIndexEdit);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setBegin(phraseIndexEdit);
- }
- }
- }
- void Sequencer::setEnd(bool multiTracks) {
- sek[trackIndexEdit].setEnd(phraseIndexEdit);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setEnd(phraseIndexEdit);
- }
- }
- }
- bool Sequencer::setGateType(int keyn, int multiSteps, float sampleRate, bool autostepClick, bool multiTracks) {// Third param is for right-click autostep. Returns success
- int newMode = keyIndexToGateTypeEx(keyn);
- if (newMode == -1)
- return false;
- sek[trackIndexEdit].setGateType(seqIndexEdit, stepIndexEdit, newMode, multiSteps);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setGateType(seqIndexEdit, stepIndexEdit, newMode, multiSteps);
- }
- }
- if (autostepClick){ // if right-click then move to next step
- moveStepIndexEdit(1, false);
- editingGateKeyLight = keyn;
- editingType = (unsigned long) (gateTime * sampleRate / displayRefreshStepSkips);
- if (windowIsModPressed() && multiSteps < 2)
- setGateType(keyn, 1, sampleRate, false, multiTracks);
- }
- return true;
- }
-
-
- void Sequencer::initSlideVal(int multiStepsCount, bool multiTracks) {
- sek[trackIndexEdit].setSlideVal(seqIndexEdit, stepIndexEdit, StepAttributes::INIT_SLIDE, multiStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setSlideVal(seqIndexEdit, stepIndexEdit, StepAttributes::INIT_SLIDE, multiStepsCount);
- }
- }
- }
- void Sequencer::initGatePVal(int multiStepsCount, bool multiTracks) {
- sek[trackIndexEdit].setGatePVal(seqIndexEdit, stepIndexEdit, StepAttributes::INIT_PROB, multiStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setGatePVal(seqIndexEdit, stepIndexEdit, StepAttributes::INIT_PROB, multiStepsCount);
- }
- }
- }
- void Sequencer::initVelocityVal(int multiStepsCount, bool multiTracks) {
- sek[trackIndexEdit].setVelocityVal(seqIndexEdit, stepIndexEdit, StepAttributes::INIT_VELOCITY, multiStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setVelocityVal(seqIndexEdit, stepIndexEdit, StepAttributes::INIT_VELOCITY, multiStepsCount);
- }
- }
- }
- void Sequencer::initPulsesPerStep(bool multiTracks) {
- sek[trackIndexEdit].initPulsesPerStep();
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].initPulsesPerStep();
- }
- }
- }
- void Sequencer::initDelay(bool multiTracks) {
- sek[trackIndexEdit].initDelay();
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].initDelay();
- }
- }
- }
- void Sequencer::initRunModeSong(bool multiTracks) {
- sek[trackIndexEdit].setRunModeSong(SequencerKernel::MODE_FWD);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setRunModeSong(SequencerKernel::MODE_FWD);
- }
- }
- }
- void Sequencer::initRunModeSeq(bool multiTracks) {
- sek[trackIndexEdit].setRunModeSeq(seqIndexEdit, SequencerKernel::MODE_FWD);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setRunModeSeq(seqIndexEdit, SequencerKernel::MODE_FWD);
- }
- }
- }
- void Sequencer::initLength(bool multiTracks) {
- sek[trackIndexEdit].setLength(seqIndexEdit, SequencerKernel::MAX_STEPS);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setLength(seqIndexEdit, SequencerKernel::MAX_STEPS);
- }
- }
- }
- void Sequencer::initPhraseReps(bool multiTracks) {
- sek[trackIndexEdit].setPhraseReps(phraseIndexEdit, 1);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setPhraseReps(phraseIndexEdit, 1);
- }
- }
- }
- void Sequencer::initPhraseSeqNum(bool multiTracks) {
- sek[trackIndexEdit].setPhraseSeqNum(phraseIndexEdit, 0);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setPhraseSeqNum(phraseIndexEdit, 0);
- }
- }
- }
-
- void Sequencer::copySequence(int countCP) {
- int startCP = stepIndexEdit;
- sek[trackIndexEdit].copySequence(&seqCPbuf, seqIndexEdit, startCP, countCP);
- }
- void Sequencer::pasteSequence(bool multiTracks) {
- int startCP = stepIndexEdit;
- sek[trackIndexEdit].pasteSequence(&seqCPbuf, seqIndexEdit, startCP);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].pasteSequence(&seqCPbuf, seqIndexEdit, startCP);
- }
- }
- }
- void Sequencer::copySong(int startCP, int countCP) {
- sek[trackIndexEdit].copySong(&songCPbuf, startCP, countCP);
- }
- void Sequencer::pasteSong(bool multiTracks) {
- sek[trackIndexEdit].pasteSong(&songCPbuf, phraseIndexEdit);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].pasteSong(&songCPbuf, phraseIndexEdit);
- }
- }
- }
-
-
- void Sequencer::writeCV(int trkn, float cvVal, int multiStepsCount, float sampleRate, bool multiTracks) {
- sek[trkn].writeCV(seqIndexEdit, stepIndexEdit, cvVal, multiStepsCount);
- editingGateCV[trkn] = cvVal;
- editingGateCV2[trkn] = sek[trkn].getVelocityVal(seqIndexEdit, stepIndexEdit);
- editingGate[trkn] = (unsigned long) (gateTime * sampleRate / displayRefreshStepSkips);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trkn) continue;
- sek[i].writeCV(seqIndexEdit, stepIndexEdit, cvVal, multiStepsCount);
- }
- }
- }
- void Sequencer::autostep(bool autoseq, bool autostepLen) {
- moveStepIndexEdit(1, autostepLen);
- if (stepIndexEdit == 0 && autoseq)
- seqIndexEdit = moveIndex(seqIndexEdit, seqIndexEdit + 1, SequencerKernel::MAX_SEQS);
- }
-
- bool Sequencer::applyNewOctave(int octn, int multiSteps, float sampleRate, bool multiTracks) { // returns true if tied
- if (sek[trackIndexEdit].getTied(seqIndexEdit, stepIndexEdit))
- return true;
- editingGateCV[trackIndexEdit] = sek[trackIndexEdit].applyNewOctave(seqIndexEdit, stepIndexEdit, octn, multiSteps);
- editingGateCV2[trackIndexEdit] = sek[trackIndexEdit].getVelocityVal(seqIndexEdit, stepIndexEdit);
- editingGate[trackIndexEdit] = (unsigned long) (gateTime * sampleRate / displayRefreshStepSkips);
- editingGateKeyLight = -1;
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].applyNewOctave(seqIndexEdit, stepIndexEdit, octn, multiSteps);
- }
- }
- return false;
- }
- bool Sequencer::applyNewKey(int keyn, int multiSteps, float sampleRate, bool autostepClick, bool multiTracks) { // returns true if tied
- bool ret = false;
- if (sek[trackIndexEdit].getTied(seqIndexEdit, stepIndexEdit)) {
- if (autostepClick)
- moveStepIndexEdit(1, false);
- else
- ret = true;
- }
- else {
- editingGateCV[trackIndexEdit] = sek[trackIndexEdit].applyNewKey(seqIndexEdit, stepIndexEdit, keyn, multiSteps);
- editingGateCV2[trackIndexEdit] = sek[trackIndexEdit].getVelocityVal(seqIndexEdit, stepIndexEdit);
- editingGate[trackIndexEdit] = (unsigned long) (gateTime * sampleRate / displayRefreshStepSkips);
- editingGateKeyLight = -1;
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].applyNewKey(seqIndexEdit, stepIndexEdit, keyn, multiSteps);
- }
- }
- if (autostepClick) {// if right-click then move to next step
- moveStepIndexEdit(1, false);
- if (windowIsModPressed() && multiSteps < 2) // if ctrl-right-click and SEL is off
- writeCV(trackIndexEdit, editingGateCV[trackIndexEdit], 1, sampleRate, multiTracks);// copy CV only to next step
- editingGateKeyLight = keyn;
- }
- }
- return ret;
- }
-
- void Sequencer::moveStepIndexEditWithEditingGate(int delta, bool writeTrig, float sampleRate) {
- moveStepIndexEdit(delta, false);
- for (int trkn = 0; trkn < NUM_TRACKS; trkn++) {
- if (!sek[trkn].getTied(seqIndexEdit, stepIndexEdit)) {// play if non-tied step
- if (!writeTrig) {// in case autostep when simultaneous writeCV and stepCV (keep what was done in Write Input block above)
- editingGate[trkn] = (unsigned long) (gateTime * sampleRate / displayRefreshStepSkips);
- editingGateCV[trkn] = sek[trkn].getCV(seqIndexEdit, stepIndexEdit);
- editingGateCV2[trkn] = sek[trkn].getVelocityVal(seqIndexEdit, stepIndexEdit);
- editingGateKeyLight = -1;
- }
- }
- }
- }
-
-
-
- void Sequencer::modSlideVal(int deltaVelKnob, int mutliStepsCount, bool multiTracks) {
- int sVal = sek[trackIndexEdit].modSlideVal(seqIndexEdit, stepIndexEdit, deltaVelKnob, mutliStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setSlideVal(seqIndexEdit, stepIndexEdit, sVal, mutliStepsCount);
- }
- }
- }
- void Sequencer::modGatePVal(int deltaVelKnob, int mutliStepsCount, bool multiTracks) {
- int gpVal = sek[trackIndexEdit].modGatePVal(seqIndexEdit, stepIndexEdit, deltaVelKnob, mutliStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setGatePVal(seqIndexEdit, stepIndexEdit, gpVal, mutliStepsCount);
- }
- }
- }
- void Sequencer::modVelocityVal(int deltaVelKnob, int mutliStepsCount, bool multiTracks) {
- int upperLimit = ((*velocityModePtr) == 0 ? 200 : 127);
- int vVal = sek[trackIndexEdit].modVelocityVal(seqIndexEdit, stepIndexEdit, deltaVelKnob, upperLimit, mutliStepsCount);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setVelocityVal(seqIndexEdit, stepIndexEdit, vVal, mutliStepsCount);
- }
- }
- }
- void Sequencer::modRunModeSong(int deltaPhrKnob, bool multiTracks) {
- int newRunMode = sek[trackIndexEdit].modRunModeSong(deltaPhrKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setRunModeSong(newRunMode);
- }
- }
- }
- void Sequencer::modPulsesPerStep(int deltaSeqKnob, bool multiTracks) {
- int newPPS = sek[trackIndexEdit].modPulsesPerStep(deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setPulsesPerStep(newPPS);
- }
- }
- }
- void Sequencer::modDelay(int deltaSeqKnob, bool multiTracks) {
- int newDelay = sek[trackIndexEdit].modDelay(deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setDelay(newDelay);
- }
- }
- }
- void Sequencer::modRunModeSeq(int deltaSeqKnob, bool multiTracks) {
- int newRunMode = sek[trackIndexEdit].modRunModeSeq(seqIndexEdit, deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setRunModeSeq(seqIndexEdit, newRunMode);
- }
- }
- }
- void Sequencer::modLength(int deltaSeqKnob, bool multiTracks) {
- int newLength = sek[trackIndexEdit].modLength(seqIndexEdit, deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setLength(seqIndexEdit, newLength);
- }
- }
- }
- void Sequencer::modPhraseReps(int deltaSeqKnob, bool multiTracks) {
- int newReps = sek[trackIndexEdit].modPhraseReps(phraseIndexEdit, deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setPhraseReps(phraseIndexEdit, newReps);
- }
- }
- }
- void Sequencer::modPhraseSeqNum(int deltaSeqKnob, bool multiTracks) {
- int newSeqn = sek[trackIndexEdit].modPhraseSeqNum(phraseIndexEdit, deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setPhraseSeqNum(phraseIndexEdit, newSeqn);
- }
- }
- }
- void Sequencer::transposeSeq(int deltaSeqKnob, bool multiTracks) {
- sek[trackIndexEdit].transposeSeq(seqIndexEdit, deltaSeqKnob);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].transposeSeq(seqIndexEdit, deltaSeqKnob);
- }
- }
- }
- void Sequencer::unTransposeSeq(bool multiTracks) {
- sek[trackIndexEdit].unTransposeSeq(seqIndexEdit);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].unTransposeSeq(seqIndexEdit);
- }
- }
- }
- void Sequencer::rotateSeq(int deltaSeqKnob, bool multiTracks) {
- sek[trackIndexEdit].rotateSeq(seqIndexEdit, deltaSeqKnob);
- if (stepIndexEdit < getLength())
- moveStepIndexEdit(deltaSeqKnob, true);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].rotateSeq(seqIndexEdit, deltaSeqKnob);
- }
- }
- }
- void Sequencer::unRotateSeq(bool multiTracks) {
- sek[trackIndexEdit].unRotateSeq(seqIndexEdit);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].unRotateSeq(seqIndexEdit);
- }
- }
- }
- void Sequencer::toggleGate(int multiSteps, bool multiTracks) {
- bool newGate = sek[trackIndexEdit].toggleGate(seqIndexEdit, stepIndexEdit, multiSteps);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setGate(seqIndexEdit, stepIndexEdit, newGate, multiSteps);
- }
- }
- }
- bool Sequencer::toggleGateP(int multiSteps, bool multiTracks) { // returns true if tied
- if (sek[trackIndexEdit].getTied(seqIndexEdit,stepIndexEdit))
- return true;
- bool newGateP = sek[trackIndexEdit].toggleGateP(seqIndexEdit, stepIndexEdit, multiSteps);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setGateP(seqIndexEdit, stepIndexEdit, newGateP, multiSteps);
- }
- }
- return false;
- }
- bool Sequencer::toggleSlide(int multiSteps, bool multiTracks) { // returns true if tied
- if (sek[trackIndexEdit].getTied(seqIndexEdit,stepIndexEdit))
- return true;
- bool newSlide = sek[trackIndexEdit].toggleSlide(seqIndexEdit, stepIndexEdit, multiSteps);
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setSlide(seqIndexEdit, stepIndexEdit, newSlide, multiSteps);
- }
- }
- return false;
- }
- void Sequencer::toggleTied(int multiSteps, bool multiTracks) {
- bool newTied = sek[trackIndexEdit].toggleTied(seqIndexEdit, stepIndexEdit, multiSteps);// will clear other attribs if new state is on
- if (multiTracks) {
- for (int i = 0; i < NUM_TRACKS; i++) {
- if (i == trackIndexEdit) continue;
- sek[i].setTied(seqIndexEdit, stepIndexEdit, newTied, multiSteps);
- }
- }
- }
-
-
- void Sequencer::toJson(json_t *rootJ) {
- // stepIndexEdit
- json_object_set_new(rootJ, "stepIndexEdit", json_integer(stepIndexEdit));
-
- // seqIndexEdit
- json_object_set_new(rootJ, "seqIndexEdit", json_integer(seqIndexEdit));
-
- // phraseIndexEdit
- json_object_set_new(rootJ, "phraseIndexEdit", json_integer(phraseIndexEdit));
-
- // trackIndexEdit
- json_object_set_new(rootJ, "trackIndexEdit", json_integer(trackIndexEdit));
-
- for (int trkn = 0; trkn < NUM_TRACKS; trkn++)
- sek[trkn].toJson(rootJ);
- }
-
-
- void Sequencer::fromJson(json_t *rootJ) {
- // stepIndexEdit
- json_t *stepIndexEditJ = json_object_get(rootJ, "stepIndexEdit");
- if (stepIndexEditJ)
- stepIndexEdit = json_integer_value(stepIndexEditJ);
-
- // phraseIndexEdit
- json_t *phraseIndexEditJ = json_object_get(rootJ, "phraseIndexEdit");
- if (phraseIndexEditJ)
- phraseIndexEdit = json_integer_value(phraseIndexEditJ);
-
- // seqIndexEdit
- json_t *seqIndexEditJ = json_object_get(rootJ, "seqIndexEdit");
- if (seqIndexEditJ)
- seqIndexEdit = json_integer_value(seqIndexEditJ);
-
- // trackIndexEdit
- json_t *trackIndexEditJ = json_object_get(rootJ, "trackIndexEdit");
- if (trackIndexEditJ)
- trackIndexEdit = json_integer_value(trackIndexEditJ);
-
- for (int trkn = 0; trkn < NUM_TRACKS; trkn++)
- sek[trkn].fromJson(rootJ);
- }
-
-
- void Sequencer::reset() {
- stepIndexEdit = 0;
- phraseIndexEdit = 0;
- seqIndexEdit = 0;
- trackIndexEdit = 0;
- seqCPbuf.reset();
- songCPbuf.reset();
-
- for (int trkn = 0; trkn < NUM_TRACKS; trkn++) {
- editingGate[trkn] = 0ul;
- sek[trkn].reset();
- }
- editingType = 0ul;
- }
-
-
- void Sequencer::clockStep(int trkn) {
- bool phraseChange = sek[trkn].clockStep();
- if (trkn == 0 && phraseChange) {
- for (int tkbcd = 1; tkbcd < NUM_TRACKS; tkbcd++) {// check for song run mode slaving
- if (sek[tkbcd].getRunModeSong() == SequencerKernel::MODE_TKA) {
- sek[tkbcd].setPhraseIndexRun(sek[0].getPhraseIndexRun());
- // The code below is to make it such that stepIndexRun should re-init upon phraseChange
- // example for phrase jump does not reset stepIndexRun in B
- //A (FWD): 1 = 1x10, 2 = 1x10
- //B (TKA): 1 = 1x20, 2 = 1x20
- // next line will not work, it will result in a double move of stepIndexRun since clock will move it also
- //sek[tkbcd].moveStepIndexRun(true);
- // this next mechanism works, the chain of events will make moveStepIndexRun(true) happen automatically and no double move will occur
- sek[tkbcd].setMoveStepIndexRunIgnore();//
- }
- }
- }
- }
-
- } // namespace rack_plugin_ImpromptuModular
-
|