Merge pull request #172 from paulfd/eg-issues
Solve some issues with DSmolken's drumkits
This commit is contained in:
commit
4c6febeca3
7 changed files with 96 additions and 8 deletions
|
|
@ -284,6 +284,7 @@ void Application::performSfzUpdate()
|
|||
|
||||
QString code;
|
||||
code += "<region>\n";
|
||||
code += "key=69\n";
|
||||
code += "sample="; code += QFileInfo(samplePath).fileName(); code += "\n";
|
||||
code += _ui->envelopeEdit->toPlainText();
|
||||
|
||||
|
|
|
|||
|
|
@ -40,11 +40,9 @@ void ADSREnvelope<Type>::reset(const EGDescription& desc, const Region& region,
|
|||
|
||||
releaseDelay = 0;
|
||||
shouldRelease = false;
|
||||
freeRunning = (
|
||||
(region.trigger == SfzTrigger::release)
|
||||
freeRunning = ((region.trigger == SfzTrigger::release)
|
||||
|| (region.trigger == SfzTrigger::release_key)
|
||||
|| region.loopMode == SfzLoopMode::one_shot
|
||||
);
|
||||
|| (region.loopMode == SfzLoopMode::one_shot && (region.isGenerator() || region.oscillator)));
|
||||
currentValue = this->start;
|
||||
currentState = State::Delay;
|
||||
}
|
||||
|
|
@ -117,8 +115,7 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
|
|||
// release takes effect this frame
|
||||
currentState = State::Release;
|
||||
releaseDelay = -1;
|
||||
}
|
||||
else if (shouldRelease && releaseDelay > 0) {
|
||||
} else if (shouldRelease && releaseDelay > 0) {
|
||||
// prevent computing the segment further than release point
|
||||
size = std::min<size_t>(size, releaseDelay);
|
||||
}
|
||||
|
|
@ -188,6 +185,8 @@ void ADSREnvelope<Type>::getBlock(absl::Span<Type> output) noexcept
|
|||
this->currentValue = currentValue;
|
||||
this->shouldRelease = shouldRelease;
|
||||
this->releaseDelay = releaseDelay;
|
||||
|
||||
ASSERT(!hasNanInf(output));
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#pragma once
|
||||
#include "Config.h"
|
||||
#include "Macros.h"
|
||||
#include "absl/types/span.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
|
|
@ -292,3 +293,38 @@ inline F fp_from_parts(bool sgn, int ex, uint64_t mant)
|
|||
(static_cast<I>(sgn) << (T::e_bits + T::m_bits));
|
||||
return u.real;
|
||||
}
|
||||
|
||||
template <class F>
|
||||
inline bool fp_naninf(F x)
|
||||
{
|
||||
typedef FP_traits<F> T;
|
||||
typedef typename T::same_size_int I;
|
||||
union {
|
||||
F real;
|
||||
I integer;
|
||||
} u;
|
||||
u.real = x;
|
||||
const auto all_ones = ((1u << T::e_bits) - 1);
|
||||
const auto ex = (u.integer >> T::m_bits) & all_ones;
|
||||
return ex == all_ones;
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
bool hasNanInf(absl::Span<Type> span)
|
||||
{
|
||||
for (const auto& x : span)
|
||||
if (fp_naninf(x))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Type>
|
||||
bool isValidAudio(absl::Span<Type> span)
|
||||
{
|
||||
for (const auto& x : span)
|
||||
if (x < -1.0f || x > 1.0f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -624,6 +624,11 @@ void sfz::Synth::renderBlock(AudioSpan<float> buffer) noexcept
|
|||
|
||||
// Reset the dispatch counter
|
||||
dispatchDuration = Duration(0);
|
||||
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(0)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(1)));
|
||||
}
|
||||
|
||||
void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept
|
||||
|
|
|
|||
|
|
@ -241,6 +241,12 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
|
|||
|
||||
powerHistory.push(buffer.meanSquared());
|
||||
this->triggerDelay = absl::nullopt;
|
||||
#if 0
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(0)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(1)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void sfz::Voice::amplitudeEnvelope(absl::Span<float> modulationSpan) noexcept
|
||||
|
|
@ -515,6 +521,13 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
|
|||
|
||||
sourcePosition = indices->back();
|
||||
floatPositionOffset = rightCoeffs->back();
|
||||
|
||||
#if 0
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(0)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(1)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
||||
|
|
@ -573,6 +586,13 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(0)));
|
||||
ASSERT(!hasNanInf(buffer.getConstSpan(1)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(0)));
|
||||
ASSERT(isValidAudio(buffer.getConstSpan(1)));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept
|
||||
|
|
|
|||
|
|
@ -253,8 +253,18 @@ WavetableMulti WavetableMulti::createForHarmonicProfile(
|
|||
const WavetableMulti* WavetableMulti::getSilenceWavetable()
|
||||
{
|
||||
static WavetableMulti wm;
|
||||
wm.allocateStorage(1);
|
||||
wm.fillExtra();
|
||||
static bool initialized { false };
|
||||
|
||||
if (!initialized) {
|
||||
constexpr unsigned numTables = WavetableMulti::numTables();
|
||||
wm.allocateStorage(1);
|
||||
for (unsigned m = 0; m < numTables; ++m) {
|
||||
float* ptr = const_cast<float*>(wm.getTablePointer(m));
|
||||
*ptr = 0;
|
||||
}
|
||||
wm.fillExtra();
|
||||
initialized = true;
|
||||
}
|
||||
return &wm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "catch2/catch.hpp"
|
||||
#include "sfizz/MathHelpers.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
TEST_CASE("[FloatMath] Fast ilog2 (float)")
|
||||
{
|
||||
|
|
@ -51,3 +52,19 @@ TEST_CASE("[FloatMath] Break apart and reconstruct (double)")
|
|||
REQUIRE(fp_from_parts<double>(sgn, ex, mant.num) == f);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("[FloatMath] Nan/Inf checker")
|
||||
{
|
||||
REQUIRE(fp_naninf(std::numeric_limits<double>::quiet_NaN()));
|
||||
REQUIRE(fp_naninf(std::numeric_limits<float>::quiet_NaN()));
|
||||
REQUIRE(fp_naninf(std::numeric_limits<double>::infinity()));
|
||||
REQUIRE(fp_naninf(std::numeric_limits<float>::infinity()));
|
||||
REQUIRE(fp_naninf(-std::numeric_limits<double>::infinity()));
|
||||
REQUIRE(fp_naninf(-std::numeric_limits<float>::infinity()));
|
||||
REQUIRE(!fp_naninf(0.0f));
|
||||
REQUIRE(!fp_naninf(0.0));
|
||||
REQUIRE(!fp_naninf(1.0f));
|
||||
REQUIRE(!fp_naninf(1.0));
|
||||
REQUIRE(!fp_naninf(-1.0f));
|
||||
REQUIRE(!fp_naninf(-1.0));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue