Skip to content

Commit

Permalink
Merge pull request #33 from glibersat/feature/20-pattern-follow
Browse files Browse the repository at this point in the history
Feature/20 pattern follow
  • Loading branch information
mebitek authored Jan 11, 2024
2 parents b2aa6d9 + 4e3f641 commit 42e0550
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 15 deletions.
14 changes: 7 additions & 7 deletions src/apps/sequencer/engine/NoteTrackEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ TrackEngine::TickResult NoteTrackEngine::tick(uint32_t tick) {
_sequenceState.advanceAligned(relativeTick / divisor, sequence.runMode(), sequence.firstStep(), sequence.lastStep(), rng);
recordStep(tick, divisor);
triggerStep(tick, divisor);

_sequenceState.calculateNextStepAligned(
(relativeTick + divisor) / divisor,
(relativeTick + divisor) / divisor,
sequence.runMode(),
sequence.firstStep(),
sequence.lastStep(),
Expand All @@ -166,11 +166,11 @@ TrackEngine::TickResult NoteTrackEngine::tick(uint32_t tick) {
recordStep(tick, divisor);
const auto &step = sequence.step(_sequenceState.step());
bool isLastStageStep = ((int) (step.stageRepeats()+1) - (int) _currentStageRepeat) <= 0;

triggerStep(tick+divisor, divisor);

if (isLastStageStep) {
_currentStageRepeat = 1;
_currentStageRepeat = 1;
} else {
_currentStageRepeat++;
}
Expand Down Expand Up @@ -332,7 +332,7 @@ void NoteTrackEngine::triggerStep(uint32_t tick, uint32_t divisor, bool forNextS

// TODO do we need to encounter rotate?
_currentStep = SequenceUtils::rotateStep(_sequenceState.step(), sequence.firstStep(), sequence.lastStep(), rotate);

int stepIndex;

if (forNextStep) {
Expand Down Expand Up @@ -397,7 +397,7 @@ void NoteTrackEngine::triggerStep(uint32_t tick, uint32_t divisor, bool forNextS
case 6:
stepGate = stepGate && (_currentStageRepeat - 1) % 3 == 0;
break;

}
break;
}
Expand Down
39 changes: 38 additions & 1 deletion src/apps/sequencer/model/NoteTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class NoteTrack {
//----------------------------------------
// Types
//----------------------------------------
static constexpr size_t NameLength = FileHeader::NameLength;
static constexpr size_t NameLength = FileHeader::NameLength;

typedef std::array<NoteSequence, CONFIG_PATTERN_COUNT + CONFIG_SNAPSHOT_COUNT> NoteSequenceArray;

Expand Down Expand Up @@ -270,6 +270,42 @@ class NoteTrack {
str("%+.1f%%", noteProbabilityBias() * 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 NoteSequenceArray &sequences() const { return _sequences; }
Expand Down Expand Up @@ -319,6 +355,7 @@ class NoteTrack {
Routable<int8_t> _retriggerProbabilityBias;
Routable<int8_t> _lengthBias;
Routable<int8_t> _noteProbabilityBias;
Types::PatternFollow _patternFollow;

NoteSequenceArray _sequences;

Expand Down
21 changes: 21 additions & 0 deletions src/apps/sequencer/model/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,27 @@ class Types {
return nullptr;
}

// Pattern Follow
enum class PatternFollow : uint8_t {
Off,
Display,
LaunchPad,
DispAndLP,
Last
};

static const char *patternFollowName(PatternFollow patternFollow) {
switch (patternFollow) {
case PatternFollow::Off: return "Off";
case PatternFollow::Display: return "Display";
case PatternFollow::LaunchPad: return "LaunchPad";
case PatternFollow::DispAndLP: return "Display+LP";
case PatternFollow::Last: break;
}
return nullptr;
}


// Condition

enum class Condition : uint8_t {
Expand Down
8 changes: 8 additions & 0 deletions src/apps/sequencer/ui/model/NoteTrackListModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class NoteTrackListModel : public RoutableListModel {
RetriggerProbabilityBias,
LengthBias,
NoteProbabilityBias,
PatternFollow,
Last
};

Expand All @@ -90,6 +91,7 @@ class NoteTrackListModel : public RoutableListModel {
case RetriggerProbabilityBias: return "Retrig P. Bias";
case LengthBias: return "Length Bias";
case NoteProbabilityBias: return "Note P. Bias";
case PatternFollow: return "Pattern Follow";
case Last: break;
}
return nullptr;
Expand Down Expand Up @@ -140,6 +142,9 @@ class NoteTrackListModel : public RoutableListModel {
case NoteProbabilityBias:
_track->printNoteProbabilityBias(str);
break;
case PatternFollow:
_track->printPatternFollow(str);
break;
case Last:
break;
}
Expand Down Expand Up @@ -186,6 +191,9 @@ class NoteTrackListModel : public RoutableListModel {
case NoteProbabilityBias:
_track->editNoteProbabilityBias(value, shift);
break;
case PatternFollow:
_track->editPatternFollow(value, shift);
break;
case Last:
break;
}
Expand Down
45 changes: 39 additions & 6 deletions src/apps/sequencer/ui/pages/NoteSequenceEditPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ void NoteSequenceEditPage::exit() {
void NoteSequenceEditPage::draw(Canvas &canvas) {
WindowPainter::clear(canvas);

const auto &note_track = _project.selectedTrack().noteTrack();

/* Prepare flags shown before mode name (top right header) */
const char *mode_flags = NULL;
if (_sectionTracking) {

const auto pattern_follow = note_track.patternFollow();
if (pattern_follow == Types::PatternFollow::Display || pattern_follow == Types::PatternFollow::DispAndLP) {
const char *st_flag = "F";
mode_flags = st_flag;
}
Expand All @@ -86,6 +90,7 @@ void NoteSequenceEditPage::draw(Canvas &canvas) {
WindowPainter::drawFooter(canvas, functionNames, pageKeyState(), activeFunctionKey());

const auto &trackEngine = _engine.selectedTrackEngine().as<NoteTrackEngine>();

const auto &sequence = _project.selectedNoteSequence();
const auto &scale = sequence.selectedScale(_project.scale());
int currentStep = trackEngine.isActiveSequence(sequence) ? trackEngine.currentStep() : -1;
Expand All @@ -96,9 +101,8 @@ void NoteSequenceEditPage::draw(Canvas &canvas) {

const int loopY = 16;


// Track Pattern Section on the UI
if (_sectionTracking && _engine.state().running()) {
if (isSectionTracking() && _engine.state().running()) {
bool section_change = bool((currentStep) % StepCount == 0); // StepCount is relative to screen
int section_no = int((currentStep) / StepCount);
if (section_change && section_no != _section) {
Expand Down Expand Up @@ -341,7 +345,7 @@ void NoteSequenceEditPage::keyPress(KeyPressEvent &event) {
if (key.pageModifier()) {
// XXX Added here, but should we move it to pageModifier structure?
if (key.is(Key::Step5)) {
setSectionTracking(not _sectionTracking);
toggleSectionTracking();
event.consume();
}
return;
Expand Down Expand Up @@ -944,8 +948,37 @@ void NoteSequenceEditPage::duplicateSequence() {
/*
* Makes the UI track the current step section
*/
void NoteSequenceEditPage::setSectionTracking(bool track) {
_sectionTracking = track;
void NoteSequenceEditPage::setSectionTracking(bool trackDisplay) {
auto &note_track = _project.selectedTrack().noteTrack();
const auto pattern_follow = note_track.patternFollow();

const bool lp_tracking =
(pattern_follow == Types::PatternFollow::LaunchPad ||
pattern_follow == Types::PatternFollow::DispAndLP);

note_track.setPatternFollow(trackDisplay, lp_tracking);
}

bool NoteSequenceEditPage::isSectionTracking() {
auto &note_track = _project.selectedTrack().noteTrack();
const auto pattern_follow = note_track.patternFollow();

return (pattern_follow == Types::PatternFollow::Display ||
pattern_follow == Types::PatternFollow::DispAndLP);
}


void NoteSequenceEditPage::toggleSectionTracking() {
auto &note_track = _project.selectedTrack().noteTrack();
const auto pattern_follow = note_track.patternFollow();

const bool disp_tracking = isSectionTracking();

const bool lp_tracking =
(pattern_follow == Types::PatternFollow::LaunchPad ||
pattern_follow == Types::PatternFollow::DispAndLP);

note_track.setPatternFollow(not disp_tracking, lp_tracking);
}

void NoteSequenceEditPage::tieNotes() {
Expand Down
3 changes: 2 additions & 1 deletion src/apps/sequencer/ui/pages/NoteSequenceEditPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ class NoteSequenceEditPage : public BasePage {
void setSelectedStepsGate(bool gate);

void setSectionTracking(bool track);
bool isSectionTracking();
void toggleSectionTracking();

NoteSequence::Layer layer() const { return _project.selectedNoteSequenceLayer(); };
void setLayer(NoteSequence::Layer layer) { _project.setSelectedNoteSequenceLayer(layer); }

int _section = 0;
bool _sectionTracking = false;
bool _showDetail;
uint32_t _showDetailTicks;

Expand Down

0 comments on commit 42e0550

Please sign in to comment.