Skip to content

Commit bec111d

Browse files
committed
🐛 FIX: serve plays the song's own render first
A DJ set's mix came after its records' renders in subfolders once those were newer (purge makes them fresh MP3s). The render next to the song's report (or render/) comes first, then MP3, then the shallower path.
1 parent a68f893 commit bec111d

2 files changed

Lines changed: 8 additions & 0 deletions

File tree

‎changelog.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ All notable changes to Wavelength. Versions follow semantic versioning.
3636
- `serve`: clicking a track name in the song player no longer solos it; soloing lives in the editor (the S button or a right-click).
3737

3838
### Fixed
39+
- `serve` plays the song's own render first (next to its report, or the kept render/): a DJ set's mix came after its records' renders in subfolders once those were newer.
3940
- `lint --harmony` reads a one-shot sample named like a drum (kick, snare, clap, hat, crash, ride, tom, perc...) as a drum, by its file name or its track's name: a 909 kick or ride that rings past 0.4 s with a clear pitch counted as notes and gave false key excursions (9 on one song).
4041
- `analyze <render folder>` finds the stems of a render made from another directory: the report names them relative to where the render ran, so they were all skipped.
4142
- `tracks[].postFaderLufs` is measured on every render: it read -120 for every track in a render without markers or a picture and in every `--from/--to` window. A streaming meter (`LoudnessMeter`, equal to the full-buffer measurement) needs no copy of the track's audio.

‎src/serve.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,16 @@ json Server::song(const std::string &slug) {
419419
const bool hasReport = !reportPath.empty() && readJson(dir / reportPath, report);
420420
std::vector<std::string> audio;
421421
for (auto &[p, f] : files) if (isAudio(p)) audio.push_back(p);
422+
// the song's own render first (next to its report, or the kept render/), then MP3 before WAV, then the
423+
// shallower path: a set's mix ahead of the records' renders in its subfolders, however recent theirs are
424+
const std::string ownDir = reportPath.empty() ? "out" : fs::path(reportPath).parent_path().generic_string();
425+
auto own = [&](const std::string &p) { const std::string d = fs::path(p).parent_path().generic_string(); return d == ownDir || d == "render"; };
426+
auto depth = [](const std::string &p) { return std::count(p.begin(), p.end(), '/'); };
422427
std::sort(audio.begin(), audio.end(), [&](const std::string &a, const std::string &b) {
428+
if (own(a) != own(b)) return own(a);
423429
const bool am = a.substr(a.size() - 4) == ".mp3", bm = b.substr(b.size() - 4) == ".mp3";
424430
if (am != bm) return am;
431+
if (depth(a) != depth(b)) return depth(a) < depth(b);
425432
return files.at(a).mtime > files.at(b).mtime;
426433
});
427434
json docs = json::object();

0 commit comments

Comments
 (0)