diff --git a/Sourcecode/include/mx/api/PitchData.h b/Sourcecode/include/mx/api/PitchData.h index 03a776a7d..ee8441b4e 100644 --- a/Sourcecode/include/mx/api/PitchData.h +++ b/Sourcecode/include/mx/api/PitchData.h @@ -69,6 +69,32 @@ namespace mx // default construction is middle c (c4) PitchData(); + constexpr explicit PitchData( + Step inStep, + int inAlter = 0, + int inOctave = 4, + Accidental inAccidental = Accidental::none, + + // less-often used params last + double inCents = 0.0, + bool inIsAccidentalParenthetical = false, + bool inIsAccidentalCautionary = false, + bool inIsAccidentalEditorial = false, + bool inIsAccidentalBracketed = false + ) + : step{ inStep } + , alter{ inAlter } + , cents{ inCents } + , accidental{ inAccidental } + , isAccidentalParenthetical{ inIsAccidentalParenthetical } + , isAccidentalCautionary{ inIsAccidentalCautionary } + , isAccidentalEditorial{ inIsAccidentalEditorial } + , isAccidentalBracketed{ inIsAccidentalBracketed } + , octave{ inOctave } + { + + } + // the note name. i.e. c, d, e, f, g, a, b Step step; @@ -82,8 +108,8 @@ namespace mx // additional alteration to the sounding pitch (in hundredths of a semitone). the MusicXML alter value is // a floating point number to facilitate microtonal music. however for mx::api we wanted the simplicity of // dealing with integrals for the more common case on non-microtonal music. in order to still support - // microtones without resording to a floating-point alter value, we break out microtonal adjustments to a - // separate 'cents' field, which will be addeded to the alter integral: + // microtones without resorting to a floating-point alter value, we break out microtonal adjustments to a + // separate 'cents' field, which will be added to the alter integral: // = (double)alter + (cents / 100.0) double cents; diff --git a/Sourcecode/private/mx/api/PitchData.cpp b/Sourcecode/private/mx/api/PitchData.cpp index b253f7779..078dad7b6 100644 --- a/Sourcecode/private/mx/api/PitchData.cpp +++ b/Sourcecode/private/mx/api/PitchData.cpp @@ -9,20 +9,11 @@ namespace mx namespace api { PitchData::PitchData() - : step{ Step::c } - , alter{ 0 } - , cents{ 0.0 } - , accidental{Accidental::none} - , isAccidentalParenthetical{ false } - , isAccidentalCautionary{ false } - , isAccidentalEditorial{ false } - , isAccidentalBracketed{ false } - , octave{ 4 } + : PitchData{ Step::c } { } - - + void PitchData::showAccidental() { switch( alter ) diff --git a/Sourcecode/private/mxtest/api/PitchDataTest.cpp b/Sourcecode/private/mxtest/api/PitchDataTest.cpp index 7b858cf8e..7b975a6c1 100644 --- a/Sourcecode/private/mxtest/api/PitchDataTest.cpp +++ b/Sourcecode/private/mxtest/api/PitchDataTest.cpp @@ -29,6 +29,8 @@ #include "mx/core/elements/Pedal.h" #include "ezxml/ezxml.h" +#include + using namespace std; using namespace mx::api; @@ -271,4 +273,32 @@ TEST( CrazyEdgeCase2, PitchData ) } T_END; +namespace +{ + struct PitchHash + { + constexpr inline size_t operator()(const mx::api::PitchData& p) const { + size_t h1 = size_t(p.step) << 32; + size_t h2 = size_t(p.alter); + return h1 ^ h2; + } + }; +} + +TEST( ConstructorTest, PitchData ) +{ + // duplicate the feature request from https://github.com/webern/mx/issues/69 + std::unordered_map root_to_key_circle { + { PitchData{ Step::f, 0, 4 }, -1 }, + { PitchData{ Step::c, 0, 4 }, 0 }, + { PitchData{ Step::g, 0, 4 }, 1 }, + }; + + PitchData g{ Step::g }; + const auto find_iter = root_to_key_circle.find( g ); + REQUIRE( find_iter != std::cend( root_to_key_circle ) ); + CHECK_EQUAL( 1, find_iter->second ); +} +T_END; + #endif diff --git a/Sourcecode/private/mxtest/import/ExpectedFiles.cpp b/Sourcecode/private/mxtest/import/ExpectedFiles.cpp index 00f1b749d..e488f585a 100755 --- a/Sourcecode/private/mxtest/import/ExpectedFiles.cpp +++ b/Sourcecode/private/mxtest/import/ExpectedFiles.cpp @@ -299,7 +299,7 @@ namespace mxtest { for( auto qIter = q.begin(); qIter != q.end(); ++qIter ) { - if( qIter->wait_for( std::chrono::milliseconds(0) ) == std::future_status::ready ) + if( qIter->wait_for( std::chrono::milliseconds(2) ) == std::future_status::ready ) { qIter->wait(); q.erase( qIter ); @@ -311,17 +311,17 @@ namespace mxtest q.push_front( std::move( fut ) ); } - while( q.empty() ) + while( !q.empty() ) { for( auto qIter = q.begin(); qIter != q.end(); ++qIter ) { - if( qIter->wait_for( std::chrono::milliseconds(0) ) == std::future_status::ready ) + if( qIter->wait_for( std::chrono::milliseconds(10) ) == std::future_status::ready ) { qIter->wait(); q.erase( qIter ); break; } - std::this_thread::sleep_for( std::chrono::milliseconds(10) ); + std::this_thread::sleep_for( std::chrono::milliseconds(50) ); } } std::cout << "done" << std::endl;