Cosmetics
This commit is contained in:
parent
dba851385d
commit
2f203fe163
6 changed files with 94 additions and 84 deletions
|
|
@ -49,14 +49,14 @@ void sfz::FilePool::loadingThread()
|
||||||
DBG("Background thread error: voice is null.");
|
DBG("Background thread error: voice is null.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG("Background loading of: " << fileToLoad.sample);
|
DBG("Background loading of: " << fileToLoad.sample);
|
||||||
std::filesystem::path file { rootDirectory / fileToLoad.sample };
|
std::filesystem::path file { rootDirectory / fileToLoad.sample };
|
||||||
if (!std::filesystem::exists(file)) {
|
if (!std::filesystem::exists(file)) {
|
||||||
DBG("Background thread: no file " << fileToLoad.sample << " exists.");
|
DBG("Background thread: no file " << fileToLoad.sample << " exists.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SndfileHandle sndFile(reinterpret_cast<const char*>(file.c_str()));
|
SndfileHandle sndFile(reinterpret_cast<const char*>(file.c_str()));
|
||||||
auto fileLoaded = std::make_unique<StereoBuffer<float>>(fileToLoad.numFrames);
|
auto fileLoaded = std::make_unique<StereoBuffer<float>>(fileToLoad.numFrames);
|
||||||
auto readBuffer = std::make_unique<Buffer<float>>(fileToLoad.numFrames * 2);
|
auto readBuffer = std::make_unique<Buffer<float>>(fileToLoad.numFrames * 2);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -82,7 +82,7 @@ void sfz::Parser::readSfzFile(const std::filesystem::path& fileName, std::vector
|
||||||
{
|
{
|
||||||
auto includePath = includeMatch.str(1);
|
auto includePath = includeMatch.str(1);
|
||||||
std::replace(includePath.begin(), includePath.end(), '\\', '/');
|
std::replace(includePath.begin(), includePath.end(), '\\', '/');
|
||||||
const auto newFile = rootDirectory / includePath;
|
const auto newFile = rootDirectory / includePath;
|
||||||
auto alreadyIncluded = std::find(includedFiles.begin(), includedFiles.end(), newFile);
|
auto alreadyIncluded = std::find(includedFiles.begin(), includedFiles.end(), newFile);
|
||||||
if (std::filesystem::exists(newFile))
|
if (std::filesystem::exists(newFile))
|
||||||
{
|
{
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -126,7 +126,7 @@ void sfz::Parser::readSfzFile(const std::filesystem::path& fileName, std::vector
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastPos <= findPos)
|
if (lastPos <= findPos)
|
||||||
{
|
{
|
||||||
newString += sfz::config::defineCharacter;
|
newString += sfz::config::defineCharacter;
|
||||||
|
|
@ -138,6 +138,6 @@ void sfz::Parser::readSfzFile(const std::filesystem::path& fileName, std::vector
|
||||||
|
|
||||||
// Copy the rest of the string
|
// Copy the rest of the string
|
||||||
newString += tmpView.substr(lastPos);
|
newString += tmpView.substr(lastPos);
|
||||||
lines.push_back(std::move(newString));
|
lines.push_back(std::move(newString));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue