Cosmetics

This commit is contained in:
paulfd 2019-08-25 14:01:03 +02:00
parent 8e8ea4f420
commit 5fd7cab909
37 changed files with 1428 additions and 1527 deletions

View file

@ -1,11 +1,10 @@
#include "Globals.h"
#include "SIMDHelpers.h"
#include "Helpers.h"
#include "ADSREnvelope.h" #include "ADSREnvelope.h"
#include "Globals.h"
#include "Helpers.h"
#include "SIMDHelpers.h"
#include <algorithm> #include <algorithm>
namespace sfz namespace sfz {
{
template <class Type> template <class Type>
void ADSREnvelope<Type>::reset(int attack, int release, Type sustain, int delay, int decay, int hold, Type start, Type depth) noexcept void ADSREnvelope<Type>::reset(int attack, int release, Type sustain, int delay, int decay, int hold, Type start, Type depth) noexcept
@ -35,14 +34,12 @@ void ADSREnvelope<Type>::reset(int attack, int release, Type sustain, int delay,
template <class Type> template <class Type>
Type ADSREnvelope<Type>::getNextValue() noexcept Type ADSREnvelope<Type>::getNextValue() noexcept
{ {
if (shouldRelease && releaseDelay-- == 0) if (shouldRelease && releaseDelay-- == 0) {
{
currentState = State::Release; currentState = State::Release;
step = std::exp((std::log(config::virtuallyZero) - std::log(currentValue)) / (release > 0 ? release : 1)); step = std::exp((std::log(config::virtuallyZero) - std::log(currentValue)) / (release > 0 ? release : 1));
} }
switch(currentState) switch (currentState) {
{
case State::Delay: case State::Delay:
if (delay-- > 0) if (delay-- > 0)
return start; return start;
@ -51,8 +48,7 @@ Type ADSREnvelope<Type>::getNextValue() noexcept
step = (1.0 - currentValue) / (attack > 0 ? attack : 1); step = (1.0 - currentValue) / (attack > 0 ? attack : 1);
[[fallthrough]]; [[fallthrough]];
case State::Attack: case State::Attack:
if (attack-- > 0) if (attack-- > 0) {
{
currentValue += step; currentValue += step;
return currentValue; return currentValue;
} }
@ -68,8 +64,7 @@ Type ADSREnvelope<Type>::getNextValue() noexcept
currentState = State::Decay; currentState = State::Decay;
[[fallthrough]]; [[fallthrough]];
case State::Decay: case State::Decay:
if (decay-- > 0) if (decay-- > 0) {
{
currentValue *= step; currentValue *= step;
return currentValue; return currentValue;
} }
@ -80,8 +75,7 @@ Type ADSREnvelope<Type>::getNextValue() noexcept
case State::Sustain: case State::Sustain:
return currentValue; return currentValue;
case State::Release: case State::Release:
if (release-- > 0) if (release-- > 0) {
{
currentValue *= step; currentValue *= step;
return currentValue; return currentValue;
} }
@ -100,8 +94,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
auto originalSpan = output; auto originalSpan = output;
auto remainingSamples = static_cast<int>(output.size()); auto remainingSamples = static_cast<int>(output.size());
int length; int length;
switch(currentState) switch (currentState) {
{
case State::Delay: case State::Delay:
length = min(remainingSamples, delay); length = min(remainingSamples, delay);
::fill<Type>(output, currentValue); ::fill<Type>(output, currentValue);
@ -171,11 +164,9 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
} }
::fill<Type>(output, currentValue); ::fill<Type>(output, currentValue);
if (shouldRelease) if (shouldRelease) {
{
remainingSamples = static_cast<int>(originalSpan.size()); remainingSamples = static_cast<int>(originalSpan.size());
if (releaseDelay > remainingSamples) if (releaseDelay > remainingSamples) {
{
releaseDelay -= remainingSamples; releaseDelay -= remainingSamples;
return; return;
} }
@ -191,13 +182,11 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
originalSpan.remove_prefix(length); originalSpan.remove_prefix(length);
release -= length; release -= length;
if (release == 0) if (release == 0) {
{
currentValue = 0.0; currentValue = 0.0;
currentState = State::Done; currentState = State::Done;
::fill<Type>(originalSpan, 0.0); ::fill<Type>(originalSpan, 0.0);
} }
} }
} }
template <class Type> template <class Type>

View file

@ -1,12 +1,10 @@
#pragma once #pragma once
#include <absl/types/span.h>
#include "Helpers.h" #include "Helpers.h"
namespace sfz #include <absl/types/span.h>
{ namespace sfz {
template <class Type> template <class Type>
class ADSREnvelope class ADSREnvelope {
{
public: public:
ADSREnvelope() = default; ADSREnvelope() = default;
void reset(int attack, int release, Type sustain = 1.0, int delay = 0, int decay = 0, int hold = 0, Type start = 0.0, Type depth = 1) noexcept; void reset(int attack, int release, Type sustain = 1.0, int delay = 0, int decay = 0, int hold = 0, Type start = 0.0, Type depth = 1) noexcept;
@ -14,10 +12,16 @@ public:
void getBlock(absl::Span<Type> output) noexcept; void getBlock(absl::Span<Type> output) noexcept;
void startRelease(int releaseDelay) noexcept; void startRelease(int releaseDelay) noexcept;
bool isSmoothing() noexcept; bool isSmoothing() noexcept;
private: private:
enum class State enum class State {
{ Delay,
Delay, Attack, Hold, Decay, Sustain, Release, Done Attack,
Hold,
Decay,
Sustain,
Release,
Done
}; };
State currentState { State::Done }; State currentState { State::Done };
Type currentValue { 0.0 }; Type currentValue { 0.0 };

View file

@ -7,8 +7,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
template <class Type, unsigned int Alignment = SIMDConfig::defaultAlignment> template <class Type, unsigned int Alignment = SIMDConfig::defaultAlignment>
class Buffer class Buffer {
{
public: public:
using value_type = std::remove_cv_t<Type>; using value_type = std::remove_cv_t<Type>;
using pointer = value_type*; using pointer = value_type*;
@ -31,16 +30,14 @@ public:
} }
bool resize(size_t newSize) bool resize(size_t newSize)
{ {
if (newSize == 0) if (newSize == 0) {
{
clear(); clear();
return true; return true;
} }
auto tempSize = newSize + 2 * AlignmentMask; // To ensure that we have leeway at the beginning and at the end auto tempSize = newSize + 2 * AlignmentMask; // To ensure that we have leeway at the beginning and at the end
auto* newData = paddedData != nullptr ? std::realloc(paddedData, tempSize * sizeof(value_type)) : std::malloc(tempSize * sizeof(value_type)); auto* newData = paddedData != nullptr ? std::realloc(paddedData, tempSize * sizeof(value_type)) : std::malloc(tempSize * sizeof(value_type));
if (newData == nullptr) if (newData == nullptr) {
{
return false; return false;
} }
@ -73,8 +70,7 @@ public:
Buffer(const Buffer<Type>& other) Buffer(const Buffer<Type>& other)
{ {
if (resize(other.size())) if (resize(other.size())) {
{
std::memcpy(this->data(), other.data(), other.size() * sizeof(value_type)); std::memcpy(this->data(), other.data(), other.size() * sizeof(value_type));
} }
} }
@ -91,8 +87,7 @@ public:
Buffer<Type>& operator=(const Buffer<Type>& other) Buffer<Type>& operator=(const Buffer<Type>& other)
{ {
if (this != &other) if (this != &other) {
{
if (resize(other.size())) if (resize(other.size()))
std::memcpy(this->data(), other.data(), other.size() * sizeof(value_type)); std::memcpy(this->data(), other.data(), other.size() * sizeof(value_type));
} }
@ -101,8 +96,7 @@ public:
Buffer<Type>& operator=(Buffer<Type>&& other) Buffer<Type>& operator=(Buffer<Type>&& other)
{ {
if (this != &other) if (this != &other) {
{
std::free(paddedData); std::free(paddedData);
largerSize = std::exchange(other.largerSize, 0); largerSize = std::exchange(other.largerSize, 0);
alignedSize = std::exchange(other.alignedSize, 0); alignedSize = std::exchange(other.alignedSize, 0);

View file

@ -1,15 +1,16 @@
#pragma once #pragma once
#include <map>
#include "Helpers.h" #include "Helpers.h"
#include <map>
namespace sfz namespace sfz {
{
template <class ValueType> template <class ValueType>
class CCMap class CCMap {
{
public: public:
CCMap() = delete; CCMap() = delete;
CCMap(const ValueType& defaultValue) : defaultValue(defaultValue) { } CCMap(const ValueType& defaultValue)
: defaultValue(defaultValue)
{
}
CCMap(CCMap&&) = default; CCMap(CCMap&&) = default;
CCMap(const CCMap&) = default; CCMap(const CCMap&) = default;
~CCMap() = default; ~CCMap() = default;
@ -17,12 +18,9 @@ public:
const ValueType& getWithDefault(int index) const noexcept const ValueType& getWithDefault(int index) const noexcept
{ {
auto it = container.find(index); auto it = container.find(index);
if (it == end(container)) if (it == end(container)) {
{
return defaultValue; return defaultValue;
} } else {
else
{
return it->second; return it->second;
} }
} }

View file

@ -1,25 +1,22 @@
#pragma once #pragma once
#include "StereoBuffer.h"
#include "Defaults.h" #include "Defaults.h"
#include "StereoBuffer.h"
#include "Voice.h" #include "Voice.h"
#include <sndfile.hh>
#include <filesystem>
#include <optional>
#include <string_view>
#include <absl/container/flat_hash_map.h>
#include <map>
#include "readerwriterqueue.h" #include "readerwriterqueue.h"
#include <absl/container/flat_hash_map.h>
#include <filesystem>
#include <map>
#include <optional>
#include <sndfile.hh>
#include <string_view>
#include <thread> #include <thread>
namespace sfz namespace sfz {
{ class FilePool {
class FilePool
{
public: public:
FilePool() FilePool()
: fileLoadingThread(std::thread(&FilePool::loadingThread, this)) : fileLoadingThread(std::thread(&FilePool::loadingThread, this))
{ {
} }
~FilePool() ~FilePool()
@ -30,8 +27,7 @@ public:
void setRootDirectory(const std::filesystem::path& directory) { rootDirectory = directory; } void setRootDirectory(const std::filesystem::path& directory) { rootDirectory = directory; }
size_t getNumPreloadedSamples() { return preloadedData.size(); } size_t getNumPreloadedSamples() { return preloadedData.size(); }
struct FileInformation struct FileInformation {
{
uint32_t end { Default::sampleEndRange.getEnd() }; uint32_t end { Default::sampleEndRange.getEnd() };
uint32_t loopBegin { Default::loopRange.getStart() }; uint32_t loopBegin { Default::loopRange.getStart() };
uint32_t loopEnd { Default::loopRange.getEnd() }; uint32_t loopEnd { Default::loopRange.getEnd() };
@ -40,7 +36,8 @@ public:
}; };
std::optional<FileInformation> getFileInformation(std::string_view filename); std::optional<FileInformation> getFileInformation(std::string_view filename);
void enqueueLoading(Voice* voice, std::string_view sample, int numFrames); void enqueueLoading(Voice* voice, std::string_view sample, int numFrames);
static void deleteAndTrackBuffers(StereoBuffer<float>* buffer) { static void deleteAndTrackBuffers(StereoBuffer<float>* buffer)
{
fileBuffers--; fileBuffers--;
delete buffer; delete buffer;
}; };
@ -48,10 +45,10 @@ public:
{ {
return fileBuffers.load(); return fileBuffers.load();
} }
private: private:
std::filesystem::path rootDirectory; std::filesystem::path rootDirectory;
struct FileLoadingInformation struct FileLoadingInformation {
{
Voice* voice; Voice* voice;
std::string_view sample; std::string_view sample;
int numFrames; int numFrames;

View file

@ -1,10 +1,8 @@
#pragma once #pragma once
namespace sfz namespace sfz {
{
namespace config namespace config {
{
constexpr float defaultSampleRate { 48000 }; constexpr float defaultSampleRate { 48000 };
constexpr int defaultSamplesPerBlock { 1024 }; constexpr int defaultSamplesPerBlock { 1024 };
constexpr int preloadSize { 8192 }; constexpr int preloadSize { 8192 };
@ -21,8 +19,7 @@ namespace config
} // namespace sfz } // namespace sfz
namespace SIMDConfig namespace SIMDConfig {
{
constexpr unsigned int defaultAlignment { 16 }; constexpr unsigned int defaultAlignment { 16 };
constexpr bool writeInterleaved { true }; constexpr bool writeInterleaved { true };
constexpr bool readInterleaved { true }; constexpr bool readInterleaved { true };

View file

@ -6,14 +6,11 @@
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());
} }
} }
@ -21,14 +18,11 @@ 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;
@ -112,8 +106,7 @@ 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 } // namespace Random
@ -132,8 +125,7 @@ constexpr Type piTwo{pi<Type> / 2};
#include <atomic> #include <atomic>
template <class Owner> template <class Owner>
class LeakDetector class LeakDetector {
{
public: public:
LeakDetector() LeakDetector()
{ {
@ -146,8 +138,7 @@ public:
~LeakDetector() ~LeakDetector()
{ {
objectCounter.count--; objectCounter.count--;
if (objectCounter.count.load() < 0) 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;
@ -155,13 +146,11 @@ public:
} }
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;

View file

@ -3,8 +3,7 @@
#include "SIMDHelpers.h" #include "SIMDHelpers.h"
#include <absl/algorithm/container.h> #include <absl/algorithm/container.h>
namespace sfz namespace sfz {
{
template <class Type> template <class Type>
LinearEnvelope<Type>::LinearEnvelope() LinearEnvelope<Type>::LinearEnvelope()
@ -60,11 +59,9 @@ void LinearEnvelope<Type>::getBlock(absl::Span<Type> output)
}); });
int index { 0 }; int index { 0 };
for (auto& event: events) for (auto& event : events) {
{
const auto length = min(event.first, static_cast<int>(output.size())) - index; const auto length = min(event.first, static_cast<int>(output.size())) - index;
if (length == 0) if (length == 0) {
{
currentValue = event.second; currentValue = event.second;
continue; continue;
} }

View file

@ -1,16 +1,14 @@
#pragma once #pragma once
#include "Globals.h" #include "Globals.h"
#include "Helpers.h" #include "Helpers.h"
#include <type_traits>
#include <functional>
#include <absl/types/span.h> #include <absl/types/span.h>
#include <functional>
#include <type_traits>
namespace sfz namespace sfz {
{
template <class Type> template <class Type>
class LinearEnvelope class LinearEnvelope {
{
public: public:
LinearEnvelope(); LinearEnvelope();
LinearEnvelope(int maxCapacity, std::function<Type(Type)> function); LinearEnvelope(int maxCapacity, std::function<Type(Type)> function);
@ -20,6 +18,7 @@ public:
void clear(); void clear();
void reset(Type value = 0.0); void reset(Type value = 0.0);
void getBlock(absl::Span<Type> output); void getBlock(absl::Span<Type> output);
private: private:
std::function<Type(Type)> function { [](Type input) { return input; } }; std::function<Type(Type)> function { [](Type input) { return input; } };
static_assert(std::is_arithmetic<Type>::value); static_assert(std::is_arithmetic<Type>::value);

View file

@ -1,11 +1,10 @@
#pragma once #pragma once
#include "Globals.h" #include "Globals.h"
#include <cmath>
#include <absl/types/span.h> #include <absl/types/span.h>
#include <cmath>
template <class Type = float> template <class Type = float>
class OnePoleFilter class OnePoleFilter {
{
public: public:
OnePoleFilter() = default; OnePoleFilter() = default;
// Normalized cutoff with respect to the sampling rate // Normalized cutoff with respect to the sampling rate
@ -31,8 +30,7 @@ public:
int processLowpass(absl::Span<const Type> input, absl::Span<Type> lowpass) int processLowpass(absl::Span<const Type> input, absl::Span<Type> lowpass)
{ {
for (auto [in, out] = std::pair(input.begin(), lowpass.begin()); for (auto [in, out] = std::pair(input.begin(), lowpass.begin());
in < input.end() && out < lowpass.end(); in++, out++) in < input.end() && out < lowpass.end(); in++, out++) {
{
oneLowpass(in, out); oneLowpass(in, out);
} }
return std::min(input.size(), lowpass.size()); return std::min(input.size(), lowpass.size());
@ -41,8 +39,7 @@ public:
int processHighpass(absl::Span<const Type> input, absl::Span<Type> highpass) int processHighpass(absl::Span<const Type> input, absl::Span<Type> highpass)
{ {
for (auto [in, out] = std::pair(input.begin(), highpass.begin()); for (auto [in, out] = std::pair(input.begin(), highpass.begin());
in < input.end() && out < highpass.end(); in++, out++) in < input.end() && out < highpass.end(); in++, out++) {
{
oneHighpass(in, out); oneHighpass(in, out);
} }
return std::min(input.size(), highpass.size()); return std::min(input.size(), highpass.size());
@ -51,8 +48,7 @@ public:
int processLowpassVariableGain(absl::Span<const Type> input, absl::Span<Type> lowpass, absl::Span<const Type> gain) int processLowpassVariableGain(absl::Span<const Type> input, absl::Span<Type> lowpass, absl::Span<const Type> gain)
{ {
for (auto [in, out, g] = std::tuple(input.begin(), lowpass.begin(), gain.begin()); for (auto [in, out, g] = std::tuple(input.begin(), lowpass.begin(), gain.begin());
in < input.end() && out < lowpass.end() && g < gain.end(); in++, out++, g++) in < input.end() && out < lowpass.end() && g < gain.end(); in++, out++, g++) {
{
setGain(*g); setGain(*g);
oneLowpass(in, out); oneLowpass(in, out);
} }
@ -63,8 +59,7 @@ public:
int processHighpassVariableGain(absl::Span<const Type> input, absl::Span<Type> highpass, absl::Span<const Type> gain) int processHighpassVariableGain(absl::Span<const Type> input, absl::Span<Type> highpass, absl::Span<const Type> gain)
{ {
for (auto [in, out, g] = std::tuple(input.begin(), highpass.begin(), gain.begin()); for (auto [in, out, g] = std::tuple(input.begin(), highpass.begin(), gain.begin());
in < input.end() && out < highpass.end() && g < gain.end(); in++, out++, g++) in < input.end() && out < highpass.end() && g < gain.end(); in++, out++, g++) {
{
setGain(*g); setGain(*g);
oneHighpass(in, out); oneHighpass(in, out);
} }
@ -73,6 +68,7 @@ public:
} }
void reset() { state = 0.0; } void reset() { state = 0.0; }
private: private:
Type state { 0.0 }; Type state { 0.0 };
Type gain { 0.25 }; Type gain { 0.25 };

View file

@ -1,15 +1,14 @@
#include "Opcode.h" #include "Opcode.h"
sfz::Opcode::Opcode(std::string_view inputOpcode, std::string_view inputValue) sfz::Opcode::Opcode(std::string_view inputOpcode, std::string_view inputValue)
:opcode(inputOpcode), value(inputValue) : opcode(inputOpcode)
{ , value(inputValue)
if (const auto lastCharIndex = inputOpcode.find_last_not_of("1234567890"); lastCharIndex != inputOpcode.npos)
{ {
if (const auto lastCharIndex = inputOpcode.find_last_not_of("1234567890"); lastCharIndex != inputOpcode.npos) {
int returnedValue; int returnedValue;
std::string_view parameterView = inputOpcode; std::string_view parameterView = inputOpcode;
parameterView.remove_prefix(lastCharIndex + 1); parameterView.remove_prefix(lastCharIndex + 1);
if (absl::SimpleAtoi(parameterView, &returnedValue)) if (absl::SimpleAtoi(parameterView, &returnedValue)) {
{
parameter = returnedValue; parameter = returnedValue;
opcode.remove_suffix(opcode.size() - lastCharIndex - 1); opcode.remove_suffix(opcode.size() - lastCharIndex - 1);
} }

View file

@ -1,18 +1,16 @@
#pragma once #pragma once
#include "Helpers.h"
#include "SfzHelpers.h"
#include "Defaults.h" #include "Defaults.h"
#include "Helpers.h"
#include "Range.h" #include "Range.h"
#include <string_view> #include "SfzHelpers.h"
#include <optional> #include <optional>
#include <string_view>
// charconv support is still sketchy with clang/gcc so we use abseil's numbers // charconv support is still sketchy with clang/gcc so we use abseil's numbers
#include "absl/strings/numbers.h" #include "absl/strings/numbers.h"
namespace sfz namespace sfz {
{ struct Opcode {
struct Opcode
{
Opcode() = delete; Opcode() = delete;
Opcode(std::string_view inputOpcode, std::string_view inputValue); Opcode(std::string_view inputOpcode, std::string_view inputValue);
std::string_view opcode {}; std::string_view opcode {};
@ -25,8 +23,7 @@ struct Opcode
template <class ValueType> template <class ValueType>
inline std::optional<ValueType> readOpcode(std::string_view value, const Range<ValueType>& validRange) inline std::optional<ValueType> readOpcode(std::string_view value, const Range<ValueType>& validRange)
{ {
if constexpr(std::is_integral<ValueType>::value) if constexpr (std::is_integral<ValueType>::value) {
{
int64_t returnedValue; int64_t returnedValue;
if (!absl::SimpleAtoi(value, &returnedValue)) if (!absl::SimpleAtoi(value, &returnedValue))
return {}; return {};
@ -37,9 +34,7 @@ inline std::optional<ValueType> readOpcode(std::string_view value, const Range<V
returnedValue = std::numeric_limits<ValueType>::min(); returnedValue = std::numeric_limits<ValueType>::min();
return validRange.clamp(static_cast<ValueType>(returnedValue)); return validRange.clamp(static_cast<ValueType>(returnedValue));
} } else {
else
{
float returnedValue; float returnedValue;
if (!absl::SimpleAtof(value, &returnedValue)) if (!absl::SimpleAtof(value, &returnedValue))
return std::nullopt; return std::nullopt;

View file

@ -1,9 +1,9 @@
#include "Parser.h" #include "Parser.h"
#include "Helpers.h"
#include "Globals.h" #include "Globals.h"
#include "Helpers.h"
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include <fstream>
#include <algorithm> #include <algorithm>
#include <fstream>
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>;
@ -32,8 +32,7 @@ bool sfz::Parser::loadSfzFile(const std::filesystem::path &file)
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
@ -42,8 +41,7 @@ bool sfz::Parser::loadSfzFile(const std::filesystem::path &file)
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) {
{
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());
@ -67,8 +65,7 @@ void sfz::Parser::readSfzFile(const std::filesystem::path &fileName, std::vector
svmatch_results defineMatch; svmatch_results defineMatch;
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);
@ -78,21 +75,16 @@ void sfz::Parser::readSfzFile(const std::filesystem::path &fileName, std::vector
continue; continue;
// New #include // New #include
if (std::regex_search(tmpView.begin(), tmpView.end(), includeMatch, sfz::Regexes::includes)) if (std::regex_search(tmpView.begin(), tmpView.end(), includeMatch, sfz::Regexes::includes)) {
{
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)) {
{ if (alreadyIncluded == includedFiles.end()) {
if (alreadyIncluded == includedFiles.end())
{
includedFiles.push_back(newFile); includedFiles.push_back(newFile);
readSfzFile(newFile, lines); readSfzFile(newFile, lines);
} } else if (!recursiveIncludeGuard) {
else if (!recursiveIncludeGuard)
{
readSfzFile(newFile, lines); readSfzFile(newFile, lines);
} }
} }
@ -100,8 +92,7 @@ void sfz::Parser::readSfzFile(const std::filesystem::path &fileName, std::vector
} }
// New #define // New #define
if (std::regex_search(tmpView.begin(), tmpView.end(), defineMatch, sfz::Regexes::defines)) if (std::regex_search(tmpView.begin(), tmpView.end(), defineMatch, sfz::Regexes::defines)) {
{
defines[defineMatch.str(1)] = defineMatch.str(2); defines[defineMatch.str(1)] = defineMatch.str(2);
continue; continue;
} }
@ -112,23 +103,19 @@ void sfz::Parser::readSfzFile(const std::filesystem::path &fileName, std::vector
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) {
{
newString += definePair.second; newString += definePair.second;
lastPos = findPos + definePair.first.length(); lastPos = findPos + definePair.first.length();
break; break;
} }
} }
if (lastPos <= findPos) if (lastPos <= findPos) {
{
newString += sfz::config::defineCharacter; newString += sfz::config::defineCharacter;
lastPos = findPos + 1; lastPos = findPos + 1;
} }

View file

@ -1,16 +1,14 @@
#pragma once #pragma once
#include "Opcode.h" #include "Opcode.h"
#include <filesystem> #include <filesystem>
#include <regex>
#include <map> #include <map>
#include <regex>
#include <string> #include <string>
#include <vector>
#include <string_view> #include <string_view>
#include <vector>
namespace sfz namespace sfz {
{ namespace Regexes {
namespace Regexes
{
inline static std::regex includes { R"V(#include\s*"(.*?)".*$)V", std::regex::optimize }; inline static std::regex includes { R"V(#include\s*"(.*?)".*$)V", std::regex::optimize };
inline static std::regex defines { R"(#define\s*(\$[a-zA-Z0-9]+)\s+([a-zA-Z0-9]+)(?=\s|$))", std::regex::optimize }; inline static std::regex defines { R"(#define\s*(\$[a-zA-Z0-9]+)\s+([a-zA-Z0-9]+)(?=\s|$))", std::regex::optimize };
inline static std::regex headers { R"(<(.*?)>(.*?)(?=<|$))", std::regex::optimize }; inline static std::regex headers { R"(<(.*?)>(.*?)(?=<|$))", std::regex::optimize };
@ -18,17 +16,18 @@ namespace Regexes
inline static std::regex opcodeParameters { R"(([a-zA-Z0-9_]+?)([0-9]+)$)", std::regex::optimize }; inline static std::regex opcodeParameters { R"(([a-zA-Z0-9_]+?)([0-9]+)$)", std::regex::optimize };
} }
class Parser class Parser {
{
public: public:
virtual bool loadSfzFile(const std::filesystem::path& file); virtual bool loadSfzFile(const std::filesystem::path& file);
const std::map<std::string, std::string>& getDefines() const noexcept { return defines; } const std::map<std::string, std::string>& getDefines() const noexcept { return defines; }
const std::vector<std::filesystem::path>& getIncludedFiles() const noexcept { return includedFiles; } const std::vector<std::filesystem::path>& getIncludedFiles() const noexcept { return includedFiles; }
void disableRecursiveIncludeGuard() { recursiveIncludeGuard = false; } void disableRecursiveIncludeGuard() { recursiveIncludeGuard = false; }
void enableRecursiveIncludeGuard() { recursiveIncludeGuard = true; } void enableRecursiveIncludeGuard() { recursiveIncludeGuard = true; }
protected: protected:
virtual void callback(std::string_view header, const std::vector<Opcode>& members) = 0; virtual void callback(std::string_view header, const std::vector<Opcode>& members) = 0;
std::filesystem::path rootDirectory { std::filesystem::current_path() }; std::filesystem::path rootDirectory { std::filesystem::current_path() };
private: private:
bool recursiveIncludeGuard { false }; bool recursiveIncludeGuard { false };
std::map<std::string, std::string> defines; std::map<std::string, std::string> defines;

View file

@ -1,12 +1,12 @@
#pragma once #pragma once
#include <type_traits>
#include <initializer_list>
#include <algorithm> #include <algorithm>
#include <initializer_list>
#include <type_traits>
template <class Type> template <class Type>
class Range class Range {
{
static_assert(std::is_arithmetic<Type>::value, "The Type should be arithmetic"); static_assert(std::is_arithmetic<Type>::value, "The Type should be arithmetic");
public: public:
constexpr Range() = default; constexpr Range() = default;
// constexpr Range(std::initializer_list<Type> list) // constexpr Range(std::initializer_list<Type> list)
@ -25,7 +25,10 @@ public:
// } // }
// } // }
constexpr Range(Type start, Type end) noexcept constexpr Range(Type start, Type end) noexcept
: _start(start), _end(std::max(start, end)) {} : _start(start)
, _end(std::max(start, end))
{
}
~Range() = default; ~Range() = default;
Type getStart() const noexcept { return _start; } Type getStart() const noexcept { return _start; }
Type getEnd() const noexcept { return _end; } Type getEnd() const noexcept { return _end; }
@ -59,6 +62,7 @@ public:
if (end < _end) if (end < _end)
_end = end; _end = end;
} }
private: private:
Type _start { static_cast<Type>(0.0) }; Type _start { static_cast<Type>(0.0) };
Type _end { static_cast<Type>(0.0) }; Type _end { static_cast<Type>(0.0) };

View file

@ -6,8 +6,7 @@
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), { { "\\", "/" } });
@ -34,8 +33,7 @@ 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;
@ -70,8 +68,7 @@ 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;
@ -115,8 +112,7 @@ 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;
@ -146,8 +142,7 @@ 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;
@ -186,8 +181,7 @@ 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;
@ -263,8 +257,7 @@ 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);
} }
@ -294,8 +287,7 @@ 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;
@ -307,8 +299,7 @@ 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;
@ -423,10 +414,8 @@ 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
@ -441,8 +430,7 @@ 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++;
@ -457,8 +445,7 @@ 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
@ -487,8 +474,7 @@ bool sfz::Region::registerNoteOff(int channel, int noteNumber, uint8_t velocity[
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

@ -1,21 +1,19 @@
#pragma once #pragma once
#include "Helpers.h"
#include <bits/stdint-uintn.h>
#include <optional>
#include <vector>
#include <string>
#include "Opcode.h"
#include "EGDescription.h"
#include "StereoBuffer.h"
#include "Defaults.h"
#include "CCMap.h" #include "CCMap.h"
#include "Defaults.h"
#include "EGDescription.h"
#include "Helpers.h"
#include "Opcode.h"
#include "StereoBuffer.h"
#include <bits/stdint-uintn.h>
#include <bitset> #include <bitset>
#include <optional>
#include <random> #include <random>
#include <string>
#include <vector>
namespace sfz namespace sfz {
{ struct Region {
struct Region
{
Region() Region()
{ {
ccSwitched.set(); ccSwitched.set();
@ -137,6 +135,7 @@ struct Region
double sampleRate { config::defaultSampleRate }; double sampleRate { config::defaultSampleRate };
int numChannels { 1 }; int numChannels { 1 };
std::shared_ptr<StereoBuffer<float>> preloadedData { nullptr }; std::shared_ptr<StereoBuffer<float>> preloadedData { nullptr };
private: private:
bool keySwitched { true }; bool keySwitched { true };
bool previousKeySwitched { true }; bool previousKeySwitched { true };

View file

@ -1,5 +1,5 @@
#include "SIMDHelpers.h"
#include "Helpers.h" #include "Helpers.h"
#include "SIMDHelpers.h"
template <> template <>
void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept void readInterleaved<float, true>(absl::Span<const float> input, absl::Span<float> outputLeft, absl::Span<float> outputRight) noexcept

View file

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "Globals.h" #include "Globals.h"
#include <absl/types/span.h>
#include <absl/algorithm/container.h>
#include "Helpers.h" #include "Helpers.h"
#include <absl/algorithm/container.h>
#include <absl/types/span.h>
#include <cmath> #include <cmath>
template <class T> template <class T>

View file

@ -1,13 +1,12 @@
#include "Synth.h" #include "Synth.h"
#include "Helpers.h" #include "Helpers.h"
#include <algorithm>
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#include <algorithm>
void sfz::Synth::callback(std::string_view header, const std::vector<Opcode>& members) void sfz::Synth::callback(std::string_view header, const std::vector<Opcode>& members)
{ {
switch (hash(header)) switch (hash(header)) {
{
case hash("global"): case hash("global"):
// We shouldn't have multiple global headers in file // We shouldn't have multiple global headers in file
ASSERT(!hasGlobal); ASSERT(!hasGlobal);
@ -35,7 +34,7 @@ void sfz::Synth::callback(std::string_view header, const std::vector<Opcode>& me
numCurves++; numCurves++;
break; break;
case hash("effect"): case hash("effect"):
// TODO: implement curves // TODO: implement effects
break; break;
default: default:
std::cerr << "Unknown header: " << header << '\n'; std::cerr << "Unknown header: " << header << '\n';
@ -79,8 +78,7 @@ void sfz::Synth::clear()
void sfz::Synth::handleGlobalOpcodes(const std::vector<Opcode>& members) void sfz::Synth::handleGlobalOpcodes(const std::vector<Opcode>& members)
{ {
for (auto& member: members) for (auto& member : members) {
{
if (member.opcode == "sw_default") if (member.opcode == "sw_default")
setValueFromOpcode(member, defaultSwitch, Default::keyRange); setValueFromOpcode(member, defaultSwitch, Default::keyRange);
} }
@ -88,10 +86,8 @@ void sfz::Synth::handleGlobalOpcodes(const std::vector<Opcode>& members)
void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members) void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
{ {
for (auto& member: members) for (auto& member : members) {
{ switch (hash(member.opcode)) {
switch (hash(member.opcode))
{
case hash("set_cc"): case hash("set_cc"):
if (member.parameter && Default::ccRange.containsWithEnd(*member.parameter)) if (member.parameter && Default::ccRange.containsWithEnd(*member.parameter))
setValueFromOpcode(member, ccState[*member.parameter], Default::ccRange); setValueFromOpcode(member, ccState[*member.parameter], Default::ccRange);
@ -125,19 +121,16 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
auto lastRegion = regions.end() - 1; auto lastRegion = regions.end() - 1;
auto currentRegion = regions.begin(); auto currentRegion = regions.begin();
while (currentRegion <= lastRegion) while (currentRegion <= lastRegion) {
{
auto region = currentRegion->get(); auto region = currentRegion->get();
if (region->isGenerator()) if (region->isGenerator()) {
{
currentRegion++; currentRegion++;
continue; continue;
} }
auto fileInformation = filePool.getFileInformation(region->sample); auto fileInformation = filePool.getFileInformation(region->sample);
if (!fileInformation) if (!fileInformation) {
{
DBG("Removing the region with sample " << region->sample); DBG("Removing the region with sample " << region->sample);
std::iter_swap(currentRegion, lastRegion); std::iter_swap(currentRegion, lastRegion);
lastRegion--; lastRegion--;
@ -159,8 +152,7 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
for (int ccIndex = 1; ccIndex < 128; ccIndex++) for (int ccIndex = 1; ccIndex < 128; ccIndex++)
region->registerCC(region->channelRange.getStart(), ccIndex, ccState[ccIndex]); region->registerCC(region->channelRange.getStart(), ccIndex, ccState[ccIndex]);
if (defaultSwitch) if (defaultSwitch) {
{
region->registerNoteOn(region->channelRange.getStart(), *defaultSwitch, 127, 1.0); region->registerNoteOn(region->channelRange.getStart(), *defaultSwitch, 127, 1.0);
region->registerNoteOff(region->channelRange.getStart(), *defaultSwitch, 0, 1.0); region->registerNoteOff(region->channelRange.getStart(), *defaultSwitch, 0, 1.0);
} }

View file

@ -5,13 +5,13 @@
#include "SfzHelpers.h" #include "SfzHelpers.h"
#include "StereoSpan.h" #include "StereoSpan.h"
#include "absl/types/span.h" #include "absl/types/span.h"
#include <chrono>
#include <optional> #include <optional>
#include <random> #include <random>
#include <set> #include <set>
#include <string_view> #include <string_view>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <chrono>
using namespace std::literals; using namespace std::literals;
namespace sfz { namespace sfz {
@ -177,8 +177,7 @@ private:
std::thread garbageCollectionThread { [&]() { std::thread garbageCollectionThread { [&]() {
while (!threadsShouldQuit) { while (!threadsShouldQuit) {
auto activeVoices { 0 }; auto activeVoices { 0 };
for (auto& voice : voices) for (auto& voice : voices) {
{
voice->garbageCollect(); voice->garbageCollect();
if (!voice->isFree()) if (!voice->isFree())
activeVoices++; activeVoices++;

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ADSREnvelope.h" #include "ADSREnvelope.h"
#include "Defaults.h"
#include "Globals.h" #include "Globals.h"
#include "Region.h" #include "Region.h"
#include "SIMDHelpers.h" #include "SIMDHelpers.h"
@ -7,7 +8,6 @@
#include "StereoBuffer.h" #include "StereoBuffer.h"
#include "StereoSpan.h" #include "StereoSpan.h"
#include "absl/types/span.h" #include "absl/types/span.h"
#include "Defaults.h"
#include <atomic> #include <atomic>
#include <memory> #include <memory>
@ -92,7 +92,6 @@ public:
if (ccState[64] < 63) if (ccState[64] < 63)
egEnvelope.startRelease(delay); egEnvelope.startRelease(delay);
} }
} }
void registerCC(int delay [[maybe_unused]], int channel [[maybe_unused]], int ccNumber [[maybe_unused]], uint8_t ccValue [[maybe_unused]]) void registerCC(int delay [[maybe_unused]], int channel [[maybe_unused]], int ccNumber [[maybe_unused]], uint8_t ccValue [[maybe_unused]])

View file

@ -1,10 +1,10 @@
#include "catch2/catch.hpp"
#include "../sources/ADSREnvelope.h" #include "../sources/ADSREnvelope.h"
#include <array> #include "catch2/catch.hpp"
#include <algorithm>
#include <iostream>
#include <absl/types/span.h>
#include <absl/algorithm/container.h> #include <absl/algorithm/container.h>
#include <absl/types/span.h>
#include <algorithm>
#include <array>
#include <iostream>
using namespace Catch::literals; using namespace Catch::literals;
template <class Type> template <class Type>
@ -14,8 +14,7 @@ inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs,
return false; return false;
for (size_t i = 0; i < rhs.size(); ++i) for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).epsilon(eps)) if (rhs[i] != Approx(lhs[i]).epsilon(eps)) {
{
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n'; std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false; return false;
} }

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Synth.h" #include "../sources/Synth.h"
#include "catch2/catch.hpp"
#include <filesystem> #include <filesystem>
using namespace Catch::literals; using namespace Catch::literals;
@ -109,14 +109,12 @@ TEST_CASE("[Files] Define test")
REQUIRE(synth.getRegionView(2)->keyRange == Range<uint8_t>(42, 42)); REQUIRE(synth.getRegionView(2)->keyRange == Range<uint8_t>(42, 42));
} }
TEST_CASE("[Files] Group from AVL") TEST_CASE("[Files] Group from AVL")
{ {
sfz::Synth synth; sfz::Synth synth;
synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/groups_avl.sfz"); synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/groups_avl.sfz");
REQUIRE(synth.getNumRegions() == 5); REQUIRE(synth.getNumRegions() == 5);
for (int i = 0; i < synth.getNumRegions(); ++i) for (int i = 0; i < synth.getNumRegions(); ++i) {
{
REQUIRE(synth.getRegionView(i)->volume == 6.0f); REQUIRE(synth.getRegionView(i)->volume == 6.0f);
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(36, 36)); REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(36, 36));
} }
@ -132,8 +130,7 @@ TEST_CASE("[Files] Full hierarchy")
sfz::Synth synth; sfz::Synth synth;
synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/basic_hierarchy.sfz"); synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/basic_hierarchy.sfz");
REQUIRE(synth.getNumRegions() == 8); REQUIRE(synth.getNumRegions() == 8);
for (int i = 0; i < synth.getNumRegions(); ++i) for (int i = 0; i < synth.getNumRegions(); ++i) {
{
REQUIRE(synth.getRegionView(i)->width == 40.0f); REQUIRE(synth.getRegionView(i)->width == 40.0f);
} }
REQUIRE(synth.getRegionView(0)->pan == 30.0f); REQUIRE(synth.getRegionView(0)->pan == 30.0f);
@ -214,8 +211,7 @@ TEST_CASE("[Files] Pizz basic")
sfz::Synth synth; sfz::Synth synth;
synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/SpecificBugs/MeatBassPizz/Programs/pizz.sfz"); synth.loadSfzFile(std::filesystem::current_path() / "tests/TestFiles/SpecificBugs/MeatBassPizz/Programs/pizz.sfz");
REQUIRE(synth.getNumRegions() == 4); REQUIRE(synth.getNumRegions() == 4);
for (int i = 0; i < synth.getNumRegions(); ++i) for (int i = 0; i < synth.getNumRegions(); ++i) {
{
REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(12, 22)); REQUIRE(synth.getRegionView(i)->keyRange == Range<uint8_t>(12, 22));
REQUIRE(synth.getRegionView(i)->velocityRange == Range<uint8_t>(97, 127)); REQUIRE(synth.getRegionView(i)->velocityRange == Range<uint8_t>(97, 127));
REQUIRE(synth.getRegionView(i)->pitchKeycenter == 21); REQUIRE(synth.getRegionView(i)->pitchKeycenter == 21);

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Helpers.h" #include "../sources/Helpers.h"
#include "catch2/catch.hpp"
#include <string_view> #include <string_view>
using namespace Catch::literals; using namespace Catch::literals;
using namespace std::literals::string_view_literals; using namespace std::literals::string_view_literals;

View file

@ -1,10 +1,10 @@
#include "catch2/catch.hpp"
#include "../sources/LinearEnvelope.h" #include "../sources/LinearEnvelope.h"
#include <array> #include "catch2/catch.hpp"
#include <algorithm>
#include <iostream>
#include <absl/types/span.h>
#include <absl/algorithm/container.h> #include <absl/algorithm/container.h>
#include <absl/types/span.h>
#include <algorithm>
#include <array>
#include <iostream>
using namespace Catch::literals; using namespace Catch::literals;
template <class Type> template <class Type>
@ -14,8 +14,7 @@ inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs,
return false; return false;
for (size_t i = 0; i < rhs.size(); ++i) for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).epsilon(eps)) if (rhs[i] != Approx(lhs[i]).epsilon(eps)) {
{
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n'; std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false; return false;
} }

View file

@ -1,10 +1,10 @@
#include "../sources/OnePoleFilter.h" #include "../sources/OnePoleFilter.h"
#include "catch2/catch.hpp" #include "catch2/catch.hpp"
#include "cnpy.h" #include "cnpy.h"
#include <string>
#include <filesystem>
#include <algorithm>
#include <absl/types/span.h> #include <absl/types/span.h>
#include <algorithm>
#include <filesystem>
#include <string>
using namespace Catch::literals; using namespace Catch::literals;
template <class Type> template <class Type>
@ -14,8 +14,7 @@ inline bool approxEqual(const std::vector<Type>& lhs, const std::vector<Type>& r
return false; return false;
for (size_t i = 0; i < rhs.size(); ++i) for (size_t i = 0; i < rhs.size(); ++i)
if (lhs[i] != Approx(rhs[i]).epsilon(1e-3)) if (lhs[i] != Approx(rhs[i]).epsilon(1e-3)) {
{
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n'; std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false; return false;
} }
@ -98,28 +97,23 @@ TEST_CASE("[OnePoleFilter] Lowpass Float")
testLowpass<float>( testLowpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.1.npy",
0.1f 0.1f);
);
testLowpass<float>( testLowpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.3.npy",
0.3f 0.3f);
);
testLowpass<float>( testLowpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.5.npy",
0.5f 0.5f);
);
testLowpass<float>( testLowpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.7.npy",
0.7f 0.7f);
);
testLowpass<float>( testLowpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.9.npy",
0.9f 0.9f);
);
} }
TEST_CASE("[OnePoleFilter] Lowpass Double") TEST_CASE("[OnePoleFilter] Lowpass Double")
@ -127,28 +121,23 @@ TEST_CASE("[OnePoleFilter] Lowpass Double")
testLowpass<double>( testLowpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.1.npy",
0.1f 0.1f);
);
testLowpass<double>( testLowpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.3.npy",
0.3f 0.3f);
);
testLowpass<double>( testLowpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.5.npy",
0.5f 0.5f);
);
testLowpass<double>( testLowpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.7.npy",
0.7f 0.7f);
);
testLowpass<double>( testLowpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_low_gain_0.9.npy",
0.9f 0.9f);
);
} }
TEST_CASE("[OnePoleFilter] Highpass Float") TEST_CASE("[OnePoleFilter] Highpass Float")
@ -156,28 +145,23 @@ TEST_CASE("[OnePoleFilter] Highpass Float")
testHighpass<float>( testHighpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.1.npy",
0.1f 0.1f);
);
testHighpass<float>( testHighpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.3.npy",
0.3f 0.3f);
);
testHighpass<float>( testHighpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.5.npy",
0.5f 0.5f);
);
testHighpass<float>( testHighpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.7.npy",
0.7f 0.7f);
);
testHighpass<float>( testHighpass<float>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.9.npy",
0.9f 0.9f);
);
} }
TEST_CASE("[OnePoleFilter] Highpass Double") TEST_CASE("[OnePoleFilter] Highpass Double")
@ -185,26 +169,21 @@ TEST_CASE("[OnePoleFilter] Highpass Double")
testHighpass<double>( testHighpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.1.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.1.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.1.npy",
0.1f 0.1f);
);
testHighpass<double>( testHighpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.3.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.3.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.3.npy",
0.3f 0.3f);
);
testHighpass<double>( testHighpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.5.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.5.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.5.npy",
0.5f 0.5f);
);
testHighpass<double>( testHighpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.7.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.7.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.7.npy",
0.7f 0.7f);
);
testHighpass<double>( testHighpass<double>(
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_input_gain_0.9.npy",
std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.9.npy", std::filesystem::current_path() / "tests/TestFiles/OnePoleFilter/OPF_high_gain_0.9.npy",
0.9f 0.9f);
);
} }

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Region.h" #include "../sources/Region.h"
#include "catch2/catch.hpp"
using namespace Catch::literals; using namespace Catch::literals;
TEST_CASE("[Opcode] Construction") TEST_CASE("[Opcode] Construction")

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Parser.h" #include "../sources/Parser.h"
#include "catch2/catch.hpp"
using namespace Catch::literals; using namespace Catch::literals;
void includeTest(const std::string& line, const std::string& fileName) void includeTest(const std::string& line, const std::string& fileName)

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Region.h" #include "../sources/Region.h"
#include "catch2/catch.hpp"
using namespace Catch::literals; using namespace Catch::literals;
TEST_CASE("Region activation", "Region tests") TEST_CASE("Region activation", "Region tests")
@ -219,7 +219,6 @@ TEST_CASE("Region activation", "Region tests")
REQUIRE(!region.isSwitchedOn()); REQUIRE(!region.isSwitchedOn());
region.registerNoteOff(1, 40, 0, 0.5f); region.registerNoteOff(1, 40, 0, 0.5f);
REQUIRE(!region.isSwitchedOn()); REQUIRE(!region.isSwitchedOn());
} }
SECTION("Sequences: length 2, position 2") SECTION("Sequences: length 2, position 2")
{ {
@ -239,7 +238,6 @@ TEST_CASE("Region activation", "Region tests")
REQUIRE(region.isSwitchedOn()); REQUIRE(region.isSwitchedOn());
region.registerNoteOff(1, 40, 0, 0.5f); region.registerNoteOff(1, 40, 0, 0.5f);
REQUIRE(region.isSwitchedOn()); REQUIRE(region.isSwitchedOn());
} }
SECTION("Sequences: length 3, position 2") SECTION("Sequences: length 3, position 2")
{ {
@ -265,4 +263,3 @@ TEST_CASE("Region activation", "Region tests")
REQUIRE(region.isSwitchedOn()); REQUIRE(region.isSwitchedOn());
} }
} }

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Region.h" #include "../sources/Region.h"
#include "catch2/catch.hpp"
using namespace Catch::literals; using namespace Catch::literals;
TEST_CASE("[Region] Parsing opcodes") TEST_CASE("[Region] Parsing opcodes")
@ -428,8 +428,7 @@ TEST_CASE("[Region] Parsing opcodes")
SECTION("on_locc, on_hicc") SECTION("on_locc, on_hicc")
{ {
for (int ccIdx = 1; ccIdx < 128; ++ccIdx) for (int ccIdx = 1; ccIdx < 128; ++ccIdx) {
{
REQUIRE(!region.ccTriggers.contains(ccIdx)); REQUIRE(!region.ccTriggers.contains(ccIdx));
} }
region.parseOpcode({ "on_locc45", "15" }); region.parseOpcode({ "on_locc45", "15" });

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/Region.h" #include "../sources/Region.h"
#include "catch2/catch.hpp"
using namespace Catch::literals; using namespace Catch::literals;
TEST_CASE("Basic triggers", "Region triggers") TEST_CASE("Basic triggers", "Region triggers")

View file

@ -1,10 +1,10 @@
#include "catch2/catch.hpp"
#include "../sources/SIMDHelpers.h" #include "../sources/SIMDHelpers.h"
#include <array> #include "catch2/catch.hpp"
#include <algorithm>
#include <iostream>
#include <absl/types/span.h>
#include <absl/algorithm/container.h> #include <absl/algorithm/container.h>
#include <absl/types/span.h>
#include <algorithm>
#include <array>
#include <iostream>
using namespace Catch::literals; using namespace Catch::literals;
constexpr int smallBufferSize { 3 }; constexpr int smallBufferSize { 3 };
@ -19,8 +19,7 @@ inline bool approxEqual(absl::Span<const Type> lhs, absl::Span<const Type> rhs,
return false; return false;
for (size_t i = 0; i < rhs.size(); ++i) for (size_t i = 0; i < rhs.size(); ++i)
if (rhs[i] != Approx(lhs[i]).epsilon(eps)) if (rhs[i] != Approx(lhs[i]).epsilon(eps)) {
{
std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n'; std::cerr << lhs[i] << " != " << rhs[i] << " at index " << i << '\n';
return false; return false;
} }
@ -96,7 +95,6 @@ TEST_CASE("[Helpers] fill() - Big buffer -- doubles")
REQUIRE(buffer == expected); REQUIRE(buffer == expected);
} }
TEST_CASE("[Helpers] Interleaved read") TEST_CASE("[Helpers] Interleaved read")
{ {
std::array<float, 16> input { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f }; std::array<float, 16> input { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };
@ -215,7 +213,16 @@ TEST_CASE("[Helpers] Interleaved read SIMD vs Scalar")
TEST_CASE("[Helpers] Interleaved write") TEST_CASE("[Helpers] Interleaved write")
{ {
std::array<float, 8> leftInput { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, }; std::array<float, 8> leftInput {
0.0f,
1.0f,
2.0f,
3.0f,
4.0f,
5.0f,
6.0f,
7.0f,
};
std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 16> output; std::array<float, 16> output;
std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f }; std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };
@ -245,7 +252,16 @@ TEST_CASE("[Helpers] Small interleaved write unaligned end")
TEST_CASE("[Helpers] Interleaved write -- SIMD") TEST_CASE("[Helpers] Interleaved write -- SIMD")
{ {
std::array<float, 8> leftInput { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, }; std::array<float, 8> leftInput {
0.0f,
1.0f,
2.0f,
3.0f,
4.0f,
5.0f,
6.0f,
7.0f,
};
std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f }; std::array<float, 8> rightInput { 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f };
std::array<float, 16> output; std::array<float, 16> output;
std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f }; std::array<float, 16> expected { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, 4.0f, 14.0f, 5.0f, 15.0f, 6.0f, 16.0f, 7.0f, 17.0f };

View file

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include "../sources/StereoBuffer.h" #include "../sources/StereoBuffer.h"
#include "catch2/catch.hpp"
#include <algorithm> #include <algorithm>
using namespace Catch::literals; using namespace Catch::literals;
@ -33,14 +33,12 @@ TEST_CASE("[StereoBuffer] Access")
{ {
const int size { 5 }; const int size { 5 };
StereoBuffer<double> doubleBuffer(size); StereoBuffer<double> doubleBuffer(size);
for (auto frameIdx = 0; frameIdx < doubleBuffer.getNumFrames(); ++frameIdx) for (auto frameIdx = 0; frameIdx < doubleBuffer.getNumFrames(); ++frameIdx) {
{
doubleBuffer.getSample(Channel::left, frameIdx) = static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx; doubleBuffer.getSample(Channel::left, frameIdx) = static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx;
doubleBuffer.getSample(Channel::right, frameIdx) = static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx; doubleBuffer.getSample(Channel::right, frameIdx) = static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx;
} }
for (auto frameIdx = 0; frameIdx < doubleBuffer.getNumFrames(); ++frameIdx) for (auto frameIdx = 0; frameIdx < doubleBuffer.getNumFrames(); ++frameIdx) {
{
REQUIRE(doubleBuffer.getSample(Channel::left, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx); REQUIRE(doubleBuffer.getSample(Channel::left, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx);
REQUIRE(doubleBuffer(Channel::left, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx); REQUIRE(doubleBuffer(Channel::left, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) + frameIdx);
REQUIRE(doubleBuffer.getSample(Channel::right, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx); REQUIRE(doubleBuffer.getSample(Channel::right, frameIdx) == static_cast<double>(doubleBuffer.getNumFrames()) - frameIdx);
@ -147,7 +145,6 @@ TEST_CASE("[AudioBuffer] fills")
REQUIRE(real == expected); REQUIRE(real == expected);
} }
TEST_CASE("[AudioBuffer] Fill a big Audiobuffer") TEST_CASE("[AudioBuffer] Fill a big Audiobuffer")
{ {
constexpr int size { 2039247 }; constexpr int size { 2039247 };