Merge Γ-W2-T2: an explicit loop enable, four named marks with grabbable caps, and the crossfade painted where it is heard
This commit is contained in:
@@ -142,6 +142,48 @@ instrument::ui::DeckEnableState ReaSamplerEditor::deckEnableState() const {
|
||||
play.filterSpline.mode == EnvMode::Spline};
|
||||
}
|
||||
|
||||
bool ReaSamplerEditor::loopControlsLive() const {
|
||||
return effectivePlayMode(params_.play) == PlayMode::Gate;
|
||||
}
|
||||
|
||||
instrument::ui::WaveMarks ReaSamplerEditor::waveMarksFor(const SetupMarkers& m) const {
|
||||
using instrument::ui::WaveMark;
|
||||
instrument::ui::WaveMarks w;
|
||||
w.frame[static_cast<int>(WaveMark::kStart)] = m.start;
|
||||
w.frame[static_cast<int>(WaveMark::kLoopStart)] = m.loopStart;
|
||||
w.frame[static_cast<int>(WaveMark::kLoopEnd)] = m.loopEnd;
|
||||
// The crossfade grows LEFT from the seam it closes, which is where it is audible.
|
||||
w.frame[static_cast<int>(WaveMark::kCrossfade)] = m.loopEnd - m.crossfade;
|
||||
// The crossfade mark belongs to an ACTIVE loop: with the enable off there is no seam for it
|
||||
// to sit on, and no length to drag.
|
||||
w.present[static_cast<int>(WaveMark::kStart)] = true;
|
||||
w.present[static_cast<int>(WaveMark::kLoopStart)] = true;
|
||||
w.present[static_cast<int>(WaveMark::kLoopEnd)] = true;
|
||||
w.present[static_cast<int>(WaveMark::kCrossfade)] = m.hasLoop;
|
||||
return w;
|
||||
}
|
||||
|
||||
instrument::ui::WaveMarks ReaSamplerEditor::grabbableMarks(const SetupMarkers& m) const {
|
||||
using instrument::ui::WaveMark;
|
||||
instrument::ui::WaveMarks w = waveMarksFor(m);
|
||||
if (!loopControlsLive()) {
|
||||
w.present[static_cast<int>(WaveMark::kLoopStart)] = false;
|
||||
w.present[static_cast<int>(WaveMark::kLoopEnd)] = false;
|
||||
w.present[static_cast<int>(WaveMark::kCrossfade)] = false;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
void ReaSamplerEditor::setLoopEnabled(bool on) {
|
||||
const auto frames = static_cast<std::int64_t>(monoPcmFor(selectedId_).size());
|
||||
if (frames <= 0) return;
|
||||
SetupMarkers m = pickedMarkers(frames);
|
||||
if (m.hasLoop == on) return; // a no-op commit would buy a re-decode for nothing
|
||||
m.hasLoop = on;
|
||||
applyMarkers(m);
|
||||
commitAndReload();
|
||||
}
|
||||
|
||||
void ReaSamplerEditor::applyDeckKnob(int id, double norm) {
|
||||
if (!processor_) return;
|
||||
norm = clamp01(norm);
|
||||
|
||||
Reference in New Issue
Block a user