Added the background loading thread and the sample rate in the file

This commit is contained in:
paul 2019-08-05 01:32:01 +02:00
parent 2a493873ae
commit d0264f3416
5 changed files with 73 additions and 4 deletions

View file

@ -63,6 +63,10 @@ if (WIN32)
target_include_directories(sndfile INTERFACE "${WIN_SNDFILE_PATH}/include")
endif()
# Export MoodyCamel's queue as a library
add_library(readerwriterqueue INTERFACE)
target_include_directories(readerwriterqueue INTERFACE "external/readerwriterqueue")
# Export the compile_commands.json file
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@ -121,7 +125,7 @@ add_executable(sfizz sources/Main.cpp ${COMMON_SOURCES})
if(UNIX)
target_link_libraries(sfizz stdc++fs)
endif(UNIX)
target_link_libraries(sfizz absl::strings cxxopts sndfile absl::flat_hash_map)
target_link_libraries(sfizz absl::strings cxxopts sndfile absl::flat_hash_map readerwriterqueue)
###############################
# Test application

View file

@ -9,7 +9,7 @@ std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(
SndfileHandle sndFile ( reinterpret_cast<const char*>(file.c_str()) );
FileInformation returnedValue;
returnedValue.end = static_cast<uint32_t>(sndFile.frames());
returnedValue.sampleRate = static_cast<double>(sndFile.samplerate());
SF_INSTRUMENT instrumentInfo;
sndFile.command(SFC_GET_INSTRUMENT, &instrumentInfo, sizeof(instrumentInfo));
@ -27,4 +27,40 @@ std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(
// sndFile.command(SFC_GET_LOG_INFO, buffer, sizeof(buffer)) ;
// DBG(buffer);
return returnedValue;
}
void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames)
{
if (!loadingQueue.try_enqueue({ voice, sample, numFrames }))
DBG("Problem enqueuing a file read for file " << sample);
}
void sfz::FilePool::loadingThread()
{
FileLoadingInformation fileToLoad;
while (true)
{
loadingQueue.wait_dequeue(fileToLoad);
if (fileToLoad.voice == nullptr)
{
DBG("Background thread error: voice is null.");
continue;
}
DBG("Background loading of: " << fileToLoad.sample);
std::filesystem::path file { rootDirectory / fileToLoad.sample };
if (!std::filesystem::exists(file))
{
DBG("Background thread: no file " << fileToLoad.sample << " exists.");
continue;
}
SndfileHandle sndFile ( reinterpret_cast<const char*>(file.c_str()) );
auto fileLoaded = std::make_unique<StereoBuffer<float>>(fileToLoad.numFrames);
auto readBuffer = std::make_unique<Buffer<float>>(fileToLoad.numFrames * 2);
sndFile.readf(readBuffer->data(), fileToLoad.numFrames);
fileLoaded->readInterleaved<SIMDConfig::useSIMD>(readBuffer->data(), fileToLoad.numFrames);
fileToLoad.voice->setFileData(std::move(fileLoaded));
}
}

View file

@ -1,19 +1,26 @@
#pragma once
#include "StereoBuffer.h"
#include "Defaults.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 <thread>
namespace sfz
{
class FilePool
{
public:
FilePool() = default;
FilePool()
: fileLoadingThread(std::thread(&FilePool::loadingThread, this))
{
}
void setRootDirectory(const std::filesystem::path& directory) { rootDirectory = directory; }
size_t getNumPreloadedSamples() { return preloadedData.size(); }
@ -22,11 +29,22 @@ public:
uint32_t end { Default::sampleEndRange.getEnd() };
uint32_t loopBegin { Default::loopRange.getStart() };
uint32_t loopEnd { Default::loopRange.getEnd() };
double sampleRate { config::defaultSampleRate };
std::shared_ptr<StereoBuffer<float>> preloadedData;
};
std::optional<FileInformation> getFileInformation(std::string_view filename);
void enqueueLoading(Voice* voice, std::string_view sample, int numFrames);
private:
std::filesystem::path rootDirectory;
struct FileLoadingInformation
{
Voice* voice;
std::string_view sample;
int numFrames;
};
moodycamel::BlockingReaderWriterQueue<FileLoadingInformation> loadingQueue;
void loadingThread();
std::thread fileLoadingThread;
Buffer<float> tempReadBuffer { config::preloadSize * 2 };
// std::map<std::string_view, std::shared_ptr<StereoBuffer<float>>> preloadedData;
absl::flat_hash_map<std::string_view, std::shared_ptr<StereoBuffer<float>>> preloadedData;

View file

@ -147,6 +147,7 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
region->sampleEnd = std::min(region->sampleEnd, fileInformation->end);
region->loopRange.shrinkIfSmaller(fileInformation->loopBegin, fileInformation->loopEnd);
region->preloadedData = fileInformation->preloadedData;
region->sampleRate = fileInformation->sampleRate;
for (auto note = region->keyRange.getStart(); note <= region->keyRange.getEnd(); note++)
noteActivationLists[note].push_back(*currentRegion);
@ -156,7 +157,7 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
currentRegion++;
}
DBG("Removed " << regions.size() - std::distance(regions.begin(), lastRegion) - 1 << " out of " << regions.size() << " regions.");
regions.resize(std::distance(regions.begin(), lastRegion) + 1);
return parserReturned;

View file

@ -1,10 +1,20 @@
#pragma once
#include "StereoBuffer.h"
#include <atomic>
#include <memory>
namespace sfz
{
class Voice
{
public:
void setFileData(std::unique_ptr<StereoBuffer<float>> file)
{
fileData = std::move(file);
dataReady.store(true);
}
private:
std::atomic<bool> dataReady;
std::unique_ptr<StereoBuffer<float>> fileData;
};
}