AronaSlate/Source/AronaCore/Thread/RenderThread.cpp
2024-01-25 11:21:15 +08:00

86 lines
1.8 KiB
C++

#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<int32> 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;
}