Skip to content

Commit

Permalink
Improved note-on performance
Browse files Browse the repository at this point in the history
- Compute the hash value on ModKey construction and memorize it
- Fix missing region ID in the hash value of ModKey
  • Loading branch information
KKQ-KKQ authored and paulfd committed Feb 4, 2024
1 parent 3d7bcb4 commit f8fc628
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/sfizz/modulations/ModKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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> region = source.region();
const ModKey::Parameters& tp = target.parameters();
Expand Down
14 changes: 12 additions & 2 deletions src/sfizz/modulations/ModKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ class ModKey {

ModKey() = default;
explicit ModKey(ModId id, NumericId<Region> 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> region = {}, uint8_t N = 0, uint8_t X = 0, uint8_t Y = 0, uint8_t Z = 0);
Expand All @@ -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 {
Expand Down Expand Up @@ -94,6 +97,10 @@ class ModKey {
return !this->operator==(other);
}

public:
size_t hash() const { return hash_; };
private:
void calculateHash();

private:
//! Identifier
Expand All @@ -104,6 +111,9 @@ class ModKey {
Parameters params_ {};
// Memorize the flag
int flags_;
// Hash number
size_t hash_ = size_t(16806506973555142816ULL);
};


} // namespace sfz
30 changes: 25 additions & 5 deletions src/sfizz/modulations/ModKeyHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,27 @@
#include "utility/StringViewHelpers.h"
#include <cstdint>

size_t std::hash<sfz::ModKey>::operator()(const sfz::ModKey &key) const
void sfz::ModKey::calculateHash()
{
uint64_t k = hashNumber(static_cast<int>(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<int>(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);
Expand All @@ -29,5 +44,10 @@ size_t std::hash<sfz::ModKey>::operator()(const sfz::ModKey &key) const
k = hashNumber(p.Z, k);
break;
}
return k;
hash_ = size_t(k);
}

size_t std::hash<sfz::ModKey>::operator()(const sfz::ModKey &key) const
{
return key.hash();
}
7 changes: 6 additions & 1 deletion src/sfizz/utility/StringViewHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ uint64_t hashNumber(Int i, uint64_t h = Fnv1aBasis)
{
static_assert(std::is_arithmetic<Int>::value,
"The hashed object must be of arithmetic type");
return hash(absl::string_view(reinterpret_cast<const char*>(&i), sizeof(i)), h);
union {
uint64_t u64;
Int i;
} un {};
un.i = i;
return (h ^ un.u64) * Fnv1aPrime;
}

/**
Expand Down

0 comments on commit f8fc628

Please sign in to comment.