diff --git a/src/ossia/dataflow/token_request.hpp b/src/ossia/dataflow/token_request.hpp index e9dbf8e5b1b..18ca66803b3 100644 --- a/src/ossia/dataflow/token_request.hpp +++ b/src/ossia/dataflow/token_request.hpp @@ -240,6 +240,11 @@ struct token_request if(start_quant != end_quant) { + if(end_quant == end_quarter * musical_quant_dur) + { + // We want quantization on start, not on end + return std::nullopt; + } // Date to quantify is the next one : const double musical_tick_duration = musical_end_position - musical_start_position; @@ -250,9 +255,9 @@ struct token_request quantification_date = prev_date + quantified_duration * ratio; } - else if(musical_start_position == 0. && musical_end_position > 0.) + else if(start_quant == start_quarter * musical_quant_dur) { - // Special first bar case + // We start on a signature change return prev_date; } } diff --git a/src/ossia/editor/scenario/detail/scenario_execution.cpp b/src/ossia/editor/scenario/detail/scenario_execution.cpp index ca2becb665b..00d27a09578 100644 --- a/src/ossia/editor/scenario/detail/scenario_execution.cpp +++ b/src/ossia/editor/scenario/detail/scenario_execution.cpp @@ -160,7 +160,7 @@ void scenario::run_interval( { interval.tick_offset_speed_precomputed(max_tick, offset, tk); } - else if(max_tick == 0_tv) + else if(cst_max_dur == 0_tv) { interval.tick_offset_speed_precomputed(max_tick, offset, tk); } diff --git a/src/ossia/editor/scenario/time_interval.cpp b/src/ossia/editor/scenario/time_interval.cpp index a508bcebc35..363f3d68d49 100644 --- a/src/ossia/editor/scenario/time_interval.cpp +++ b/src/ossia/editor/scenario/time_interval.cpp @@ -130,9 +130,9 @@ void time_interval::tick_impl( m_musical_start_position = num_quarters; } - if(new_date.impl - 1 > old_date.impl) + if(new_date.impl > old_date.impl) { - auto d = ossia::time_value{new_date.impl - 1}; + auto d = ossia::time_value{new_date.impl}; const double num_quarters = d.impl / m_quarter_duration; auto [time, sig] = *ossia::last_before(m_timeSignature, d); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7b9b14f10a9..24dd047f212 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -77,6 +77,7 @@ if(OSSIA_EDITOR) ossia_add_test(ExpressionPulseTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/ExpressionPulseTest.cpp") ossia_add_test(MapperTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/MapperTest.cpp") ossia_add_test(MessageTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/MessageTest.cpp") + ossia_add_test(QuantificationTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/QuantificationTest.cpp") ossia_add_test(StateTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/StateTest.cpp") ossia_add_test(TimeIntervalTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/TimeIntervalTest.cpp") ossia_add_test(TimeEventTest "${CMAKE_CURRENT_SOURCE_DIR}/Editor/TimeEventTest.cpp") diff --git a/tests/Editor/QuantificationTest.cpp b/tests/Editor/QuantificationTest.cpp new file mode 100644 index 00000000000..b20506d358d --- /dev/null +++ b/tests/Editor/QuantificationTest.cpp @@ -0,0 +1,138 @@ + +#include "TestUtils.hpp" +#include "include_catch.hpp" + +#include + +#include + +using namespace ossia; +using namespace std::placeholders; + +TEST_CASE("get_quantification_date_0", "get_quantification_date_0") +{ + ossia::token_request req{0_tv, 100_tv, 15000_tv, 0_tv, 1., {4, 4}, ossia::root_tempo}; + REQUIRE(req.get_quantification_date(0.25)); + REQUIRE(req.get_quantification_date(0.25) == 0_tv); + REQUIRE(req.get_quantification_date(1.)); + REQUIRE(req.get_quantification_date(1.) == 0_tv); + REQUIRE(req.get_quantification_date(2.)); + REQUIRE(req.get_quantification_date(2.) == 0_tv); + REQUIRE(req.get_quantification_date(100.)); + REQUIRE(req.get_quantification_date(100.) == 0_tv); +} + +TEST_CASE("get_quantification_date_some", "get_quantification_date_some") +{ + ossia::token_request req{100_tv, 200_tv, 15000_tv, 0_tv, + 1., {4, 4}, ossia::root_tempo}; + GIVEN("quantization in the middle") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 0.95; + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.05; + REQUIRE(req.get_quantification_date(4.)); + REQUIRE(req.get_quantification_date(4.) == 150_tv); + } + GIVEN("quantization before the beginning 1") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 0.99; + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.05; + REQUIRE(req.get_quantification_date(4.)); + REQUIRE(req.get_quantification_date(4.) == 116_tv); + } + GIVEN("quantization before the beginning 2") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 0.999; + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.05; + REQUIRE(req.get_quantification_date(4.)); + REQUIRE(req.get_quantification_date(4.) == 101_tv); + } + GIVEN("quantization before the beginning 3") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 0.999999999; + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.05; + REQUIRE(req.get_quantification_date(4.)); + REQUIRE(req.get_quantification_date(4.) == 100_tv); + } + GIVEN("quantization before the beginning 4") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = std::nextafter(1., 0.); + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.05; + REQUIRE(req.get_quantification_date(4.)); + REQUIRE(req.get_quantification_date(4.) == 100_tv); + } + GIVEN("quantization at the beginning") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 1.; + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.10; + REQUIRE(req.get_quantification_date(4.)); + REQUIRE(req.get_quantification_date(4.) == 100_tv); + } + + GIVEN("quantization before the end") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 1.90; + req.musical_end_last_bar = 0.; + req.musical_end_position = 1.999999999999999; + REQUIRE(!req.get_quantification_date(4.)); + } + GIVEN("quantization at the end") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = 1.90; + req.musical_end_last_bar = 0.; + req.musical_end_position = 2.; + req.get_quantification_date(4.); + REQUIRE(!req.get_quantification_date(4.)); + //REQUIRE(!req.get_quantification_date(4.) == 200_tv); + } + GIVEN("quantization after the end") + { + req.musical_start_last_signature = 0.; + req.musical_start_last_bar = 0.; + req.musical_start_position = std::nextafter(2., 3.); + REQUIRE(req.musical_start_position != 2.); + req.musical_end_last_bar = 0.; + req.musical_end_position = 2.1; + REQUIRE(!req.get_quantification_date(4.)); + } +} +TEST_CASE("test_quant", "test_quant") +{ + std::shared_ptr start_node{std::make_shared()}; + std::shared_ptr end_node{std::make_shared()}; + + std::shared_ptr start_event{std::make_shared( + ossia::time_event::exec_callback{}, *start_node, + ossia::expressions::make_expression_true())}; + std::shared_ptr end_event{std::make_shared( + ossia::time_event::exec_callback{}, *end_node, + ossia::expressions::make_expression_true())}; + + std::shared_ptr interval{ossia::time_interval::create( + {}, *start_event, *end_event, ossia::time_value{15000}, ossia::time_value{15000}, + ossia::time_value{15000})}; + + // +} diff --git a/tests/Editor/TestUtils.hpp b/tests/Editor/TestUtils.hpp index ff234901352..4e5aa527215 100644 --- a/tests/Editor/TestUtils.hpp +++ b/tests/Editor/TestUtils.hpp @@ -156,6 +156,11 @@ std::ostream& operator<<(std::ostream& d, const ossia::time_value& t) d << t.impl; return d; } +inline std::ostream& +operator<<(std::ostream& d, const std::optional& t) +{ + return t ? (d << t->impl) : (d << "nullopt"); +} inline std::ostream& operator<<(std::ostream& d, const ossia::token_request& t) {