Cosmetics

This commit is contained in:
paulfd 2019-08-25 00:46:31 +02:00
parent dba851385d
commit 2f203fe163
6 changed files with 94 additions and 84 deletions

View file

@ -3,14 +3,17 @@
#include <signal.h> #include <signal.h>
#include <string_view> #include <string_view>
inline void trimInPlace(std::string_view& s) inline void trimInPlace(std::string_view &s)
{ {
const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v"); const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v");
if (leftPosition != s.npos) { if (leftPosition != s.npos)
{
s.remove_prefix(leftPosition); s.remove_prefix(leftPosition);
const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v"); const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v");
s.remove_suffix(s.size() - rightPosition - 1); s.remove_suffix(s.size() - rightPosition - 1);
} else { }
else
{
s.remove_suffix(s.size()); s.remove_suffix(s.size());
} }
} }
@ -18,11 +21,14 @@ inline void trimInPlace(std::string_view& s)
inline std::string_view trim(std::string_view s) inline std::string_view trim(std::string_view s)
{ {
const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v"); const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v");
if (leftPosition != s.npos) { if (leftPosition != s.npos)
{
s.remove_prefix(leftPosition); s.remove_prefix(leftPosition);
const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v"); const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v");
s.remove_suffix(s.size() - rightPosition - 1); s.remove_suffix(s.size() - rightPosition - 1);
} else { }
else
{
s.remove_suffix(s.size()); s.remove_suffix(s.size());
} }
return s; return s;
@ -30,7 +36,7 @@ inline std::string_view trim(std::string_view s)
inline constexpr unsigned int Fnv1aBasis = 0x811C9DC5; inline constexpr unsigned int Fnv1aBasis = 0x811C9DC5;
inline constexpr unsigned int Fnv1aPrime = 0x01000193; inline constexpr unsigned int Fnv1aPrime = 0x01000193;
inline constexpr unsigned int hash(const char* s, unsigned int h = Fnv1aBasis) inline constexpr unsigned int hash(const char *s, unsigned int h = Fnv1aBasis)
{ {
return !*s ? h : hash(s + 1, static_cast<unsigned int>((h ^ *s) * static_cast<unsigned long long>(Fnv1aPrime))); return !*s ? h : hash(s + 1, static_cast<unsigned int>((h ^ *s) * static_cast<unsigned long long>(Fnv1aPrime)));
} }
@ -106,10 +112,11 @@ inline constexpr Type mag2db(Type in)
return static_cast<Type>(20.0) * std::log10(in); return static_cast<Type>(20.0) * std::log10(in);
} }
namespace Random { namespace Random
{
static inline std::random_device randomDevice; static inline std::random_device randomDevice;
static inline std::mt19937 randomGenerator { randomDevice() }; static inline std::mt19937 randomGenerator{randomDevice()};
} } // namespace Random
inline float midiNoteFrequency(const int noteNumber) inline float midiNoteFrequency(const int noteNumber)
{ {
@ -117,64 +124,58 @@ inline float midiNoteFrequency(const int noteNumber)
} }
template <class Type> template <class Type>
constexpr Type pi { 3.141592653589793238462643383279502884 }; constexpr Type pi{3.141592653589793238462643383279502884};
template <class Type> template <class Type>
constexpr Type twoPi { 2 * pi<Type> }; constexpr Type twoPi{2 * pi<Type>};
template <class Type> template <class Type>
constexpr Type piTwo { pi<Type> / 2 }; constexpr Type piTwo{pi<Type> / 2};
#include <atomic> #include <atomic>
template <class Owner> template <class Owner>
class LeakDetector { class LeakDetector
{
public: public:
LeakDetector() LeakDetector()
{ {
// auto currentCounter = objectCounter.count.load();
// auto desiredCounter = currentCounter + 1;
// while(!objectCounter.count.compare_exchange_weak(currentCounter, desiredCounter))
// desiredCounter = currentCounter + 1;
objectCounter.count++; objectCounter.count++;
// DBG("Counted " << desiredCounter << " " << Owner::getClassName());
} }
LeakDetector(const LeakDetector&) LeakDetector(const LeakDetector &)
{ {
objectCounter.count++; objectCounter.count++;
} }
~LeakDetector() ~LeakDetector()
{ {
objectCounter.count--; objectCounter.count--;
// auto currentCounter = objectCounter.count.load(); if (objectCounter.count.load() < 0)
// auto desiredCounter = currentCounter - 1; {
// while(!objectCounter.count.compare_exchange_weak(currentCounter, desiredCounter))
// desiredCounter = currentCounter - 1;
// DBG("Counted " << desiredCounter << " " << Owner::getClassName() << " left after deletion");
if (objectCounter.count.load() < 0) {
DBG("Deleted a dangling pointer for class " << Owner::getClassName()); DBG("Deleted a dangling pointer for class " << Owner::getClassName());
// Deleted a dangling pointer! // Deleted a dangling pointer!
// ASSERTFALSE; ASSERTFALSE;
} }
} }
private: private:
struct ObjectCounter { struct ObjectCounter
{
ObjectCounter() = default; ObjectCounter() = default;
~ObjectCounter() ~ObjectCounter()
{ {
if (auto residualCount = count.load() > 0) { if (auto residualCount = count.load() > 0)
{
DBG("Leaked " << residualCount << " instance(s) of class " << Owner::getClassName()); DBG("Leaked " << residualCount << " instance(s) of class " << Owner::getClassName());
// Leaked ojects // Leaked ojects
// ASSERTFALSE; ASSERTFALSE;
} }
}; };
std::atomic<int> count { 0 }; std::atomic<int> count{0};
}; };
static inline ObjectCounter objectCounter; static inline ObjectCounter objectCounter;
}; };
#ifndef NDEBUG #ifndef NDEBUG
#define LEAK_DETECTOR(Class) \ #define LEAK_DETECTOR(Class) \
friend class LeakDetector<Class>; \ friend class LeakDetector<Class>; \
static const char* getClassName() noexcept { return #Class; } \ static const char *getClassName() { return #Class; } \
LeakDetector<Class> leakDetector; LeakDetector<Class> leakDetector;
#else #else
#define LEAK_DETECTOR(Class) #define LEAK_DETECTOR(Class)

View file

@ -8,38 +8,38 @@
using svregex_iterator = std::regex_iterator<std::string_view::const_iterator>; using svregex_iterator = std::regex_iterator<std::string_view::const_iterator>;
using svmatch_results = std::match_results<std::string_view::const_iterator>; using svmatch_results = std::match_results<std::string_view::const_iterator>;
void removeCommentOnLine(std::string_view& line) void removeCommentOnLine(std::string_view &line)
{ {
if (auto position = line.find("//"); position != line.npos) if (auto position = line.find("//"); position != line.npos)
line.remove_suffix(line.size() - position); line.remove_suffix(line.size() - position);
} }
bool sfz::Parser::loadSfzFile(const std::filesystem::path& file) bool sfz::Parser::loadSfzFile(const std::filesystem::path &file)
{ {
const auto sfzFile = file.is_absolute() ? file : rootDirectory / file; const auto sfzFile = file.is_absolute() ? file : rootDirectory / file;
if (!std::filesystem::exists(sfzFile)) if (!std::filesystem::exists(sfzFile))
return false; return false;
rootDirectory = file.parent_path(); rootDirectory = file.parent_path();
std::vector<std::string> lines; std::vector<std::string> lines;
readSfzFile(file, lines); readSfzFile(file, lines);
aggregatedContent = absl::StrJoin(lines, " "); aggregatedContent = absl::StrJoin(lines, " ");
const std::string_view aggregatedView { aggregatedContent }; const std::string_view aggregatedView{aggregatedContent};
svregex_iterator headerIterator(aggregatedView.cbegin(), aggregatedView.cend(), sfz::Regexes::headers); svregex_iterator headerIterator(aggregatedView.cbegin(), aggregatedView.cend(), sfz::Regexes::headers);
const auto regexEnd = svregex_iterator(); const auto regexEnd = svregex_iterator();
std::vector<Opcode> currentMembers; std::vector<Opcode> currentMembers;
for (; headerIterator != regexEnd; ++headerIterator) for (; headerIterator != regexEnd; ++headerIterator)
{ {
svmatch_results headerMatch = *headerIterator; svmatch_results headerMatch = *headerIterator;
// Can't use uniform initialization here because it generates narrowing conversions // Can't use uniform initialization here because it generates narrowing conversions
const std::string_view header(&*headerMatch[1].first, headerMatch[1].length()); const std::string_view header(&*headerMatch[1].first, headerMatch[1].length());
const std::string_view members(&*headerMatch[2].first, headerMatch[2].length()); const std::string_view members(&*headerMatch[2].first, headerMatch[2].length());
auto paramIterator = svregex_iterator (members.cbegin(), members.cend(), sfz::Regexes::members); auto paramIterator = svregex_iterator(members.cbegin(), members.cend(), sfz::Regexes::members);
// Store or handle members // Store or handle members
for (; paramIterator != regexEnd; ++paramIterator) for (; paramIterator != regexEnd; ++paramIterator)
@ -47,16 +47,16 @@ bool sfz::Parser::loadSfzFile(const std::filesystem::path& file)
const svmatch_results paramMatch = *paramIterator; const svmatch_results paramMatch = *paramIterator;
const std::string_view opcode(&*paramMatch[1].first, paramMatch[1].length()); const std::string_view opcode(&*paramMatch[1].first, paramMatch[1].length());
const std::string_view value(&*paramMatch[2].first, paramMatch[2].length()); const std::string_view value(&*paramMatch[2].first, paramMatch[2].length());
currentMembers.emplace_back(opcode, value); currentMembers.emplace_back(opcode, value);
} }
callback(header, currentMembers); callback(header, currentMembers);
currentMembers.clear(); currentMembers.clear();
} }
return true; return true;
} }
void sfz::Parser::readSfzFile(const std::filesystem::path& fileName, std::vector<std::string>& lines) noexcept void sfz::Parser::readSfzFile(const std::filesystem::path &fileName, std::vector<std::string> &lines) noexcept
{ {
std::ifstream fileStream(fileName.c_str()); std::ifstream fileStream(fileName.c_str());
if (!fileStream) if (!fileStream)
@ -69,7 +69,7 @@ void sfz::Parser::readSfzFile(const std::filesystem::path& fileName, std::vector
std::string tmpString; std::string tmpString;
while (std::getline(fileStream, tmpString)) while (std::getline(fileStream, tmpString))
{ {
std::string_view tmpView { tmpString }; std::string_view tmpView{tmpString};
removeCommentOnLine(tmpView); removeCommentOnLine(tmpView);
trimInPlace(tmpView); trimInPlace(tmpView);
@ -110,13 +110,13 @@ void sfz::Parser::readSfzFile(const std::filesystem::path& fileName, std::vector
std::string newString; std::string newString;
newString.reserve(tmpView.length()); newString.reserve(tmpView.length());
std::string::size_type lastPos = 0; std::string::size_type lastPos = 0;
std::string::size_type findPos = tmpView.find(sfz::config::defineCharacter, lastPos); std::string::size_type findPos = tmpView.find(sfz::config::defineCharacter, lastPos);
while(findPos < tmpView.npos) while (findPos < tmpView.npos)
{ {
newString.append(tmpView, lastPos, findPos - lastPos); newString.append(tmpView, lastPos, findPos - lastPos);
for (auto& definePair: defines) for (auto &definePair : defines)
{ {
std::string_view candidate = tmpView.substr(findPos, definePair.first.length()); std::string_view candidate = tmpView.substr(findPos, definePair.first.length());
if (candidate == definePair.first) if (candidate == definePair.first)

View file

@ -4,26 +4,27 @@
#include <bits/stdint-uintn.h> #include <bits/stdint-uintn.h>
#include <random> #include <random>
bool sfz::Region::parseOpcode(const Opcode& opcode) bool sfz::Region::parseOpcode(const Opcode &opcode)
{ {
switch (hash(opcode.opcode)) { switch (hash(opcode.opcode))
{
// Sound source: sample playback // Sound source: sample playback
case hash("sample"): case hash("sample"):
sample = absl::StrReplaceAll(trim(opcode.value), { { "\\", "/" } }); sample = absl::StrReplaceAll(trim(opcode.value), {{"\\", "/"}});
break; break;
case hash("delay"): case hash("delay"):
setValueFromOpcode(opcode, delay, Default::delayRange); setValueFromOpcode(opcode, delay, Default::delayRange);
break; break;
case hash("delay_random"): case hash("delay_random"):
setValueFromOpcode(opcode, delayRandom, Default::delayRange); setValueFromOpcode(opcode, delayRandom, Default::delayRange);
delayDistribution.param( std::uniform_real_distribution<float>::param_type(0, delayRandom) ); delayDistribution.param(std::uniform_real_distribution<float>::param_type(0, delayRandom));
break; break;
case hash("offset"): case hash("offset"):
setValueFromOpcode(opcode, offset, Default::offsetRange); setValueFromOpcode(opcode, offset, Default::offsetRange);
break; break;
case hash("offset_random"): case hash("offset_random"):
setValueFromOpcode(opcode, offsetRandom, Default::offsetRange); setValueFromOpcode(opcode, offsetRandom, Default::offsetRange);
offsetDistribution.param( std::uniform_int_distribution<uint32_t>::param_type(0, offsetRandom) ); offsetDistribution.param(std::uniform_int_distribution<uint32_t>::param_type(0, offsetRandom));
break; break;
case hash("end"): case hash("end"):
setValueFromOpcode(opcode, sampleEnd, Default::sampleEndRange); setValueFromOpcode(opcode, sampleEnd, Default::sampleEndRange);
@ -33,7 +34,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
break; break;
case hash("loopmode"): case hash("loopmode"):
case hash("loop_mode"): case hash("loop_mode"):
switch (hash(opcode.value)) { switch (hash(opcode.value))
{
case hash("no_loop"): case hash("no_loop"):
loopMode = SfzLoopMode::no_loop; loopMode = SfzLoopMode::no_loop;
break; break;
@ -68,7 +70,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
setValueFromOpcode(opcode, offBy, Default::groupRange); setValueFromOpcode(opcode, offBy, Default::groupRange);
break; break;
case hash("off_mode"): case hash("off_mode"):
switch (hash(opcode.value)) { switch (hash(opcode.value))
{
case hash("fast"): case hash("fast"):
offMode = SfzOffMode::fast; offMode = SfzOffMode::fast;
break; break;
@ -112,7 +115,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
setRangeEndFromOpcode(opcode, bendRange, Default::bendRange); setRangeEndFromOpcode(opcode, bendRange, Default::bendRange);
break; break;
case hash("locc"): case hash("locc"):
if (opcode.parameter) { if (opcode.parameter)
{
setRangeStartFromOpcode(opcode, ccConditions[*opcode.parameter], Default::ccRange); setRangeStartFromOpcode(opcode, ccConditions[*opcode.parameter], Default::ccRange);
} }
break; break;
@ -142,7 +146,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
previousKeySwitched = false; previousKeySwitched = false;
break; break;
case hash("sw_vel"): case hash("sw_vel"):
switch (hash(opcode.value)) { switch (hash(opcode.value))
{
case hash("current"): case hash("current"):
velocityOverride = SfzVelocityOverride::current; velocityOverride = SfzVelocityOverride::current;
break; break;
@ -181,7 +186,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
break; break;
// Region logic: triggers // Region logic: triggers
case hash("trigger"): case hash("trigger"):
switch (hash(opcode.value)) { switch (hash(opcode.value))
{
case hash("attack"): case hash("attack"):
trigger = SfzTrigger::attack; trigger = SfzTrigger::attack;
break; break;
@ -257,7 +263,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
gainDistribution.param(std::uniform_real_distribution<float>::param_type(-ampRandom, ampRandom)); gainDistribution.param(std::uniform_real_distribution<float>::param_type(-ampRandom, ampRandom));
break; break;
case hash("amp_velcurve_"): case hash("amp_velcurve_"):
if (opcode.parameter && Default::ccRange.containsWithEnd(*opcode.parameter)) { if (opcode.parameter && Default::ccRange.containsWithEnd(*opcode.parameter))
{
if (auto value = readOpcode(opcode.value, Default::ampVelcurveRange); value) if (auto value = readOpcode(opcode.value, Default::ampVelcurveRange); value)
velocityPoints.emplace_back(*opcode.parameter, *value); velocityPoints.emplace_back(*opcode.parameter, *value);
} }
@ -287,7 +294,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
setRangeEndFromOpcode(opcode, crossfadeVelOutRange, Default::velocityRange); setRangeEndFromOpcode(opcode, crossfadeVelOutRange, Default::velocityRange);
break; break;
case hash("xf_keycurve"): case hash("xf_keycurve"):
switch (hash(opcode.value)) { switch (hash(opcode.value))
{
case hash("power"): case hash("power"):
crossfadeKeyCurve = SfzCrossfadeCurve::power; crossfadeKeyCurve = SfzCrossfadeCurve::power;
break; break;
@ -299,7 +307,8 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
} }
break; break;
case hash("xf_velcurve"): case hash("xf_velcurve"):
switch (hash(opcode.value)) { switch (hash(opcode.value))
{
case hash("power"): case hash("power"):
crossfadeVelCurve = SfzCrossfadeCurve::power; crossfadeVelCurve = SfzCrossfadeCurve::power;
break; break;
@ -414,8 +423,10 @@ bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity,
if (!chanOk) if (!chanOk)
return false; return false;
if (keyswitchRange.containsWithEnd(noteNumber)) { if (keyswitchRange.containsWithEnd(noteNumber))
if (keyswitch) { {
if (keyswitch)
{
if (*keyswitch == noteNumber) if (*keyswitch == noteNumber)
keySwitched = true; keySwitched = true;
else else
@ -430,7 +441,8 @@ bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity,
} }
const bool keyOk = keyRange.containsWithEnd(noteNumber); const bool keyOk = keyRange.containsWithEnd(noteNumber);
if (keyOk) { if (keyOk)
{
// Update the number of notes playing for the region // Update the number of notes playing for the region
activeNotesInRange++; activeNotesInRange++;
@ -445,7 +457,8 @@ bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity,
if (trigger == SfzTrigger::release_key || velocityOverride == SfzVelocityOverride::previous) if (trigger == SfzTrigger::release_key || velocityOverride == SfzVelocityOverride::previous)
lastNoteVelocities[noteNumber] = velocity; lastNoteVelocities[noteNumber] = velocity;
if (previousNote) { if (previousNote)
{
if (*previousNote == noteNumber) if (*previousNote == noteNumber)
previousKeySwitched = true; previousKeySwitched = true;
else else
@ -468,13 +481,14 @@ bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity,
return keyOk && velOk && chanOk && randOk && (attackTrigger || firstLegatoNote || notFirstLegatoNote); return keyOk && velOk && chanOk && randOk && (attackTrigger || firstLegatoNote || notFirstLegatoNote);
} }
bool sfz::Region::registerNoteOff(int channel, int noteNumber, uint8_t velocity [[maybe_unused]], float randValue) bool sfz::Region::registerNoteOff(int channel, int noteNumber, uint8_t velocity[[maybe_unused]], float randValue)
{ {
const bool chanOk = channelRange.containsWithEnd(channel); const bool chanOk = channelRange.containsWithEnd(channel);
if (!chanOk) if (!chanOk)
return false; return false;
if (keyswitchRange.containsWithEnd(noteNumber)) { if (keyswitchRange.containsWithEnd(noteNumber))
{
if (keyswitchDown && *keyswitchDown == noteNumber) if (keyswitchDown && *keyswitchDown == noteNumber)
keySwitched = false; keySwitched = false;

View file

@ -13,12 +13,6 @@ void writeInterleaved<float, true>(absl::Span<const float> inputLeft, absl::Span
writeInterleaved<float, false>(inputLeft, inputRight, output); writeInterleaved<float, false>(inputLeft, inputRight, output);
} }
// template<class Type, bool SIMD=false>
// void linearRamp(absl::Span<Type> output, Type start, Type step);
// template<class Type, bool SIMD=false>
// void exponentialRamp(absl::Span<Type> output, Type start, Type step);
template<> template<>
void fill<float, true>(absl::Span<float> output, float value) noexcept void fill<float, true>(absl::Span<float> output, float value) noexcept
{ {

View file

@ -133,6 +133,7 @@ public:
void fillWithData(StereoSpan<float> buffer) void fillWithData(StereoSpan<float> buffer)
{ {
const StereoSpan<const float> source([&]() -> StereoBuffer<float>& { const StereoSpan<const float> source([&]() -> StereoBuffer<float>& {
// TODO: shouldn't need to check fileData here, something is a bit strange...
if (dataReady.load(std::memory_order_seq_cst) && fileData != nullptr) if (dataReady.load(std::memory_order_seq_cst) && fileData != nullptr)
return *fileData; return *fileData;
else else
@ -191,12 +192,12 @@ public:
void reset() void reset()
{ {
dataReady.store(false);
state = State::idle;
if (region != nullptr) { if (region != nullptr) {
DBG("Reset voice with sample " << region->sample); DBG("Reset voice with sample " << region->sample);
} }
region = nullptr; region = nullptr;
state = State::idle;
dataReady.store(false);
noteIsOff = false; noteIsOff = false;
} }