#pragma once #include #include #include #include #include #include #include #include namespace vamp_test { inline auto add_timing(boost::json::value &value) -> void { auto &music = value.at("music"); music.at("metadata").as_object()["song_id"] = "fixture"; auto &measures = music.at("staves").as_array().front().at("measures").as_array(); auto &pages = value.at("presentation").at("pages").as_array(); while (measures.size() < pages.size()) { measures.push_back(boost::json::object{}); } auto beat = [](std::size_t n) { return boost::json::object{{"numerator", n}, {"denominator", 1}}; }; auto clicks = boost::json::array{}; for (std::size_t i = 0; i < measures.size(); ++i) { measures[i].as_object()["duration"] = beat(4); for (std::size_t b = 0; b < 4; ++b) { clicks.push_back(boost::json::object{{"beat", beat(i * 4 + b)}, {"downbeat", b == 0}}); } } std::size_t cursor{}; for (std::size_t i = 0; i < pages.size(); ++i) { auto count = i + 1 == pages.size() ? measures.size() - cursor : 1U; auto &page = pages[i].as_object(); page["first_measure"] = cursor + 1; page["measure_count"] = count; page["start_beat"] = beat(cursor * 4); page["end_beat"] = beat((cursor + count) * 4); cursor += count; } value.as_object()["performance"] = boost::json::object{{"song_id", "fixture"}, {"duration", beat(measures.size() * 4)}, {"count_in_beats", 4}, {"clicks", clicks}}; } inline auto build_catalog(std::filesystem::path const &assets, std::filesystem::path const &database) -> std::bool_t { auto source = assets.string(); auto destination = database.string(); auto child = ::fork(); BOOST_REQUIRE(child >= 0); if (child == 0) { ::execl(VAMP_TEST_PYTHON, VAMP_TEST_PYTHON, VAMP_TEST_SOURCE_DIR "/generator/catalog.py", source.c_str(), destination.c_str(), nullptr); ::_exit(127); } auto status = std::int32_t{}; auto waited = ::waitpid(child, &status, 0); while (waited < 0 && errno == EINTR) { waited = ::waitpid(child, &status, 0); } BOOST_REQUIRE(waited == child); return WIFEXITED(status) && WEXITSTATUS(status) == 0; } }