Continue integrating the preloading size and oversampling factor

This commit is contained in:
Paul Ferrand 2019-12-01 20:44:49 +01:00
parent 630220e7e0
commit d017a63a36
8 changed files with 72 additions and 48 deletions

View file

@ -24,8 +24,7 @@
#pragma once
namespace sfz {
enum class Oversampling: int
{
enum Oversampling {
x1 = 1,
x2 = 2,
x4 = 4,

View file

@ -142,7 +142,7 @@ void sfz::FilePool::loadingThread() noexcept
if (sndFile.error() != 0)
continue;
DBG("Loading file for " << *promise->filename << " in the background");
DBG("Loading file for " << promise->filename << " in the background");
const uint32_t frames = sndFile.frames();
promise->fileData = readFromFile<float>(sndFile, frames);
promise->dataReady = true;
@ -179,3 +179,19 @@ void sfz::FilePool::cleanupPromises() noexcept
}
}
}
void sfz::FilePool::setOversamplingFactor(sfz::Oversampling factor) noexcept
{
this->oversamplingFactor = factor;
}
sfz::Oversampling sfz::FilePool::getOversamplingFactor() const noexcept
{
return oversamplingFactor;
}
uint32_t sfz::FilePool::getPreloadSize() const noexcept
{
return preloadSize;
}

View file

@ -133,6 +133,9 @@ public:
void cleanupPromises() noexcept;
FilePromisePtr getFilePromise(const std::string& filename) noexcept;
void setPreloadSize(uint32_t preloadSize) noexcept;
uint32_t getPreloadSize() const noexcept;
void setOversamplingFactor(Oversampling factor) noexcept;
Oversampling getOversamplingFactor() const noexcept;
private:
fs::path rootDirectory;

View file

@ -644,9 +644,9 @@ float sfz::Region::getBaseGain() noexcept
return normalizePercents(amplitude);
}
uint32_t sfz::Region::getOffset() noexcept
uint32_t sfz::Region::getOffset(Oversampling factor) noexcept
{
return offset + offsetDistribution(Random::randomGenerator);
return (offset + offsetDistribution(Random::randomGenerator)) * factor;
}
float sfz::Region::getDelay() noexcept
@ -654,9 +654,19 @@ float sfz::Region::getDelay() noexcept
return delay + delayDistribution(Random::randomGenerator);
}
uint32_t sfz::Region::trueSampleEnd() const noexcept
uint32_t sfz::Region::trueSampleEnd(Oversampling factor) const noexcept
{
return min(sampleEnd, loopRange.getEnd());
return min(sampleEnd, loopRange.getEnd()) * factor;
}
uint32_t sfz::Region::loopStart(Oversampling factor) const noexcept
{
return loopRange.getStart() * factor;
}
uint32_t sfz::Region::loopEnd(Oversampling factor) const noexcept
{
return loopRange.getEnd() * factor;
}
template<class T, class U>
@ -757,13 +767,3 @@ float sfz::Region::velocityCurve(uint8_t velocity) const noexcept
return gain;
}
void sfz::Region::setOversamplingFactor(sfz::Oversampling factor) noexcept
{
oversamplingFactor = factor;
}
sfz::Oversampling sfz::Region::getOversamplingFactor() const noexcept
{
return oversamplingFactor;
}

View file

@ -201,7 +201,7 @@ struct Region {
*
* @return uint32_t
*/
uint32_t getOffset() noexcept;
uint32_t getOffset(Oversampling factor = x1) noexcept;
/**
* @brief Get the region delay in seconds
*
@ -214,14 +214,7 @@ struct Region {
*
* @return uint32_t
*/
uint32_t trueSampleEnd() const noexcept;
/**
* @brief Can the region use the preloaded data only to play its full range?
*
* @return true
* @return false
*/
bool canUsePreloadedData() const noexcept;
uint32_t trueSampleEnd(Oversampling factor = x1) const noexcept;
/**
* @brief Parse a new opcode into the region to fill in the proper parameters.
* This must be called multiple times for each opcode applying to this region.
@ -232,21 +225,8 @@ struct Region {
*/
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;
uint32_t loopStart(Oversampling factor = x1) const noexcept;
uint32_t loopEnd(Oversampling factor = x1) const noexcept;
// Sound source: sample playback
std::string sample {}; // Sample

View file

@ -550,10 +550,7 @@ void sfz::Synth::setOversamplingFactor(sfz::Oversampling factor) noexcept
for (auto& voice: voices)
voice->reset();
for (auto& region: regions) {
region->setOversamplingFactor(factor);
}
resources.filePool.setOversamplingFactor(factor);
oversamplingFactor = factor;
}
@ -561,3 +558,18 @@ sfz::Oversampling sfz::Synth::getOversamplingFactor() const noexcept
{
return oversamplingFactor;
}
void sfz::Synth::setPreloadSize(uint32_t preloadSize) noexcept
{
AtomicDisabler callbackDisabler{ canEnterCallback };
while (inCallback) {
std::this_thread::sleep_for(1ms);
}
resources.filePool.setPreloadSize(preloadSize);
}
uint32_t sfz::Synth::getPreloadSize() const noexcept
{
return resources.filePool.getPreloadSize();
}

View file

@ -296,6 +296,20 @@ public:
* @return Oversampling
*/
Oversampling getOversamplingFactor() const noexcept;
/**
* @brief Set the preloaded file size. This will disable the callback.
*
* @param factor
*/
void setPreloadSize(uint32_t preloadSize) noexcept;
/**
* @brief get the current preloaded file size
*
* @return Oversampling
*/
uint32_t getPreloadSize() const noexcept;
protected:
/**
* @brief The parser callback; this is called by the parent object each time

View file

@ -373,9 +373,9 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
add<int>(sourcePosition, indices);
//FIXME : all this casting is driving me crazy
const auto sampleEnd = min(static_cast<int>(region->trueSampleEnd()), static_cast<int>(source.getNumFrames())) - 1;
if (region->shouldLoop() && region->loopRange.getEnd() <= source.getNumFrames()) {
const auto offset = sampleEnd - static_cast<int>(region->loopRange.getStart());
const auto sampleEnd = min(static_cast<size_t>(region->trueSampleEnd(currentPromise->oversamplingFactor)), source.getNumFrames()) - 1;
if (region->shouldLoop() && region->loopEnd(currentPromise->oversamplingFactor) <= source.getNumFrames()) {
const auto offset = sampleEnd - static_cast<int>(region->loopStart(currentPromise->oversamplingFactor));
for (auto* index = indices.begin(); index < indices.end(); ++index) {
if (*index > sampleEnd) {
const auto remainingElements = static_cast<size_t>(std::distance(index, indices.end()));