Added the basic structure for changing the oversampling factor

This commit is contained in:
Paul Ferrand 2019-12-01 11:57:42 +01:00
parent 4aa370dd0a
commit d151e31406
5 changed files with 78 additions and 3 deletions

View file

@ -24,6 +24,13 @@
#pragma once #pragma once
namespace sfz { namespace sfz {
enum class Oversampling: int
{
x1 = 1,
x2 = 2,
x4 = 4,
x8 = 8
};
namespace config { namespace config {
constexpr float defaultSampleRate { 48000 }; constexpr float defaultSampleRate { 48000 };
@ -37,7 +44,7 @@ namespace config {
constexpr float virtuallyZero { 0.00005f }; constexpr float virtuallyZero { 0.00005f };
constexpr float fastReleaseDuration { 0.01 }; constexpr float fastReleaseDuration { 0.01 };
constexpr char defineCharacter { '$' }; constexpr char defineCharacter { '$' };
constexpr int oversamplingFactor { 2 }; constexpr Oversampling defaultOversamplingFactor { Oversampling::x1 };
constexpr float A440 { 440.0 }; constexpr float A440 { 440.0 };
constexpr unsigned powerHistoryLength { 16 }; constexpr unsigned powerHistoryLength { 16 };
constexpr float voiceStealingThreshold { 0.00001 }; constexpr float voiceStealingThreshold { 0.00001 };

View file

@ -773,3 +773,13 @@ float sfz::Region::velocityCurve(uint8_t velocity) const noexcept
return gain; return gain;
} }
void sfz::Region::setOversamplingFactor(sfz::Oversampling factor) noexcept
{
oversamplingFactor = factor;
}
sfz::Oversampling sfz::Region::getOversamplingFactor() const noexcept
{
return oversamplingFactor;
}

View file

@ -49,8 +49,8 @@ namespace sfz {
* *
*/ */
struct Region { struct Region {
Region(const MidiState& midiState) Region(const MidiState& midiState, Oversampling factor = config::defaultOversamplingFactor)
: midiState(midiState) : midiState(midiState), oversamplingFactor(factor)
{ {
ccSwitched.set(); ccSwitched.set();
} }
@ -238,6 +238,22 @@ struct Region {
*/ */
bool parseOpcode(const Opcode& opcode); bool parseOpcode(const Opcode& opcode);
/**
* @brief Set the oversampling factor to a new value. This will trigger updates of
* all the relevant values (sample ends, loop points, etc). It will also trigger
* preloading the file data again.
*
* @param factor
*/
void setOversamplingFactor(Oversampling factor) noexcept;
/**
* @brief get the current oversampling factor
*
* @return Oversampling
*/
Oversampling getOversamplingFactor() const noexcept;
// Sound source: sample playback // Sound source: sample playback
std::string sample {}; // Sample std::string sample {}; // Sample
float delay { Default::delay }; // delay float delay { Default::delay }; // delay
@ -338,6 +354,8 @@ private:
int activeNotesInRange { -1 }; int activeNotesInRange { -1 };
int sequenceCounter { 0 }; int sequenceCounter { 0 };
Oversampling oversamplingFactor { config::defaultOversamplingFactor };
std::uniform_real_distribution<float> volumeDistribution { -sfz::Default::ampRandom, sfz::Default::ampRandom }; std::uniform_real_distribution<float> volumeDistribution { -sfz::Default::ampRandom, sfz::Default::ampRandom };
std::uniform_real_distribution<float> delayDistribution { 0, sfz::Default::delayRandom }; std::uniform_real_distribution<float> delayDistribution { 0, sfz::Default::delayRandom };
std::uniform_int_distribution<uint32_t> offsetDistribution { 0, sfz::Default::offsetRandom }; std::uniform_int_distribution<uint32_t> offsetDistribution { 0, sfz::Default::offsetRandom };

View file

@ -546,3 +546,26 @@ void sfz::Synth::resetVoices(int numVoices)
voiceViewArray.reserve(numVoices); voiceViewArray.reserve(numVoices);
this->numVoices = numVoices; this->numVoices = numVoices;
} }
void sfz::Synth::setOversamplingFactor(sfz::Oversampling factor) noexcept
{
AtomicDisabler callbackDisabler{ canEnterCallback };
while (inCallback) {
std::this_thread::sleep_for(1ms);
}
resources.filePool.emptyFileLoadingQueue();
for (auto& voice: voices)
voice->reset();
for (auto& region: regions) {
region->setOversamplingFactor(factor);
}
oversamplingFactor = factor;
}
sfz::Oversampling sfz::Synth::getOversamplingFactor() const noexcept
{
return oversamplingFactor;
}

View file

@ -279,6 +279,22 @@ public:
* *
*/ */
void garbageCollect() noexcept; void garbageCollect() noexcept;
/**
* @brief Set the oversampling factor to a new value. This will disable all callbacks
* kill all the voices, and trigger a reloading of every file in the FilePool under
* the new oversampling.
*
* @param factor
*/
void setOversamplingFactor(Oversampling factor) noexcept;
/**
* @brief get the current oversampling factor
*
* @return Oversampling
*/
Oversampling getOversamplingFactor() const noexcept;
protected: protected:
/** /**
* @brief The parser callback; this is called by the parent object each time * @brief The parser callback; this is called by the parent object each time
@ -370,6 +386,7 @@ private:
float sampleRate { config::defaultSampleRate }; float sampleRate { config::defaultSampleRate };
float volume { Default::volume }; float volume { Default::volume };
int numVoices { config::numVoices }; int numVoices { config::numVoices };
Oversampling oversamplingFactor { config::defaultOversamplingFactor };
// Distribution used to generate random value for the *rand opcodes // Distribution used to generate random value for the *rand opcodes
std::uniform_real_distribution<float> randNoteDistribution { 0, 1 }; std::uniform_real_distribution<float> randNoteDistribution { 0, 1 };