diff options
Diffstat (limited to 'src/djinterop/performance_data.cpp')
-rw-r--r-- | src/djinterop/performance_data.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/djinterop/performance_data.cpp b/src/djinterop/performance_data.cpp new file mode 100644 index 0000000..6656919 --- /dev/null +++ b/src/djinterop/performance_data.cpp @@ -0,0 +1,88 @@ +/* + 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 <http://www.gnu.org/licenses/>. + */ + +#include <algorithm> +#include <cmath> + +#include <djinterop/djinterop.hpp> + +namespace djinterop +{ +namespace enginelibrary +{ +std::vector<beatgrid_marker> normalize_beatgrid( + std::vector<beatgrid_marker> 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<int32_t>(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<int32_t>(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 +} + +} // namespace enginelibrary +} // namespace djinterop |