diff --git a/src/sfizz/modulations/ModKey.cpp b/src/sfizz/modulations/ModKey.cpp index 61b55859f..af38defda 100644 --- a/src/sfizz/modulations/ModKey.cpp +++ b/src/sfizz/modulations/ModKey.cpp @@ -228,7 +228,7 @@ std::string ModKey::toString() const } } -ModKey ModKey::getSourceDepthKey(ModKey source, ModKey target) +ModKey ModKey::getSourceDepthKey(const ModKey& source, const ModKey& target) { const NumericId region = source.region(); const ModKey::Parameters& tp = target.parameters(); diff --git a/src/sfizz/modulations/ModKey.h b/src/sfizz/modulations/ModKey.h index 92f11ca43..b3047eba7 100644 --- a/src/sfizz/modulations/ModKey.h +++ b/src/sfizz/modulations/ModKey.h @@ -26,7 +26,10 @@ class ModKey { ModKey() = default; explicit ModKey(ModId id, NumericId region = {}, Parameters params = {}) - : id_(id), region_(region), params_(params), flags_(ModIds::flags(id_)) {} + : id_(id), region_(region), params_(params), flags_(ModIds::flags(id_)) + { + calculateHash(); + } static ModKey createCC(uint16_t cc, uint8_t curve, uint16_t smooth, float step); static ModKey createNXYZ(ModId id, NumericId region = {}, uint8_t N = 0, uint8_t X = 0, uint8_t Y = 0, uint8_t Z = 0); @@ -46,7 +49,7 @@ class ModKey { * @brief Obtain the modulation key of the source depth, in the connection * between source and target, if such a key exists. */ - static ModKey getSourceDepthKey(ModKey source, ModKey target); + static ModKey getSourceDepthKey(const ModKey& source, const ModKey& target); struct RawParameters { union { @@ -94,6 +97,10 @@ class ModKey { return !this->operator==(other); } +public: + size_t hash() const { return hash_; }; +private: + void calculateHash(); private: //! Identifier @@ -104,6 +111,9 @@ class ModKey { Parameters params_ {}; // Memorize the flag int flags_; + // Hash number + size_t hash_ = size_t(16806506973555142816ULL); }; + } // namespace sfz diff --git a/src/sfizz/modulations/ModKeyHash.cpp b/src/sfizz/modulations/ModKeyHash.cpp index a8b8ac6f0..f51d36d59 100644 --- a/src/sfizz/modulations/ModKeyHash.cpp +++ b/src/sfizz/modulations/ModKeyHash.cpp @@ -10,12 +10,27 @@ #include "utility/StringViewHelpers.h" #include -size_t std::hash::operator()(const sfz::ModKey &key) const +void sfz::ModKey::calculateHash() { - uint64_t k = hashNumber(static_cast(key.id())); - const sfz::ModKey::Parameters& p = key.parameters(); +#if !defined(NDEBUG) + static bool once = false; + if (!once) { + once = true; + ModKey m; + size_t h = m.hash(); + m.calculateHash(); + if (h != m.hash()) { + printf("ModKey default hash is %llu\n", (uint64_t)m.hash()); + assert(false && "Number of variables is wrong. Needs updating the default hash."); + } + } +#endif - switch (key.id()) { + uint64_t k = hashNumber(static_cast(id())); + k = hashNumber(region_.number(), k); + const sfz::ModKey::Parameters& p = parameters(); + + switch (id()) { case sfz::ModId::Controller: k = hashNumber(p.cc, k); k = hashNumber(p.curve, k); @@ -29,5 +44,10 @@ size_t std::hash::operator()(const sfz::ModKey &key) const k = hashNumber(p.Z, k); break; } - return k; + hash_ = size_t(k); +} + +size_t std::hash::operator()(const sfz::ModKey &key) const +{ + return key.hash(); } diff --git a/src/sfizz/utility/StringViewHelpers.h b/src/sfizz/utility/StringViewHelpers.h index 278833c18..9fcf355da 100644 --- a/src/sfizz/utility/StringViewHelpers.h +++ b/src/sfizz/utility/StringViewHelpers.h @@ -101,7 +101,12 @@ uint64_t hashNumber(Int i, uint64_t h = Fnv1aBasis) { static_assert(std::is_arithmetic::value, "The hashed object must be of arithmetic type"); - return hash(absl::string_view(reinterpret_cast(&i), sizeof(i)), h); + union { + uint64_t u64; + Int i; + } un {}; + un.i = i; + return (h ^ un.u64) * Fnv1aPrime; } /**