Skip to content

Commit

Permalink
issue #20 (westlicht#270) Pattern Follow
Browse files Browse the repository at this point in the history
  • Loading branch information
mebitek committed Jan 11, 2024
1 parent 9cf8fa0 commit 6a5a846
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 75 deletions.
37 changes: 37 additions & 0 deletions src/apps/sequencer/model/CurveTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,42 @@ class CurveTrack {
str("%+.1f%%", gateProbabilityBias() * 12.5f);
}

// patternFollow
Types::PatternFollow patternFollow() const { return _patternFollow; }
void setPatternFollow(const Types::PatternFollow patternFollow) {
_patternFollow = ModelUtils::clampedEnum(patternFollow);
}

void setPatternFollow(bool trackDisplay, bool trackLP) {

if (trackDisplay && trackLP) {
setPatternFollow(Types::PatternFollow::DispAndLP);
return;
}

else if (trackDisplay) {
setPatternFollow(Types::PatternFollow::Display);
return;
}

else if (trackLP) {
setPatternFollow(Types::PatternFollow::LaunchPad);
return;
}

setPatternFollow(Types::PatternFollow::Off);

return;
}

void editPatternFollow(int value, bool shift) {
setPatternFollow(ModelUtils::adjustedEnum(patternFollow(), value));
}

void printPatternFollow(StringBuilder &str) const {
str(Types::patternFollowName(patternFollow()));
}

// sequences

const CurveSequenceArray &sequences() const { return _sequences; }
Expand Down Expand Up @@ -250,6 +286,7 @@ class CurveTrack {
Routable<int8_t> _rotate;
Routable<int8_t> _shapeProbabilityBias;
Routable<int8_t> _gateProbabilityBias;
Types::PatternFollow _patternFollow;

CurveSequenceArray _sequences;

Expand Down
192 changes: 118 additions & 74 deletions src/apps/sequencer/ui/controllers/launchpad/LaunchpadController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ static const RangeMap *curveSequenceLayerRangeMap[] = {
[int(CurveSequence::Layer::GateProbability)] = nullptr,
};

bool _followMode[8];
std::map<int8_t, int> dict;

UserSettings _userSettings;
Expand Down Expand Up @@ -327,74 +326,85 @@ void LaunchpadController::sequenceButton(const Button &button, ButtonAction acti
if (_noteStyle == 0) {
sequenceEditStep(button.row, button.col);
} else {
const auto &sequence = _project.selectedNoteSequence();
const auto &scale = sequence.selectedScale(_project.scale());
int rootNote = sequence.selectedRootNote(_model.project().rootNote());
switch ( _project.selectedNoteSequenceLayer()) {
case NoteSequence::Layer::Note:

if (button.row >=3 && button.row <= 4) {
int ft = -1;
if (button.row == 3) {
ft = semitones[button.col];
} else if (button.row == 4) {
ft = tones[button.col];
}
if (scale.isNotePresent(ft)) {
int noteIndex = scale.getNoteIndex(ft);
selectedNote = noteIndex + (scale.notesPerOctave()*selectedOctave);
if (button.col == 7) {
selectedNote = selectedNote + scale.notesPerOctave();
switch (_project.selectedTrack().trackMode()) {
case (Track::TrackMode::Note): {
const auto &sequence = _project.selectedNoteSequence();
const auto &scale = sequence.selectedScale(_project.scale());
int rootNote = sequence.selectedRootNote(_model.project().rootNote());
switch ( _project.selectedNoteSequenceLayer()) {
case NoteSequence::Layer::Note:

if (button.row >=3 && button.row <= 4) {
int ft = -1;
if (button.row == 3) {
ft = semitones[button.col];
} else if (button.row == 4) {
ft = tones[button.col];
}
}
break;
} else if (button.row >= 0 && button.row <= 2) {
auto &sequence = _project.selectedNoteSequence();
auto layer = _project.selectedNoteSequenceLayer();
int ofs = _sequence.navigation.col * 16;
int linearIndex = button.col + ofs + (button.row*8);
if (isNoteKeyboardPressed()) {
sequence.step(linearIndex).setLayerValue(layer, selectedNote);
if (!sequence.step(linearIndex).gate()) {
sequence.step(linearIndex).toggleGate();
}
} else {
sequence.step(linearIndex).toggleGate();
}
break;
} else if (button.row == 6) {
switch (button.col) {
case 0:
selectedOctave = -4;
break;
case 1:
selectedOctave = -3;
break;
case 2:
selectedOctave = -2;
break;
case 3:
selectedOctave = -1;
break;
case 4:
selectedOctave = 0;
break;
case 5:
selectedOctave = 1;
break;
case 6:
selectedOctave = 2;
if (scale.isNotePresent(ft)) {
int noteIndex = scale.getNoteIndex(ft);
selectedNote = noteIndex + (scale.notesPerOctave()*selectedOctave);
if (button.col == 7) {
selectedNote = selectedNote + scale.notesPerOctave();
}
}
break;
case 7:
selectedOctave = 3;
break;
default:
} else if (button.row >= 0 && button.row <= 2) {
auto &sequence = _project.selectedNoteSequence();
auto layer = _project.selectedNoteSequenceLayer();
int ofs = _sequence.navigation.col * 16;
int linearIndex = button.col + ofs + (button.row*8);
if (isNoteKeyboardPressed()) {
sequence.step(linearIndex).setLayerValue(layer, selectedNote);
if (!sequence.step(linearIndex).gate()) {
sequence.step(linearIndex).toggleGate();
}
} else {
sequence.step(linearIndex).toggleGate();
}
break;
}
} else if (button.row == 6) {
switch (button.col) {
case 0:
selectedOctave = -4;
break;
case 1:
selectedOctave = -3;
break;
case 2:
selectedOctave = -2;
break;
case 3:
selectedOctave = -1;
break;
case 4:
selectedOctave = 0;
break;
case 5:
selectedOctave = 1;
break;
case 6:
selectedOctave = 2;
break;
case 7:
selectedOctave = 3;
break;
default:
break;
}
}
default:
sequenceEditStep(button.row, button.col);
break;
break;
}
default:
}
case Track::TrackMode::Curve:
sequenceEditStep(button.row, button.col);
break;
default:
break;

}
}

Expand Down Expand Up @@ -546,10 +556,15 @@ void LaunchpadController::sequenceSetRunMode(int mode) {
}

void LaunchpadController::sequenceSetFollowMode(int col) {
if (_followMode[col]) {
_followMode[col] = false;
} else {
_followMode[col] = true;
switch (_project.selectedTrack().trackMode()) {
case Track::TrackMode::Note:
_project.selectedTrack().noteTrack().setPatternFollow(Types::PatternFollow(col));
break;
case Track::TrackMode::Curve:
_project.selectedTrack().curveTrack().setPatternFollow(Types::PatternFollow(col));
break;
default:
break;
}
}

Expand Down Expand Up @@ -691,10 +706,18 @@ void LaunchpadController::sequenceDrawRunMode() {
}

void LaunchpadController::sequenceDrawFollowMode() {
for (int i= 0; i < 8; ++i) {
setGridLed(0, i, _followMode[i] ? colorGreen() : colorRed());
switch (_project.selectedTrack().trackMode()) {
case Track::TrackMode::Note: {
drawEnum(_project.selectedTrack().noteTrack().patternFollow());
break;
}
case Track::TrackMode::Curve: {
drawEnum(_project.selectedTrack().curveTrack().patternFollow());
break;
}
default:
break;
}

}

void LaunchpadController::sequenceDrawSequence() {
Expand Down Expand Up @@ -1170,19 +1193,40 @@ void LaunchpadController::drawCurveSequenceDots(const CurveSequence &sequence, C
void LaunchpadController::followModeAction(int currentStep, int lastStep) {

int trackIndex = _project.selectedTrack().trackIndex();
if (_followMode[trackIndex] && _engine.state().running()) {

int g = currentStep / 8;
if (_project.selectedNoteSequenceLayer()==NoteSequence::Layer::Note) {
g = currentStep / 16;
if (_engine.state().running()) {
bool followMode = false;
int g = currentStep / 8;
switch (_project.selectedTrack().trackMode()) {
case Track::TrackMode::Note: {
auto mode = _project.selectedTrack().noteTrack().patternFollow();
if (mode == Types::PatternFollow::LaunchPad || mode == Types::PatternFollow::DispAndLP) {
followMode = true;
if (_project.selectedNoteSequenceLayer()==NoteSequence::Layer::Note) {
g = currentStep / 16;
}
}
break;
}
case Track::TrackMode::Curve: {
auto mode = _project.selectedTrack().curveTrack().patternFollow();
if (mode == Types::PatternFollow::LaunchPad || mode == Types::PatternFollow::DispAndLP) {
followMode = true;
}
break;
}
default:
break;
}

if (followMode) {
int row = dict.at(_sequence.navigation.row);
Button button = Button(row,g);
if (currentStep == lastStep) {
button = Button(row,0);
}
navigationButtonDown(_sequence.navigation, button);
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/apps/sequencer/ui/model/CurveTrackListModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class CurveTrackListModel : public RoutableListModel {
Rotate,
ShapeProbabilityBias,
GateProbabilityBias,
PatternFollow,
Last
};

Expand All @@ -76,6 +77,7 @@ class CurveTrackListModel : public RoutableListModel {
case Rotate: return "Rotate";
case ShapeProbabilityBias: return "Shape P. Bias";
case GateProbabilityBias: return "Gate P. Bias";
case PatternFollow: return "Pattern Follow";
case Last: break;
}
return nullptr;
Expand Down Expand Up @@ -114,6 +116,9 @@ class CurveTrackListModel : public RoutableListModel {
case GateProbabilityBias:
_track->printGateProbabilityBias(str);
break;
case PatternFollow:
_track->printPatternFollow(str);
break;
case Last:
break;
}
Expand Down Expand Up @@ -147,6 +152,9 @@ class CurveTrackListModel : public RoutableListModel {
case GateProbabilityBias:
_track->editGateProbabilityBias(value, shift);
break;
case PatternFollow:
_track->editPatternFollow(value, shift);
break;
case Last:
break;
}
Expand Down
Loading

0 comments on commit 6a5a846

Please sign in to comment.