Skip to content

Commit 536b222

Browse files
committed
Add backup scheduler for DAW in case audio is bypassed
1 parent 0df4889 commit 536b222

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

Source/PluginProcessor.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,12 @@ void PluginProcessor::prepareToPlay(double const sampleRate, int const samplesPe
562562
limiter.prepare({ sampleRate, static_cast<uint32>(samplesPerBlock), std::max(1u, static_cast<uint32>(maxChannels)) });
563563

564564
smoothedGain.reset(AudioProcessor::getSampleRate(), 0.02);
565+
566+
if(!ProjectInfo::isStandalone) {
567+
backupRunLoopInterval = static_cast<int>((samplesPerBlock / sampleRate) * 4000.0);
568+
backupRunLoopInterval = jmax(32, backupRunLoopInterval);
569+
backupRunLoop.startTimer(backupRunLoopInterval * 32);
570+
}
565571
}
566572

567573
bool PluginProcessor::isBusesLayoutSupported(BusesLayout const& layouts) const
@@ -629,6 +635,8 @@ void PluginProcessor::processBlockBypassed(AudioBuffer<float>& buffer, MidiBuffe
629635

630636
void PluginProcessor::processBlock(AudioBuffer<float>& buffer, MidiBuffer& midiBuffer)
631637
{
638+
isProcessingAudio = true;
639+
632640
ScopedNoDenormals noDenormals;
633641
AudioProcessLoadMeasurer::ScopedTimer cpuTimer(cpuLoadMeasurer, buffer.getNumSamples());
634642

@@ -637,6 +645,13 @@ void PluginProcessor::processBlock(AudioBuffer<float>& buffer, MidiBuffer& midiB
637645
auto midiInputHistory = midiBuffer;
638646

639647
setThis();
648+
649+
if(!ProjectInfo::isStandalone) {
650+
backupLoopLock.enter();
651+
backupRunLoop.stopTimer();
652+
backupLoopLock.exit();
653+
}
654+
640655
sendPlayhead();
641656

642657
for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) {
@@ -724,6 +739,15 @@ void PluginProcessor::processBlock(AudioBuffer<float>& buffer, MidiBuffer& midiB
724739
auto block = dsp::AudioBlock<float>(buffer);
725740
limiter.process(block);
726741
}
742+
743+
// If we miss 4 audio blocks, start the backup scheduler
744+
if(!ProjectInfo::isStandalone) {
745+
backupLoopLock.enter();
746+
backupRunLoop.startTimer(backupRunLoopInterval * 4);
747+
backupLoopLock.exit();
748+
}
749+
750+
isProcessingAudio = false;
727751
}
728752

729753
// only used for standalone, and if blocksize if a multiple of 64
@@ -1361,6 +1385,45 @@ void PluginProcessor::setTheme(String themeToUse, bool const force)
13611385
currentThemeName = themeToUse;
13621386
}
13631387

1388+
void PluginProcessor::runBackupLoop()
1389+
{
1390+
if(ProjectInfo::isStandalone) return;
1391+
1392+
int blocksToProcess = backupRunLoopInterval / (int)((DEFDACBLKSIZE / AudioProcessor::getSampleRate()) * 1000.0);
1393+
if(blocksToProcess < 1)
1394+
{
1395+
blocksToProcess = jmax(1, blocksToProcess); // At least 1 block
1396+
backupRunLoopInterval *= 2; // Increase the interval so we get correct timing
1397+
}
1398+
1399+
if(backupLoopLock.tryEnter()) {
1400+
if(isProcessingAudio)
1401+
{
1402+
backupRunLoop.stopTimer();
1403+
backupLoopLock.exit();
1404+
return;
1405+
}
1406+
1407+
backupRunLoop.startTimer(backupRunLoopInterval);
1408+
backupLoopLock.exit();
1409+
}
1410+
else {
1411+
return;
1412+
}
1413+
1414+
setThis();
1415+
if(audioLock.tryEnter()) {
1416+
sendMessagesFromQueue();
1417+
sendParameters();
1418+
for(int i = 0; i < blocksToProcess; i++) {
1419+
if(isProcessingAudio) break;
1420+
sys_pollgui();
1421+
sched_tick_nodsp();
1422+
}
1423+
audioLock.exit();
1424+
}
1425+
}
1426+
13641427
void PluginProcessor::updateAllEditorsLNF()
13651428
{
13661429
for (auto const& editor : getEditors())

Source/PluginProcessor.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ class PluginProcessor final : public AudioProcessor
154154
void titleChanged() override;
155155

156156
void setTheme(String themeToUse, bool force = false);
157+
158+
void runBackupLoop();
157159

158160
int lastUIWidth = 1000, lastUIHeight = 650;
159161

@@ -274,6 +276,10 @@ class PluginProcessor final : public AudioProcessor
274276
};
275277

276278
HostInfoUpdater hostInfoUpdater;
277-
279+
280+
int backupRunLoopInterval;
281+
TimedCallback backupRunLoop = TimedCallback([this](){ runBackupLoop(); });
282+
CriticalSection backupLoopLock;
283+
std::atomic<bool> isProcessingAudio;
278284
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginProcessor)
279285
};

0 commit comments

Comments
 (0)