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