@@ -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
567573bool PluginProcessor::isBusesLayoutSupported (BusesLayout const & layouts) const
@@ -629,6 +635,8 @@ void PluginProcessor::processBlockBypassed(AudioBuffer<float>& buffer, MidiBuffe
629635
630636void 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+
13641427void PluginProcessor::updateAllEditorsLNF ()
13651428{
13661429 for (auto const & editor : getEditors ())
0 commit comments