Background work when idle

This commit is contained in:
Jean Pierre Cimalando 2021-03-18 02:17:06 +01:00
parent 520ae553f0
commit 0a63256b65
2 changed files with 43 additions and 37 deletions

View file

@ -37,7 +37,6 @@ static const char* kRingIdOsc = "Osc";
static const char* kMsgIdSetNumVoices = "SetNumVoices"; static const char* kMsgIdSetNumVoices = "SetNumVoices";
static const char* kMsgIdSetOversampling = "SetOversampling"; static const char* kMsgIdSetOversampling = "SetOversampling";
static const char* kMsgIdSetPreloadSize = "SetPreloadSize"; static const char* kMsgIdSetPreloadSize = "SetPreloadSize";
static const char* kMsgIdCheckShouldReload = "CheckShouldReload";
static const char* kMsgIdNotifyPlayState = "NotifyPlayState"; static const char* kMsgIdNotifyPlayState = "NotifyPlayState";
static const char* kMsgIdReceiveMessage = "ReceiveMessage"; static const char* kMsgIdReceiveMessage = "ReceiveMessage";
static const char* kMsgIdNoteEvents = "NoteEvents"; static const char* kMsgIdNoteEvents = "NoteEvents";
@ -204,7 +203,6 @@ tresult PLUGIN_API SfizzVstProcessor::setActive(TBool state)
synth->setSampleRate(processSetup.sampleRate); synth->setSampleRate(processSetup.sampleRate);
synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock); synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock);
_fileChangePeriod = static_cast<uint32>(1.0 * processSetup.sampleRate);
_playStateChangePeriod = static_cast<uint32>(50e-3 * processSetup.sampleRate); _playStateChangePeriod = static_cast<uint32>(50e-3 * processSetup.sampleRate);
startBackgroundWork(); startBackgroundWork();
@ -271,13 +269,6 @@ tresult PLUGIN_API SfizzVstProcessor::process(Vst::ProcessData& data)
synth.renderBlock(outputs, numFrames, numChannels); synth.renderBlock(outputs, numFrames, numChannels);
_fileChangeCounter += numFrames;
if (_fileChangeCounter > _fileChangePeriod) {
_fileChangeCounter %= _fileChangePeriod;
if (writeWorkerMessage(kMsgIdCheckShouldReload, nullptr, 0))
_semaToWorker.post();
}
_playStateChangeCounter += numFrames; _playStateChangeCounter += numFrames;
if (_playStateChangeCounter > _playStateChangePeriod) { if (_playStateChangeCounter > _playStateChangePeriod) {
_playStateChangeCounter %= _playStateChangePeriod; _playStateChangeCounter %= _playStateChangePeriod;
@ -640,19 +631,28 @@ void SfizzVstProcessor::loadSfzFileOrDefault(sfz::Sfizz& synth, const std::strin
void SfizzVstProcessor::doBackgroundWork() void SfizzVstProcessor::doBackgroundWork()
{ {
using Clock = std::chrono::steady_clock;
bool haveDoneIdleWork = false;
Clock::time_point lastIdleWorkTime;
for (;;) { for (;;) {
_semaToWorker.wait(); bool isNotified = _semaToWorker.timed_wait(1000);
if (!_workRunning) if (!_workRunning)
break; break;
RTMessagePtr msg = readWorkerMessage(); const char* id = nullptr;
if (!msg) { RTMessagePtr msg;
fprintf(stderr, "[Sfizz] message synchronization error in worker\n");
std::abort();
}
const char* id = msg->type; if (isNotified) {
msg = readWorkerMessage();
if (!msg) {
fprintf(stderr, "[Sfizz] message synchronization error in worker\n");
std::abort();
}
id = msg->type;
}
if (id == kMsgIdSetNumVoices) { if (id == kMsgIdSetNumVoices) {
int32 value = *msg->payload<int32>(); int32 value = *msg->payload<int32>();
@ -669,23 +669,6 @@ void SfizzVstProcessor::doBackgroundWork()
std::lock_guard<SpinMutex> lock(_processMutex); std::lock_guard<SpinMutex> lock(_processMutex);
_synth->setPreloadSize(value); _synth->setPreloadSize(value);
} }
else if (id == kMsgIdCheckShouldReload) {
if (_synth->shouldReloadFile()) {
fprintf(stderr, "[Sfizz] sfz file has changed, reloading\n");
std::lock_guard<SpinMutex> lock(_processMutex);
loadSfzFileOrDefault(*_synth, _state.sfzFile);
Steinberg::OPtr<Vst::IMessage> reply { allocateMessage() };
reply->setMessageID("LoadedSfz");
reply->getAttributes()->setBinary("File", _state.sfzFile.data(), _state.sfzFile.size());
sendMessage(reply);
}
else if (_synth->shouldReloadScala()) {
fprintf(stderr, "[Sfizz] scala file has changed, reloading\n");
std::lock_guard<SpinMutex> lock(_processMutex);
_synth->loadScalaFile(_state.scalaFile);
}
}
else if (id == kMsgIdNotifyPlayState) { else if (id == kMsgIdNotifyPlayState) {
SfizzPlayState playState = *msg->payload<SfizzPlayState>(); SfizzPlayState playState = *msg->payload<SfizzPlayState>();
Steinberg::OPtr<Vst::IMessage> notification { allocateMessage() }; Steinberg::OPtr<Vst::IMessage> notification { allocateMessage() };
@ -705,6 +688,32 @@ void SfizzVstProcessor::doBackgroundWork()
notification->getAttributes()->setBinary("Events", msg->payload<uint8_t>(), msg->size); notification->getAttributes()->setBinary("Events", msg->payload<uint8_t>(), msg->size);
sendMessage(notification); sendMessage(notification);
} }
Clock::time_point currentTime = Clock::now();
if (!haveDoneIdleWork || currentTime - lastIdleWorkTime > std::chrono::seconds(1)) {
doBackgroundIdle();
haveDoneIdleWork = true;
lastIdleWorkTime = currentTime;
}
}
}
void SfizzVstProcessor::doBackgroundIdle()
{
if (_synth->shouldReloadFile()) {
fprintf(stderr, "[Sfizz] sfz file has changed, reloading\n");
std::lock_guard<SpinMutex> lock(_processMutex);
loadSfzFileOrDefault(*_synth, _state.sfzFile);
Steinberg::OPtr<Vst::IMessage> reply { allocateMessage() };
reply->setMessageID("LoadedSfz");
reply->getAttributes()->setBinary("File", _state.sfzFile.data(), _state.sfzFile.size());
sendMessage(reply);
}
if (_synth->shouldReloadScala()) {
fprintf(stderr, "[Sfizz] scala file has changed, reloading\n");
std::lock_guard<SpinMutex> lock(_processMutex);
_synth->loadScalaFile(_state.scalaFile);
} }
} }

View file

@ -72,10 +72,6 @@ private:
Ring_Buffer _fifoMessageFromUi; Ring_Buffer _fifoMessageFromUi;
SpinMutex _processMutex; SpinMutex _processMutex;
// file modification periodic checker
uint32 _fileChangeCounter = 0;
uint32 _fileChangePeriod = 0;
// state notification periodic timer // state notification periodic timer
uint32 _playStateChangeCounter = 0; uint32 _playStateChangeCounter = 0;
uint32 _playStateChangePeriod = 0; uint32 _playStateChangePeriod = 0;
@ -99,6 +95,7 @@ private:
// worker // worker
void doBackgroundWork(); void doBackgroundWork();
void doBackgroundIdle();
void startBackgroundWork(); void startBackgroundWork();
void stopBackgroundWork(); void stopBackgroundWork();
// writer // writer