/* This file is part of libdjinterop. libdjinterop is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. libdjinterop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libdjinterop. If not, see . */ #include #include #include #include #include "enginelibrary/el_database_impl.hpp" #include "enginelibrary/el_transaction_guard_impl.hpp" #include "enginelibrary/schema/schema.hpp" #include "util.hpp" namespace djinterop::enginelibrary { /// Gets a descriptive name for a given schema version. std::string version_name(const semantic_version& version) { auto schema_creator_validator = schema::make_schema_creator_validator(version); return schema_creator_validator->name(); } database create_database( const std::string& directory, const semantic_version& schema_version) { auto storage = std::make_shared(directory, schema_version); return database{std::make_shared(storage)}; } database create_database_from_scripts( const std::string& db_directory, const std::string& script_directory) { std::string stmt; std::ifstream m_db_script{script_directory + "/m.db.sql"}; sqlite::database m_db{db_directory + "/m.db"}; while (std::getline(m_db_script, stmt)) { m_db << stmt; } std::ifstream p_db_script{script_directory + "/p.db.sql"}; sqlite::database p_db{db_directory + "/p.db"}; while (std::getline(p_db_script, stmt)) { p_db << stmt; } return load_database(db_directory); } database create_or_load_database( const std::string& directory, const semantic_version& schema_version, bool& created) { try { created = false; return load_database(directory); } catch (database_not_found& e) { created = true; return create_database(directory, schema_version); } } bool database_exists(const std::string& directory) { try { load_database(directory); } catch (database_not_found& e) { return false; } return true; } database load_database(const std::string& directory) { auto storage = std::make_shared(directory); return database{std::make_shared(storage)}; } std::string music_db_path(const database& db) { return db.directory() + "/m.db"; } std::vector normalize_beatgrid( std::vector beatgrid, int64_t sample_count) { if (beatgrid.empty()) { return beatgrid; // Named RVO } { auto last_marker_iter = std::find_if( beatgrid.begin(), beatgrid.end(), [sample_count](const beatgrid_marker& marker) { return marker.sample_offset > sample_count; }); if (last_marker_iter != beatgrid.end()) { beatgrid.erase(last_marker_iter + 1, beatgrid.end()); } } { auto after_first_marker_iter = std::find_if( beatgrid.begin(), beatgrid.end(), [](const beatgrid_marker& marker) { return marker.sample_offset > 0; }); if (after_first_marker_iter != beatgrid.begin()) { beatgrid.erase(beatgrid.begin(), after_first_marker_iter - 1); } } if (beatgrid.size() < 2) { throw std::invalid_argument{ "Attempted to normalize a misplaced beadgrid"}; } { double samples_per_beat = (beatgrid[1].sample_offset - beatgrid[0].sample_offset) / (beatgrid[1].index - beatgrid[0].index); beatgrid[0].sample_offset -= (4 + beatgrid[0].index) * samples_per_beat; beatgrid[0].index = -4; } { int32_t last = static_cast(beatgrid.size() - 1); double samples_per_beat = (beatgrid[last].sample_offset - beatgrid[last - 1].sample_offset) / (beatgrid[last].index - beatgrid[last - 1].index); int32_t index_adjustment = static_cast(std::ceil( (sample_count - beatgrid[last].sample_offset) / samples_per_beat)); beatgrid[last].sample_offset += index_adjustment * samples_per_beat; beatgrid[last].index += index_adjustment; } return beatgrid; // Named RVO } std::string perfdata_db_path(const database& db) { return db.directory() + "/p.db"; } } // namespace djinterop::enginelibrary