Changed the queue and added debug messages
This commit is contained in:
parent
1d5a70b252
commit
f410bcb072
2 changed files with 43 additions and 35 deletions
|
|
@ -86,15 +86,15 @@ void streamFromFile(SndfileHandle& sndFile, uint32_t numFrames, sfz::Oversamplin
|
||||||
}
|
}
|
||||||
|
|
||||||
sfz::FilePool::FilePool()
|
sfz::FilePool::FilePool()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < config::numBackgroundThreads; ++i)
|
for (int i = 0; i < config::numBackgroundThreads; ++i)
|
||||||
threadPool.emplace_back( &FilePool::loadingThread, this );
|
threadPool.emplace_back( &FilePool::loadingThread, this );
|
||||||
|
|
||||||
threadPool.emplace_back( &FilePool::clearingThread, this );
|
threadPool.emplace_back( &FilePool::clearingThread, this );
|
||||||
|
|
||||||
for (int i = 0; i < config::maxFilePromises; ++i)
|
for (int i = 0; i < config::maxFilePromises; ++i)
|
||||||
emptyPromises.push_back(std::make_shared<FilePromise>());
|
emptyPromises.push_back(std::make_shared<FilePromise>());
|
||||||
}
|
}
|
||||||
|
|
||||||
sfz::FilePool::~FilePool()
|
sfz::FilePool::~FilePool()
|
||||||
{
|
{
|
||||||
|
|
@ -165,21 +165,29 @@ bool sfz::FilePool::preloadFile(const std::string& filename, uint32_t maxOffset)
|
||||||
|
|
||||||
sfz::FilePromisePtr sfz::FilePool::getFilePromise(const std::string& filename) noexcept
|
sfz::FilePromisePtr sfz::FilePool::getFilePromise(const std::string& filename) noexcept
|
||||||
{
|
{
|
||||||
if (emptyPromises.empty())
|
if (emptyPromises.empty()) {
|
||||||
|
DBG("[sfizz] No empty promises left to honor the one for " << filename);
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const auto preloaded = preloadedFiles.find(filename);
|
const auto preloaded = preloadedFiles.find(filename);
|
||||||
if (preloaded == preloadedFiles.end())
|
if (preloaded == preloadedFiles.end()) {
|
||||||
|
DBG("[sfizz] File not found in the preloaded files: " << filename);
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
auto promise = emptyPromises.back();
|
auto promise = emptyPromises.back();
|
||||||
promise->filename = preloaded->first;
|
promise->filename = preloaded->first;
|
||||||
promise->preloadedData = preloaded->second.preloadedData;
|
promise->preloadedData = preloaded->second.preloadedData;
|
||||||
promise->sampleRate = preloaded->second.sampleRate;
|
promise->sampleRate = preloaded->second.sampleRate;
|
||||||
promise->oversamplingFactor = oversamplingFactor;
|
promise->oversamplingFactor = oversamplingFactor;
|
||||||
promiseQueue.try_enqueue(promise);
|
|
||||||
emptyPromises.pop_back();
|
|
||||||
|
|
||||||
|
if (!promiseQueue.try_push(promise)) {
|
||||||
|
DBG("[sfizz] Could not enqueue the promise for " << filename << " (queue size " << promiseQueue.size() << ")");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyPromises.pop_back();
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,37 +229,34 @@ void sfz::FilePool::loadingThread() noexcept
|
||||||
{
|
{
|
||||||
FilePromisePtr promise;
|
FilePromisePtr promise;
|
||||||
while (!quitThread) {
|
while (!quitThread) {
|
||||||
|
|
||||||
if (emptyQueue) {
|
if (emptyQueue) {
|
||||||
while(promiseQueue.try_dequeue(promise)) {
|
while(promiseQueue.try_pop(promise)) {
|
||||||
// We're just dequeuing
|
// We're just dequeuing
|
||||||
}
|
}
|
||||||
emptyQueue = false;
|
emptyQueue = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!promiseQueue.wait_dequeue_timed(promise, 50ms)) {
|
if (!promiseQueue.try_pop(promise)) {
|
||||||
|
std::this_thread::sleep_for(1ms);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The voice abandoned the promise already we just don't care
|
threadsLoading++;
|
||||||
if (promise.use_count() != 1) {
|
fs::path file { rootDirectory / std::string(promise->filename) };
|
||||||
threadsLoading++;
|
SndfileHandle sndFile(file.c_str());
|
||||||
|
if (sndFile.error() != 0) {
|
||||||
fs::path file { rootDirectory / std::string(promise->filename) };
|
DBG("[sfizz] libsndfile errored for " << promise->filename << " with message " << sndFile.strError());
|
||||||
SndfileHandle sndFile(file.c_str());
|
continue;
|
||||||
if (sndFile.error() != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DBG("Loading file for " << promise->filename << " in the background");
|
|
||||||
const uint32_t frames = sndFile.frames();
|
|
||||||
streamFromFile<float>(sndFile, frames, oversamplingFactor, promise->fileData, &promise->availableFrames);
|
|
||||||
promise->dataReady = true;
|
|
||||||
|
|
||||||
threadsLoading--;
|
|
||||||
}
|
}
|
||||||
|
const uint32_t frames = sndFile.frames();
|
||||||
|
streamFromFile<float>(sndFile, frames, oversamplingFactor, promise->fileData, &promise->availableFrames);
|
||||||
|
promise->dataReady = true;
|
||||||
|
threadsLoading--;
|
||||||
|
|
||||||
while (!filledPromiseQueue.try_enqueue(promise)) {
|
while (!filledPromiseQueue.try_push(promise)) {
|
||||||
DBG("Error enqueuing the file for " << promise->filename << " in the filledPromiseQueue");
|
DBG("[sfizz] Error enqueuing the promise for " << promise->filename << " in the filledPromiseQueue");
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,7 +297,7 @@ void sfz::FilePool::cleanupPromises() noexcept
|
||||||
FilePromisePtr promise;
|
FilePromisePtr promise;
|
||||||
// Remove the promises from the filled queue and put them in a linear
|
// Remove the promises from the filled queue and put them in a linear
|
||||||
// storage
|
// storage
|
||||||
while (filledPromiseQueue.try_dequeue(promise))
|
while (filledPromiseQueue.try_pop(promise))
|
||||||
temporaryFilePromises.push_back(promise);
|
temporaryFilePromises.push_back(promise);
|
||||||
|
|
||||||
auto filledIterator = temporaryFilePromises.begin();
|
auto filledIterator = temporaryFilePromises.begin();
|
||||||
|
|
@ -346,7 +351,7 @@ void sfz::FilePool::waitForBackgroundLoading() noexcept
|
||||||
// TODO: validate that this is enough, otherwise we will need an atomic count
|
// TODO: validate that this is enough, otherwise we will need an atomic count
|
||||||
// of the files we need to load still.
|
// of the files we need to load still.
|
||||||
// Spinlocking on the size of the background queue
|
// Spinlocking on the size of the background queue
|
||||||
while (promiseQueue.size_approx() > 0)
|
while (promiseQueue.size() > 0)
|
||||||
std::this_thread::sleep_for(0.1ms);
|
std::this_thread::sleep_for(0.1ms);
|
||||||
// Spinlocking on the threads possibly logging in the background
|
// Spinlocking on the threads possibly logging in the background
|
||||||
while (threadsLoading > 0)
|
while (threadsLoading > 0)
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@
|
||||||
#include <absl/container/flat_hash_map.h>
|
#include <absl/container/flat_hash_map.h>
|
||||||
#include <absl/types/optional.h>
|
#include <absl/types/optional.h>
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "moodycamel/blockingconcurrentqueue.h"
|
// #include "moodycamel/concurrentqueue.h"
|
||||||
|
#include "atomic_queue/atomic_queue.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <sndfile.hh>
|
#include <sndfile.hh>
|
||||||
|
|
||||||
|
|
@ -215,8 +216,10 @@ private:
|
||||||
void clearingThread();
|
void clearingThread();
|
||||||
void tryToClearPromises();
|
void tryToClearPromises();
|
||||||
|
|
||||||
moodycamel::BlockingConcurrentQueue<FilePromisePtr> promiseQueue { config::maxVoices };
|
// moodycamel::ConcurrentQueue<FilePromisePtr> promiseQueue { config::maxVoices };
|
||||||
moodycamel::BlockingConcurrentQueue<FilePromisePtr> filledPromiseQueue { config::maxVoices };
|
// moodycamel::ConcurrentQueue<FilePromisePtr> filledPromiseQueue { config::maxVoices };
|
||||||
|
atomic_queue::AtomicQueue2<FilePromisePtr, config::maxVoices> promiseQueue;
|
||||||
|
atomic_queue::AtomicQueue2<FilePromisePtr, config::maxVoices> filledPromiseQueue;
|
||||||
uint32_t preloadSize { config::preloadSize };
|
uint32_t preloadSize { config::preloadSize };
|
||||||
Oversampling oversamplingFactor { config::defaultOversamplingFactor };
|
Oversampling oversamplingFactor { config::defaultOversamplingFactor };
|
||||||
// Signals
|
// Signals
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue