Files
AronaSlate/Source/AronaCore/Singleton/PluginHostList.cpp
2024-01-25 11:21:15 +08:00

158 lines
3.3 KiB
C++

#include "PluginHostList.h"
#include "Paths.h"
#include "PluginHost/PluginHost.h"
#include "PortAudioAPI.h"
#include "PluginHost/Sampler.h"
#include "PluginHost/VST2PluginHost.h"
#include "Thread/MainThreadEventList.h"
#include "AudioBuffer/ChannelNode.h"
#include "MixerList.h"
#include "Mixer/MixerTrack.h"
DEFINE_LOG_CATEGORY(LogPluginHostList);
DECLARE_THREAD_MESSAGE(FPortAudioAPI, RegisterInstrument,
FPluginHost* Host;
)
{
FPluginHostList::Get().RegisterInstrument_AudioThread(Args.Host);
}
DECLARE_THREAD_MESSAGE(FMainThreadEventList, OnPluginHostRemoved,
FPluginHost* Host;
)
{
FPluginHostList::Get().OnPluginHostRemoved.Broadcast(Args.Host);
}
DECLARE_THREAD_MESSAGE(FPortAudioAPI, RemovePluginHost,
FPluginHost* Host;
)
{
FPluginHostList::Get().Instruments.RemoveSingle(Args.Host);
FPluginHostList::Get().RemoveSingle(Args.Host);
delete Args.Host;
PUSH_THREAD_EVENT(OnPluginHostRemoved, Args.Host);
FMixerList::Get().BuildProcessNode();
}
DECLARE_THREAD_MESSAGE(FMainThreadEventList, OnInstrumentRegistered,
FPluginHost* Host;
)
{
FPluginHostList::Get().OnInstrumentHostCreated.Broadcast(Args.Host);
}
void FPluginHostList::Init()
{
}
void FPluginHostList::Release()
{
for (FPluginHost* Element : *this)
{
for (FMixerTrack* Track : Element->OwnerTracks)
{
Track->Effects.RemoveSingle(Element);
}
delete Element;
}
Reset();
}
FPluginHost* FPluginHostList::TryLoadPlugin(const FString& Path)
{
const FString& Extension = FPaths::GetExtension(Path);
FPluginHost* Host = nullptr;
if (Extension == "dll")
{
Host = new FVST2PluginHost();
}
if (!Host)
{
UE_LOG(LogPluginHostList, Error, TEXT("加载插件失败 %s: 未知的拓展名 %s"), *Path, *Extension);
return nullptr;
}
if (Host->Load(Path))
{
Add(Host);
}
else
{
delete Host;
Host = nullptr;
}
return Host;
}
FSampler* FPluginHostList::TryLoadSampler(const FString& SampleFilePath)
{
FSampler* Sampler = new FSampler();
if (Sampler->Load(SampleFilePath))
{
Add(Sampler);
RegisterInstrument(Sampler);
}
else
{
delete Sampler;
Sampler = nullptr;
}
return Sampler;
}
void FPluginHostList::RegisterInstrument(FPluginHost* Host)
{
if (Host)
PUSH_THREAD_EVENT(RegisterInstrument, Host);
}
void FPluginHostList::RemovePluginHost(FPluginHost* Host)
{
if (Host)
PUSH_THREAD_EVENT(RemovePluginHost, Host);
}
void FPluginHostList::RemoveInstrument(FPluginHost* Host)
{
if (!Host)
return;
for (FMixerTrack* OwnerTrack : Host->OwnerTracks)
{
FMixerList::Get().RemoveTrack(OwnerTrack);
}
Host->OwnerTracks.Reset();
PUSH_THREAD_EVENT(RemovePluginHost, Host);
}
void FPluginHostList::Process(int32 NumSamples)
{
for (FPluginHost* Instrument : Instruments)
{
Instrument->Process(NumSamples);
}
}
void FPluginHostList::StopAllMidiOn()
{
for (FPluginHost* Instrument : Instruments)
{
Instrument->IncomingMidi.addEvent(FMidiMessage::allNotesOff(1));
}
}
void FPluginHostList::RegisterInstrument_AudioThread(FPluginHost* Host)
{
FInstrumentMixerTrack* MixerTrack = FMixerList::Get().CreateInstrumentTrack(Host);
Host->ChannelInterface->SetInputChannel(MixerTrack->GetChannelInterface()->OutputChannelNodes);
Host->ChannelInterface->SetOutputChannel(MixerTrack->GetChannelInterface()->OutputChannelNodes);
Host->OwnerTracks.Add(MixerTrack);
Instruments.Add(Host);
PUSH_THREAD_EVENT(OnInstrumentRegistered, Host);
}