Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/20 pattern follow #33

Merged
merged 2 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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