Added the background loading thread and the sample rate in the file
This commit is contained in:
parent
2a493873ae
commit
d0264f3416
5 changed files with 73 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue