1b4d0e67b7
Also corrects the cap-area, em-dash, glyph-overhang and heuristic-comment findings noted in review.
64 lines
2.2 KiB
C++
64 lines
2.2 KiB
C++
// loop_marks.cpp — see loop_marks.h. Pure value folds; no host types.
|
|
|
|
#include "core/instrument/ui/loop_marks.h"
|
|
|
|
#include "core/instrument/engine/loop/loop_span.h" // defaultLoopBounds
|
|
|
|
namespace reasampler::instrument::ui {
|
|
|
|
namespace {
|
|
|
|
// The engine's own acceptance test, restated over the editor's two integers: resolveLoop
|
|
// refuses an inverted, empty or out-of-range span rather than repairing it, so a span it would
|
|
// refuse is one the handles must be re-parked out of.
|
|
bool spanUsable(std::int64_t loopStart, std::int64_t loopEnd, std::int64_t frameCount) {
|
|
return loopStart >= 0 && loopEnd > loopStart && loopEnd <= frameCount;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
LoopMarks resolveLoopMarks(const StoredLoop& stored, std::int64_t frameCount) {
|
|
LoopMarks m;
|
|
if (stored.override_) {
|
|
m.hasLoop = stored.override_->hasLoop;
|
|
m.loopStart = stored.override_->start;
|
|
m.loopEnd = stored.override_->end;
|
|
} else if (stored.intrinsic && stored.intrinsic->hasLoop) {
|
|
m.hasLoop = true;
|
|
m.loopStart = stored.intrinsic->start;
|
|
m.loopEnd = stored.intrinsic->end;
|
|
}
|
|
if (stored.startPoint) m.start = *stored.startPoint;
|
|
m.crossfade = stored.crossfade > 0 ? stored.crossfade : 0;
|
|
|
|
if (!spanUsable(m.loopStart, m.loopEnd, frameCount)) {
|
|
m.hasLoop = false;
|
|
m.parked = true;
|
|
const engine::loop::LoopBounds d = engine::loop::defaultLoopBounds(frameCount);
|
|
m.loopStart = d.start;
|
|
m.loopEnd = d.end;
|
|
}
|
|
return m;
|
|
}
|
|
|
|
LoopWrite applyLoopMarks(const LoopMarks& m) {
|
|
LoopWrite w;
|
|
const bool spanAlive = m.loopEnd > m.loopStart;
|
|
w.loop.hasLoop = m.hasLoop && spanAlive;
|
|
if (m.parked && !m.hasLoop) {
|
|
// A parked pair (never set) must round-trip back to parked, not to a real "LOOP OFF"
|
|
// span — resolveLoopMarks only re-parks a span spanUsable would refuse, so collapse it
|
|
// deliberately rather than writing back the default bounds' own alive span.
|
|
w.loop.start = m.loopStart;
|
|
w.loop.end = m.loopStart;
|
|
} else {
|
|
w.loop.start = m.loopStart;
|
|
w.loop.end = m.loopEnd;
|
|
}
|
|
w.crossfade = (spanAlive && m.crossfade > 0) ? m.crossfade : 0;
|
|
w.start = m.start;
|
|
return w;
|
|
}
|
|
|
|
} // namespace reasampler::instrument::ui
|