#include "RenderThread.h" #include "HAL/PlatformProcess.h" #include "Singleton/MidiSequencer.h" #include "Singleton/MixerList.h" #include "Mixer/MixerTrack.h" #include "PluginHost/PluginHost.h" #include "Singleton/PluginHostList.h" void FInstrumentRenderThread::DoThreadedWork() { PluginHost->Process(FrameNum); --Counter; } FAudioRenderThread::FAudioRenderThread() { BlockSize = 512; Size = BlockSize * 16; IsRunning = true; } bool FAudioRenderThread::Init() { ThreadPool = FQueuedThreadPool::Allocate(); ThreadPool->Create(FPlatformMisc::NumberOfIOWorkerThreadsToSpawn() * 2, 128 * 1024); Buffer.SetCapacity(Size); return true; } uint32 FAudioRenderThread::Run() { FPortAudioAPI& AudioAPI = FPortAudioAPI::Get(); FMixerList& MixerList = FMixerList::Get(); FPluginHostList& PluginHostList = FPluginHostList::Get(); FMidiSequencer& MidiSequencer = FMidiSequencer::Get(); FMixerTrack* MasterTrack = MixerList.GetMaster(); while (IsRunning.load()) { const float Seconds = 1.f / (SampleRate / (BlockSize / 4)); AudioAPI.ProcessMessage(); if (Buffer.Num() >= Size) { FPlatformProcess::Sleep(Seconds); continue; } MixerList.ResetAllTracks(); MidiSequencer.Process(SampleRate, BlockSize); TAtomic LeftTask = PluginHostList.Instruments.Num(); for (FPluginHost* PluginHost : PluginHostList.Instruments) { ThreadPool->AddQueuedWork(new FInstrumentRenderThread(PluginHost, BlockSize, LeftTask)); } while (LeftTask.Load() > 0) { FPlatformProcess::Sleep(Seconds); } MixerList.Process(BlockSize); float** Headers = MasterTrack->Buffer.GetHeaders(); for (int i = 0; i < 2; ++i) Buffer.Push(Headers[i], BlockSize); } return 0; } void FAudioRenderThread::Stop() { IsRunning.store(false); } void FAudioRenderThread::Exit() { ThreadPool->Destroy(); delete ThreadPool; ThreadPool = nullptr; }