Reorganized the helpers to make more sense

This commit is contained in:
paulfd 2019-08-30 13:05:07 +02:00
parent ab14b7fda3
commit 004afb6d8a
35 changed files with 546 additions and 257 deletions

View file

@ -73,6 +73,7 @@ set(COMMON_SOURCES
sources/FilePool.cpp
sources/Region.cpp
sources/Voice.cpp
sources/ScopedFTZ.cpp
sources/SfzHelpers.cpp
sources/FloatEnvelopes.cpp
sources/Parser.cpp

View file

@ -23,7 +23,6 @@
#include "ADSREnvelope.h"
#include "Globals.h"
#include "Helpers.h"
#include "SIMDHelpers.h"
#include <algorithm>

View file

@ -22,7 +22,7 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "Helpers.h"
#include "LeakDetector.h"
#include <absl/types/span.h>
namespace sfz {

View file

@ -23,7 +23,7 @@
#pragma once
#include "Globals.h"
#include "Helpers.h"
#include "LeakDetector.h"
#include <cstdlib>
#include <cstring>
#include <memory>

View file

@ -22,7 +22,7 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "Helpers.h"
#include "LeakDetector.h"
#include <map>
namespace sfz {

48
sources/Debug.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
#ifndef NDEBUG
#include <iostream>
// These trap into the signal library rather than your own sourcecode
// #include <signal.h>
// #define ASSERTFALSE { ::kill(0, SIGTRAP); }
// #define ASSERTFALSE { raise(SIGTRAP); }
#if (__linux__ || __unix__)
// Break in source code
#if (__x86_64__ || __i386__)
#define ASSERTFALSE \
{ \
__asm__("int3"); \
}
#elif (__arm__ || __aarch64__)
#define ASSERTFALSE \
{ \
__builtin_trap(); \
}
#endif
#elif (_WIN32 || _WIN64)
#pragma intrinsic(__debugbreak)
#define ASSERTFALSE \
{ \
__debugbreak(); \
}
#else
#define ASSERTFALSE
#endif
// Assert stuff
#define ASSERT(expression) \
if (!(expression)) \
ASSERTFALSE
// Debug message
#define DBG(ostream) std::cerr << ostream << '\n'
#else // NDEBUG
#define ASSERTFALSE
#define ASSERT(expression)
#define DBG(ostream)
#endif

View file

@ -24,6 +24,7 @@
#pragma once
#include "Globals.h"
#include "Defaults.h"
#include "LeakDetector.h"
#include "SfzHelpers.h"
#include <optional>

View file

@ -23,8 +23,10 @@
#include "FilePool.h"
#include "Globals.h"
#include "Debug.h"
#include "absl/types/span.h"
#include <chrono>
#include <sndfile.hh>
using namespace std::chrono_literals;
template <class T>

View file

@ -23,13 +23,13 @@
#pragma once
#include "Defaults.h"
#include "LeakDetector.h"
#include "StereoBuffer.h"
#include "Voice.h"
#include "readerwriterqueue.h"
#include <absl/container/flat_hash_map.h>
#include <filesystem>
#include <optional>
#include <sndfile.hh>
#include <string_view>
#include <thread>

View file

@ -1,231 +0,0 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <cstdint>
#include <random>
#include <signal.h>
#include <string_view>
#ifdef HAVE_X86INTRIN_H
#include <x86intrin.h>
#endif
#ifdef HAVE_INTRIN_H
#include <intrin.h>
#endif
inline void trimInPlace(std::string_view& s)
{
const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v");
if (leftPosition != s.npos) {
s.remove_prefix(leftPosition);
const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v");
s.remove_suffix(s.size() - rightPosition - 1);
} else {
s.remove_suffix(s.size());
}
}
inline std::string_view trim(std::string_view s)
{
const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v");
if (leftPosition != s.npos) {
s.remove_prefix(leftPosition);
const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v");
s.remove_suffix(s.size() - rightPosition - 1);
} else {
s.remove_suffix(s.size());
}
return s;
}
inline constexpr uint64_t Fnv1aBasis = 0x811C9DC5;
inline constexpr uint64_t Fnv1aPrime = 0x01000193;
inline constexpr uint64_t hash(std::string_view s, uint64_t h = Fnv1aBasis)
{
if (s.length() > 0)
return hash( { s.data() + 1, s.length() - 1 }, (h ^ s.front()) * Fnv1aPrime );
return h;
}
template <class T>
inline constexpr T min(T op1, T op2) { return std::min(op1, op2); }
template <class T>
inline constexpr T min(T op1, T op2, T op3) { return std::min(op1, std::min(op2, op3)); }
template <class T>
inline constexpr T min(T op1, T op2, T op3, T op4) { return std::min(op1, std::min(op2, std::min(op3, op4))); }
#ifndef NDEBUG
#if __linux__ || __unix__
// These trap into the signal library rather than your own sourcecode
// #define ASSERTFALSE { ::kill(0, SIGTRAP); }
// #define ASSERTFALSE { raise(SIGTRAP); }
#define ASSERTFALSE \
{ \
__asm__("int3"); \
}
#elif _WIN32 || _WIN64
#pragma intrinsic(__debugbreak)
#define ASSERTFALSE \
{ \
__debugbreak(); \
}
#else
#define ASSERTFALSE \
{ \
__asm int 3; \
}
#endif
#define ASSERT(expression) \
if (!(expression)) \
ASSERTFALSE
#include <iostream>
#define DBG(ostream) std::cerr << ostream << '\n'
#else
#define ASSERTFALSE
#define ASSERT(expression)
#define DBG(ostream)
#endif
template <class Type>
inline constexpr Type db2pow(Type in)
{
return std::pow(static_cast<Type>(10.0), in * static_cast<Type>(0.1));
}
template <class Type>
inline constexpr Type pow2db(Type in)
{
return static_cast<Type>(10.0) * std::log10(in);
}
template <class Type>
inline constexpr Type db2mag(Type in)
{
return std::pow(static_cast<Type>(10.0), in * static_cast<Type>(0.05));
}
template <class Type>
inline constexpr Type mag2db(Type in)
{
return static_cast<Type>(20.0) * std::log10(in);
}
namespace Random {
static inline std::random_device randomDevice;
static inline std::mt19937 randomGenerator { randomDevice() };
} // namespace Random
inline float midiNoteFrequency(const int noteNumber)
{
return 440.0f * std::pow(2.0f, (noteNumber - 69) / 12.0f);
}
template <class Type>
constexpr Type pi { 3.141592653589793238462643383279502884 };
template <class Type>
constexpr Type twoPi { 2 * pi<Type> };
template <class Type>
constexpr Type piTwo { pi<Type> / 2 };
#include <atomic>
template <class Owner>
class LeakDetector {
public:
LeakDetector()
{
objectCounter.count++;
}
LeakDetector(const LeakDetector&)
{
objectCounter.count++;
}
~LeakDetector()
{
objectCounter.count--;
if (objectCounter.count.load() < 0) {
DBG("Deleted a dangling pointer for class " << Owner::getClassName());
// Deleted a dangling pointer!
ASSERTFALSE;
}
}
private:
struct ObjectCounter {
ObjectCounter() = default;
~ObjectCounter()
{
if (auto residualCount = count.load() > 0) {
DBG("Leaked " << residualCount << " instance(s) of class " << Owner::getClassName());
// Leaked ojects
ASSERTFALSE;
}
};
std::atomic<int> count { 0 };
};
static inline ObjectCounter objectCounter;
};
#ifndef NDEBUG
#define LEAK_DETECTOR(Class) \
friend class LeakDetector<Class>; \
static const char* getClassName() { return #Class; } \
LeakDetector<Class> leakDetector;
#else
#define LEAK_DETECTOR(Class)
#endif
class ScopedFTZ {
public:
ScopedFTZ()
{
#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H)
unsigned mask = _MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK;
registerState = _mm_getcsr();
_mm_setcsr((registerState & (~mask)) | mask);
#elif HAVE_ARM_NEON_H
intptr_t mask = (1 << 24);
asm volatile("vmrs %0, fpscr"
: "=r"(registerState));
asm volatile("vmsr fpscr, %0"
:
: "ri"((registerState & (~mask)) | mask));
#endif
}
~ScopedFTZ()
{
#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H)
_mm_setcsr(registerState);
#elif HAVE_ARM_NEON_H
asm volatile("vmsr %0, fpscr"
: "=r"(registerState));
#endif
}
private:
unsigned registerState;
};

72
sources/LeakDetector.h Normal file
View file

@ -0,0 +1,72 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <atomic>
#include "Debug.h"
template <class Owner>
class LeakDetector {
public:
LeakDetector()
{
objectCounter.count++;
}
LeakDetector(const LeakDetector&)
{
objectCounter.count++;
}
~LeakDetector()
{
objectCounter.count--;
if (objectCounter.count.load() < 0) {
DBG("Deleted a dangling pointer for class " << Owner::getClassName());
// Deleted a dangling pointer!
ASSERTFALSE;
}
}
private:
struct ObjectCounter {
ObjectCounter() = default;
~ObjectCounter()
{
if (auto residualCount = count.load() > 0) {
DBG("Leaked " << residualCount << " instance(s) of class " << Owner::getClassName());
// Leaked ojects
ASSERTFALSE;
}
};
std::atomic<int> count { 0 };
};
static inline ObjectCounter objectCounter;
};
#ifndef NDEBUG
#define LEAK_DETECTOR(Class) \
friend class LeakDetector<Class>; \
static const char* getClassName() { return #Class; } \
LeakDetector<Class> leakDetector;
#else
#define LEAK_DETECTOR(Class)
#endif

View file

@ -22,8 +22,8 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "LinearEnvelope.h"
#include "Helpers.h"
#include "SIMDHelpers.h"
#include "MathHelpers.h"
#include <absl/algorithm/container.h>
namespace sfz {

View file

@ -23,7 +23,7 @@
#pragma once
#include "Globals.h"
#include "Helpers.h"
#include "LeakDetector.h"
#include <absl/types/span.h>
#include <functional>
#include <type_traits>

76
sources/MathHelpers.h Normal file
View file

@ -0,0 +1,76 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <algorithm>
#include <cmath>
#include <random>
template <class T>
inline constexpr T min(T op1, T op2) { return std::min(op1, op2); }
template <class T>
inline constexpr T min(T op1, T op2, T op3) { return std::min(op1, std::min(op2, op3)); }
template <class T>
inline constexpr T min(T op1, T op2, T op3, T op4) { return std::min(op1, std::min(op2, std::min(op3, op4))); }
template <class Type>
inline constexpr Type db2pow(Type in)
{
return std::pow(static_cast<Type>(10.0), in * static_cast<Type>(0.1));
}
template <class Type>
inline constexpr Type pow2db(Type in)
{
return static_cast<Type>(10.0) * std::log10(in);
}
template <class Type>
inline constexpr Type db2mag(Type in)
{
return std::pow(static_cast<Type>(10.0), in * static_cast<Type>(0.05));
}
template <class Type>
inline constexpr Type mag2db(Type in)
{
return static_cast<Type>(20.0) * std::log10(in);
}
namespace Random {
static inline std::random_device randomDevice;
static inline std::mt19937 randomGenerator { randomDevice() };
} // namespace Random
inline float midiNoteFrequency(const int noteNumber)
{
return 440.0f * std::pow(2.0f, (noteNumber - 69) / 12.0f);
}
template <class Type>
constexpr Type pi { 3.141592653589793238462643383279502884 };
template <class Type>
constexpr Type twoPi { 2 * pi<Type> };
template <class Type>
constexpr Type piTwo { pi<Type> / 2 };

View file

@ -23,7 +23,7 @@
#pragma once
#include "Globals.h"
#include "Helpers.h"
#include "MathHelpers.h"
#include <absl/types/span.h>
#include <cmath>

View file

@ -22,6 +22,7 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Opcode.h"
#include "StringViewHelpers.h"
sfz::Opcode::Opcode(std::string_view inputOpcode, std::string_view inputValue)
: opcode(inputOpcode)

View file

@ -23,7 +23,7 @@
#pragma once
#include "Defaults.h"
#include "Helpers.h"
#include "LeakDetector.h"
#include "Range.h"
#include "SfzHelpers.h"
#include <optional>

View file

@ -23,7 +23,7 @@
#include "Parser.h"
#include "Globals.h"
#include "Helpers.h"
#include "StringViewHelpers.h"
#include "absl/strings/str_join.h"
#include <algorithm>
#include <fstream>

View file

@ -22,7 +22,8 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Region.h"
#include "Helpers.h"
#include "Debug.h"
#include "StringViewHelpers.h"
#include "absl/strings/str_replace.h"
#include <random>

View file

@ -23,6 +23,7 @@
#pragma once
#include "CCMap.h"
#include "LeakDetector.h"
#include "Defaults.h"
#include "EGDescription.h"
#include "Opcode.h"

View file

@ -21,7 +21,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Helpers.h"
#include "SIMDHelpers.h"
template <>

View file

@ -23,7 +23,8 @@
#pragma once
#include "Globals.h"
#include "Helpers.h"
#include "Debug.h"
#include "MathHelpers.h"
#include <absl/algorithm/container.h>
#include <absl/types/span.h>
#include <cmath>

View file

@ -21,7 +21,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Helpers.h"
#include "SIMDHelpers.h"
#if HAVE_X86INTRIN_H

54
sources/ScopedFTZ.cpp Normal file
View file

@ -0,0 +1,54 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ScopedFTZ.h"
#if (HAVE_X86INTRIN_H)
#include <x86intrin.h>
#elif (HAVE_INTRIN_H)
#include <intrin.h>
#elif (HAVE_ARM_NEON_H)
#include "arm_neon.h"
#endif
ScopedFTZ::ScopedFTZ()
{
#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H)
unsigned mask = _MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK;
registerState = _mm_getcsr();
_mm_setcsr((registerState & (~mask)) | mask);
#elif HAVE_ARM_NEON_H
intptr_t mask = (1 << 24);
asm volatile("vmrs %0, fpscr" : "=r"(registerState));
asm volatile("vmsr fpscr, %0" : : "ri"((registerState & (~mask)) | mask));
#endif
}
ScopedFTZ::~ScopedFTZ()
{
#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H)
_mm_setcsr(registerState);
#elif HAVE_ARM_NEON_H
asm volatile("vmsr %0, fpscr" : : "ri"(registerState));
#endif
}

31
sources/ScopedFTZ.h Normal file
View file

@ -0,0 +1,31 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class ScopedFTZ {
public:
ScopedFTZ();
~ScopedFTZ();
private:
unsigned registerState;
};

171
sources/SfzHelpers.cpp Normal file
View file

@ -0,0 +1,171 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "SfzHelpers.h"
#include "StringViewHelpers.h"
std::optional<uint8_t> sfz::readNoteValue(const std::string_view& value)
{
switch(hash(value))
{
case hash("c-1"): case hash("C-1"): return (uint8_t) 0;
case hash("c#-1"): case hash("C#-1"): return (uint8_t) 1;
case hash("d-1"): case hash("D-1"): return (uint8_t) 2;
case hash("d#-1"): case hash("D#-1"): return (uint8_t) 3;
case hash("e-1"): case hash("E-1"): return (uint8_t) 4;
case hash("f-1"): case hash("F-1"): return (uint8_t) 5;
case hash("f#-1"): case hash("F#-1"): return (uint8_t) 6;
case hash("g-1"): case hash("G-1"): return (uint8_t) 7;
case hash("g#-1"): case hash("G#-1"): return (uint8_t) 8;
case hash("a-1"): case hash("A-1"): return (uint8_t) 9;
case hash("a#-1"): case hash("A#-1"): return (uint8_t) 10;
case hash("b-1"): case hash("B-1"): return (uint8_t) 11;
case hash("c0"): case hash("C0"): return (uint8_t) 12;
case hash("c#0"): case hash("C#0"): return (uint8_t) 13;
case hash("d0"): case hash("D0"): return (uint8_t) 14;
case hash("d#0"): case hash("D#0"): return (uint8_t) 15;
case hash("e0"): case hash("E0"): return (uint8_t) 16;
case hash("f0"): case hash("F0"): return (uint8_t) 17;
case hash("f#0"): case hash("F#0"): return (uint8_t) 18;
case hash("g0"): case hash("G0"): return (uint8_t) 19;
case hash("g#0"): case hash("G#0"): return (uint8_t) 20;
case hash("a0"): case hash("A0"): return (uint8_t) 21;
case hash("a#0"): case hash("A#0"): return (uint8_t) 22;
case hash("b0"): case hash("B0"): return (uint8_t) 23;
case hash("c1"): case hash("C1"): return (uint8_t) 24;
case hash("c#1"): case hash("C#1"): return (uint8_t) 25;
case hash("d1"): case hash("D1"): return (uint8_t) 26;
case hash("d#1"): case hash("D#1"): return (uint8_t) 27;
case hash("e1"): case hash("E1"): return (uint8_t) 28;
case hash("f1"): case hash("F1"): return (uint8_t) 29;
case hash("f#1"): case hash("F#1"): return (uint8_t) 30;
case hash("g1"): case hash("G1"): return (uint8_t) 31;
case hash("g#1"): case hash("G#1"): return (uint8_t) 32;
case hash("a1"): case hash("A1"): return (uint8_t) 33;
case hash("a#1"): case hash("A#1"): return (uint8_t) 34;
case hash("b1"): case hash("B1"): return (uint8_t) 35;
case hash("c2"): case hash("C2"): return (uint8_t) 36;
case hash("c#2"): case hash("C#2"): return (uint8_t) 37;
case hash("d2"): case hash("D2"): return (uint8_t) 38;
case hash("d#2"): case hash("D#2"): return (uint8_t) 39;
case hash("e2"): case hash("E2"): return (uint8_t) 40;
case hash("f2"): case hash("F2"): return (uint8_t) 41;
case hash("f#2"): case hash("F#2"): return (uint8_t) 42;
case hash("g2"): case hash("G2"): return (uint8_t) 43;
case hash("g#2"): case hash("G#2"): return (uint8_t) 44;
case hash("a2"): case hash("A2"): return (uint8_t) 45;
case hash("a#2"): case hash("A#2"): return (uint8_t) 46;
case hash("b2"): case hash("B2"): return (uint8_t) 47;
case hash("c3"): case hash("C3"): return (uint8_t) 48;
case hash("c#3"): case hash("C#3"): return (uint8_t) 49;
case hash("d3"): case hash("D3"): return (uint8_t) 50;
case hash("d#3"): case hash("D#3"): return (uint8_t) 51;
case hash("e3"): case hash("E3"): return (uint8_t) 52;
case hash("f3"): case hash("F3"): return (uint8_t) 53;
case hash("f#3"): case hash("F#3"): return (uint8_t) 54;
case hash("g3"): case hash("G3"): return (uint8_t) 55;
case hash("g#3"): case hash("G#3"): return (uint8_t) 56;
case hash("a3"): case hash("A3"): return (uint8_t) 57;
case hash("a#3"): case hash("A#3"): return (uint8_t) 58;
case hash("b3"): case hash("B3"): return (uint8_t) 59;
case hash("c4"): case hash("C4"): return (uint8_t) 60;
case hash("c#4"): case hash("C#4"): return (uint8_t) 61;
case hash("d4"): case hash("D4"): return (uint8_t) 62;
case hash("d#4"): case hash("D#4"): return (uint8_t) 63;
case hash("e4"): case hash("E4"): return (uint8_t) 64;
case hash("f4"): case hash("F4"): return (uint8_t) 65;
case hash("f#4"): case hash("F#4"): return (uint8_t) 66;
case hash("g4"): case hash("G4"): return (uint8_t) 67;
case hash("g#4"): case hash("G#4"): return (uint8_t) 68;
case hash("a4"): case hash("A4"): return (uint8_t) 69;
case hash("a#4"): case hash("A#4"): return (uint8_t) 70;
case hash("b4"): case hash("B4"): return (uint8_t) 71;
case hash("c5"): case hash("C5"): return (uint8_t) 72;
case hash("c#5"): case hash("C#5"): return (uint8_t) 73;
case hash("d5"): case hash("D5"): return (uint8_t) 74;
case hash("d#5"): case hash("D#5"): return (uint8_t) 75;
case hash("e5"): case hash("E5"): return (uint8_t) 76;
case hash("f5"): case hash("F5"): return (uint8_t) 77;
case hash("f#5"): case hash("F#5"): return (uint8_t) 78;
case hash("g5"): case hash("G5"): return (uint8_t) 79;
case hash("g#5"): case hash("G#5"): return (uint8_t) 80;
case hash("a5"): case hash("A5"): return (uint8_t) 81;
case hash("a#5"): case hash("A#5"): return (uint8_t) 82;
case hash("b5"): case hash("B5"): return (uint8_t) 83;
case hash("c6"): case hash("C6"): return (uint8_t) 84;
case hash("c#6"): case hash("C#6"): return (uint8_t) 85;
case hash("d6"): case hash("D6"): return (uint8_t) 86;
case hash("d#6"): case hash("D#6"): return (uint8_t) 87;
case hash("e6"): case hash("E6"): return (uint8_t) 88;
case hash("f6"): case hash("F6"): return (uint8_t) 89;
case hash("f#6"): case hash("F#6"): return (uint8_t) 90;
case hash("g6"): case hash("G6"): return (uint8_t) 91;
case hash("g#6"): case hash("G#6"): return (uint8_t) 92;
case hash("a6"): case hash("A6"): return (uint8_t) 93;
case hash("a#6"): case hash("A#6"): return (uint8_t) 94;
case hash("b6"): case hash("B6"): return (uint8_t) 95;
case hash("c7"): case hash("C7"): return (uint8_t) 96;
case hash("c#7"): case hash("C#7"): return (uint8_t) 97;
case hash("d7"): case hash("D7"): return (uint8_t) 98;
case hash("d#7"): case hash("D#7"): return (uint8_t) 99;
case hash("e7"): case hash("E7"): return (uint8_t) 100;
case hash("f7"): case hash("F7"): return (uint8_t) 101;
case hash("f#7"): case hash("F#7"): return (uint8_t) 102;
case hash("g7"): case hash("G7"): return (uint8_t) 103;
case hash("g#7"): case hash("G#7"): return (uint8_t) 104;
case hash("a7"): case hash("A7"): return (uint8_t) 105;
case hash("a#7"): case hash("A#7"): return (uint8_t) 106;
case hash("b7"): case hash("B7"): return (uint8_t) 107;
case hash("c8"): case hash("C8"): return (uint8_t) 108;
case hash("c#8"): case hash("C#8"): return (uint8_t) 109;
case hash("d8"): case hash("D8"): return (uint8_t) 110;
case hash("d#8"): case hash("D#8"): return (uint8_t) 111;
case hash("e8"): case hash("E8"): return (uint8_t) 112;
case hash("f8"): case hash("F8"): return (uint8_t) 113;
case hash("f#8"): case hash("F#8"): return (uint8_t) 114;
case hash("g8"): case hash("G8"): return (uint8_t) 115;
case hash("g#8"): case hash("G#8"): return (uint8_t) 116;
case hash("a8"): case hash("A8"): return (uint8_t) 117;
case hash("a#8"): case hash("A#8"): return (uint8_t) 118;
case hash("b8"): case hash("B8"): return (uint8_t) 119;
case hash("c9"): case hash("C9"): return (uint8_t) 120;
case hash("c#9"): case hash("C#9"): return (uint8_t) 121;
case hash("d9"): case hash("D9"): return (uint8_t) 122;
case hash("d#9"): case hash("D#9"): return (uint8_t) 123;
case hash("e9"): case hash("E9"): return (uint8_t) 124;
case hash("f9"): case hash("F9"): return (uint8_t) 125;
case hash("f#9"): case hash("F#9"): return (uint8_t) 126;
case hash("g9"): case hash("G9"): return (uint8_t) 127;
default: return {};
}
}

View file

@ -26,7 +26,6 @@
#include <string>
#include <array>
#include <cmath>
#include "Helpers.h"
namespace sfz
{
@ -63,5 +62,6 @@ inline float ccSwitchedValue(const CCValueArray& ccValues, const std::optional<C
}
std::optional<uint8_t> readNoteValue(const std::string_view& value);
} // namespace sfz

View file

@ -24,7 +24,8 @@
#pragma once
#include "Buffer.h"
#include "Globals.h"
#include "Helpers.h"
#include "Debug.h"
#include "LeakDetector.h"
#include "SIMDHelpers.h"
#include <array>
#include <iostream>

View file

@ -22,7 +22,7 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include "Helpers.h"
#include "LeakDetector.h"
#include "SIMDHelpers.h"
#include "StereoBuffer.h"
#include <absl/types/span.h>

View file

@ -0,0 +1,63 @@
// Copyright (c) 2019, Paul Ferrand
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <string_view>
inline void trimInPlace(std::string_view& s)
{
const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v");
if (leftPosition != s.npos) {
s.remove_prefix(leftPosition);
const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v");
s.remove_suffix(s.size() - rightPosition - 1);
} else {
s.remove_suffix(s.size());
}
}
inline std::string_view trim(std::string_view s)
{
const auto leftPosition = s.find_first_not_of(" \r\t\n\f\v");
if (leftPosition != s.npos) {
s.remove_prefix(leftPosition);
const auto rightPosition = s.find_last_not_of(" \r\t\n\f\v");
s.remove_suffix(s.size() - rightPosition - 1);
} else {
s.remove_suffix(s.size());
}
return s;
}
inline constexpr uint64_t Fnv1aBasis = 0x811C9DC5;
inline constexpr uint64_t Fnv1aPrime = 0x01000193;
inline constexpr uint64_t hash(std::string_view s, uint64_t h = Fnv1aBasis)
{
if (s.length() > 0)
return hash( { s.data() + 1, s.length() - 1 }, (h ^ s.front()) * Fnv1aPrime );
return h;
}

View file

@ -22,7 +22,9 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Synth.h"
#include "Helpers.h"
#include "ScopedFTZ.h"
#include "Debug.h"
#include "StringViewHelpers.h"
#include "absl/algorithm/container.h"
#include <algorithm>
#include <iostream>

View file

@ -25,18 +25,14 @@
#include "FilePool.h"
#include "Parser.h"
#include "Region.h"
#include "SfzHelpers.h"
#include "Helpers.h"
#include "LeakDetector.h"
#include "StereoSpan.h"
#include "absl/types/span.h"
#include <chrono>
#include <optional>
#include <random>
#include <set>
#include <string_view>
#include <thread>
#include <vector>
using namespace std::literals;
namespace sfz {
@ -99,8 +95,7 @@ private:
StereoBuffer<float> tempBuffer { config::defaultSamplesPerBlock };
int samplesPerBlock { config::defaultSamplesPerBlock };
float sampleRate { config::defaultSampleRate };
std::random_device rd {};
std::mt19937 randomGenerator { rd() };
std::uniform_real_distribution<float> randNoteDistribution { 0, 1 };
LEAK_DETECTOR(Synth);

View file

@ -21,6 +21,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Voice.h"
#include "Voice.h"
#include "SIMDHelpers.h"
#include "SfzHelpers.h"

View file

@ -27,6 +27,7 @@
#include "Region.h"
#include "StereoBuffer.h"
#include "StereoSpan.h"
#include "LeakDetector.h"
#include <absl/types/span.h>
#include <atomic>

View file

@ -21,7 +21,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../sources/Helpers.h"
#include "../sources/StringViewHelpers.h"
#include "catch2/catch.hpp"
#include <string_view>
using namespace Catch::literals;