Introduced the concept of AudioResourceMeta object and applied it to audio resource resolvers

This commit is contained in:
vpereverzev 2021-08-31 16:49:58 +02:00
parent 29c97df411
commit 27f03de912
24 changed files with 235 additions and 127 deletions

View file

@ -25,6 +25,7 @@
#include <variant>
#include <memory>
#include <set>
#include <string>
#include "midi/miditypes.h"
@ -53,31 +54,87 @@ using MixerChannelId = int32_t;
using AudioSourceName = std::string;
using AudioResourceId = std::string;
using AudioResourceIdList = std::vector<AudioResourceId>;
using AudioResourceVendor = std::string;
enum class AudioResourceType {
Undefined = -1,
FluidSoundfont,
VstPlugin
};
struct AudioResourceMeta {
AudioResourceId id;
AudioResourceType type = AudioResourceType::Undefined;
AudioResourceVendor vendor;
bool hasNativeEditorSupport = false;
bool isValid() const
{
return !id.empty() && !vendor.empty();
}
bool operator==(const AudioResourceMeta& other) const
{
return id == other.id
&& vendor == other.vendor
&& hasNativeEditorSupport == other.hasNativeEditorSupport;
}
};
using AudioResourceMetaList = std::vector<AudioResourceMeta>;
using FxProcessorId = std::string;
using FxProcessorIdList = std::vector<FxProcessorId>;
enum class AudioFxType {
Undefined = -1,
Vst
VstFx
};
enum class AudioFxCategory {
Undefined = -1,
FxEqualizer,
FxAnalyzer,
FxDelay,
FxDistortion,
FxDynamics,
FxFilter,
FxGenerator,
FxMastering,
FxModulation,
FxPitchShift,
FxRestoration,
FxReverb,
FxSurround,
FxTools
};
using AudioFxCategories = std::set<AudioFxCategory>;
struct AudioFxParams {
AudioFxType type = AudioFxType::Undefined;
AudioResourceId resourceId;
AudioFxType type() const
{
switch (resourceMeta.type) {
case AudioResourceType::VstPlugin: return AudioFxType::VstFx;
default: return AudioFxType::Undefined;
}
}
AudioFxCategories categories;
AudioResourceMeta resourceMeta;
bool active = false;
bool operator ==(const AudioFxParams& other) const
{
return type == other.type
&& resourceId == other.resourceId
&& active == other.active;
return resourceMeta == other.resourceMeta
&& active == other.active
&& categories == other.categories;
}
bool isValid() const
{
return type != AudioFxType::Undefined
&& !resourceId.empty();
return resourceMeta.isValid();
}
};
@ -105,19 +162,27 @@ enum class AudioSourceType {
};
struct AudioSourceParams {
AudioSourceType type = AudioSourceType::Undefined;
AudioResourceId resourceId;
AudioSourceType type() const
{
switch (resourceMeta.type) {
case AudioResourceType::FluidSoundfont: return AudioSourceType::Fluid;
case AudioResourceType::VstPlugin: return AudioSourceType::Vsti;
default: return AudioSourceType::Undefined;
}
}
AudioResourceMeta resourceMeta;
bool isValid() const
{
return type != AudioSourceType::Undefined
&& !resourceId.empty();
return type() != AudioSourceType::Undefined
&& resourceMeta.isValid();
}
bool operator ==(const AudioSourceParams& other) const
{
return type == other.type
&& resourceId == other.resourceId;
return type() == other.type()
&& resourceMeta == other.resourceMeta;
}
};

View file

@ -44,7 +44,7 @@ public:
virtual void setMasterOutputParams(const AudioOutputParams& params) = 0;
virtual async::Channel<AudioOutputParams> masterOutputParamsChanged() const = 0;
virtual async::Promise<AudioResourceIdList> availableOutputResources(const AudioFxType type) const = 0;
virtual async::Promise<AudioResourceMetaList> availableOutputResources() const = 0;
virtual async::Promise<AudioSignalChanges> signalChanges(const TrackSequenceId sequenceId, const TrackId trackId) const = 0;
virtual async::Promise<AudioSignalChanges> masterSignalChanges() const = 0;

View file

@ -46,14 +46,14 @@ public:
virtual std::vector<IFxProcessorPtr> resolveFxList(const audio::TrackId trackId, const std::vector<AudioFxParams>& fxParams) = 0;
virtual std::vector<IFxProcessorPtr> resolveMasterFxList(const std::vector<AudioFxParams>& fxParams) = 0;
virtual AudioResourceIdList resolveResources() const = 0;
virtual AudioResourceMetaList resolveResources() const = 0;
virtual void refresh() = 0;
};
using IResolverPtr = std::shared_ptr<IResolver>;
virtual std::vector<IFxProcessorPtr> resolveMasterFxList(const AudioFxParamsMap& params) = 0;
virtual std::vector<IFxProcessorPtr> resolveFxList(const TrackId trackId, const AudioFxParamsMap& params) = 0;
virtual AudioResourceIdList resolveAvailableResources(const AudioFxType type) const = 0;
virtual AudioResourceMetaList resolveAvailableResources() const = 0;
virtual void registerResolver(const AudioFxType type, IResolverPtr resolver) = 0;
};

View file

@ -47,6 +47,7 @@ static const Settings::Key USER_SOUNDFONTS_PATH("midi", "application/paths/mySou
static const Settings::Key SHOW_CONTROLS_IN_MIXER("midi", "io/midi/showControlsInMixer");
static const AudioResourceId DEFAULT_SOUND_FONT_NAME = "MuseScore_General"; // "GeneralUser GS v1.471.sf2"; // "MuseScore_General.sf3";
static const AudioResourceMeta DEFAULT_AUDIO_RESOURCE_META = { DEFAULT_SOUND_FONT_NAME, AudioResourceType::FluidSoundfont, "Fluid", false /*hasNativeEditor*/};
void AudioConfiguration::init()
{
@ -124,7 +125,7 @@ void AudioConfiguration::setIsShowControlsInMixer(bool show)
AudioInputParams AudioConfiguration::defaultAudioInputParams() const
{
return { AudioSourceType::Fluid, DEFAULT_SOUND_FONT_NAME };
return { DEFAULT_AUDIO_RESOURCE_META };
}
const SynthesizerState& AudioConfiguration::defaultSynthesizerState() const

View file

@ -80,7 +80,7 @@ std::vector<IFxProcessorPtr> FxResolver::resolveFxList(const TrackId trackId, co
return result;
}
AudioResourceIdList FxResolver::resolveAvailableResources(const AudioFxType type) const
AudioResourceMetaList FxResolver::resolveAvailableResources() const
{
ONLY_AUDIO_WORKER_THREAD;
@ -88,13 +88,14 @@ AudioResourceIdList FxResolver::resolveAvailableResources(const AudioFxType type
std::lock_guard lock(m_mutex);
auto search = m_resolvers.find(type);
AudioResourceMetaList result;
if (search == m_resolvers.end()) {
return {};
for (const auto& pair : m_resolvers) {
const AudioResourceMetaList& resolvedResources = pair.second->resolveResources();
result.insert(result.end(), resolvedResources.begin(), resolvedResources.end());
}
return search->second->resolveResources();
return result;
}
void FxResolver::registerResolver(const AudioFxType type, IResolverPtr resolver)

View file

@ -34,7 +34,7 @@ class FxResolver : public IFxResolver
public:
std::vector<IFxProcessorPtr> resolveMasterFxList(const AudioFxParamsMap& fxParams) override;
std::vector<IFxProcessorPtr> resolveFxList(const TrackId trackId, const AudioFxParamsMap& fxParams) override;
AudioResourceIdList resolveAvailableResources(const AudioFxType type) const override;
AudioResourceMetaList resolveAvailableResources() const override;
void registerResolver(const AudioFxType type, IResolverPtr resolver) override;
private:

View file

@ -35,6 +35,8 @@ static const std::map<SoundFontFormat, std::string> FLUID_SF_FILE_EXTENSIONS =
{ SoundFontFormat::SF3, "*.sf3" }
};
static const AudioResourceVendor FLUID_VENDOR_NAME = "Fluid";
FluidResolver::FluidResolver(const io::paths& soundFontDirs, async::Channel<io::paths> sfDirsChanges)
{
ONLY_AUDIO_WORKER_THREAD;
@ -67,14 +69,21 @@ ISynthesizerPtr FluidResolver::resolveSynth(const TrackId /*trackId*/, const Aud
return synth;
}
AudioResourceIdList FluidResolver::resolveResources() const
AudioResourceMetaList FluidResolver::resolveResources() const
{
ONLY_AUDIO_WORKER_THREAD;
AudioResourceIdList result(m_resourcesCache.size());
AudioResourceMetaList result;
result.reserve(m_resourcesCache.size());
for (const auto& pair : m_resourcesCache) {
result.push_back(pair.first);
AudioResourceMeta meta;
meta.id = pair.first;
meta.type = AudioResourceType::FluidSoundfont;
meta.vendor = FLUID_VENDOR_NAME;
meta.hasNativeEditorSupport = false;
result.push_back(std::move(meta));
}
return result;

View file

@ -41,7 +41,7 @@ public:
explicit FluidResolver(const io::paths& soundFontDirs, async::Channel<io::paths> sfDirsChanges);
ISynthesizerPtr resolveSynth(const audio::TrackId trackId, const audio::AudioResourceId& resourceId) const override;
AudioResourceIdList resolveResources() const override;
audio::AudioResourceMetaList resolveResources() const override;
void refresh() override;

View file

@ -57,14 +57,14 @@ ISynthesizerPtr SynthResolver::resolveSynth(const TrackId trackId, const AudioIn
std::lock_guard lock(m_mutex);
auto search = m_resolvers.find(params.type);
auto search = m_resolvers.find(params.type());
if (search == m_resolvers.end()) {
return nullptr;
}
const IResolverPtr& resolver = search->second;
return resolver->resolveSynth(trackId, params.resourceId);
return resolver->resolveSynth(trackId, params.resourceMeta.id);
}
ISynthesizerPtr SynthResolver::resolveDefaultSynth(const TrackId trackId) const
@ -74,7 +74,7 @@ ISynthesizerPtr SynthResolver::resolveDefaultSynth(const TrackId trackId) const
return resolveSynth(trackId, m_defaultInputParams);
}
AudioResourceIdList SynthResolver::resolveAvailableResources(const AudioSourceType type) const
AudioResourceMetaList SynthResolver::resolveAvailableResources() const
{
ONLY_AUDIO_WORKER_THREAD;
@ -82,14 +82,14 @@ AudioResourceIdList SynthResolver::resolveAvailableResources(const AudioSourceTy
std::lock_guard lock(m_mutex);
auto search = m_resolvers.find(type);
AudioResourceMetaList result;
if (search != m_resolvers.end()) {
return search->second->resolveResources();
for (const auto& pair : m_resolvers) {
const AudioResourceMetaList& resolvedResources = pair.second->resolveResources();
result.insert(result.end(), resolvedResources.begin(), resolvedResources.end());
}
LOGE() << "Unable to find a resolver for type: " << static_cast<int>(type);
return {};
return result;
}
void SynthResolver::registerResolver(const AudioSourceType type, IResolverPtr resolver)

View file

@ -37,7 +37,7 @@ public:
ISynthesizerPtr resolveSynth(const TrackId trackId, const AudioInputParams& params) const override;
ISynthesizerPtr resolveDefaultSynth(const TrackId trackId) const override;
AudioResourceIdList resolveAvailableResources(const AudioSourceType type) const override;
AudioResourceMetaList resolveAvailableResources() const override;
void registerResolver(const AudioSourceType type, IResolverPtr resolver) override;

View file

@ -119,17 +119,13 @@ Channel<AudioOutputParams> AudioOutputHandler::masterOutputParamsChanged() const
return m_masterOutputParamsChanged;
}
Promise<AudioResourceIdList> AudioOutputHandler::availableOutputResources(const AudioFxType type) const
Promise<AudioResourceMetaList> AudioOutputHandler::availableOutputResources() const
{
return Promise<AudioResourceIdList>([this, type](Promise<AudioResourceIdList>::Resolve resolve,
Promise<AudioResourceIdList>::Reject reject) {
return Promise<AudioResourceMetaList>([this](Promise<AudioResourceMetaList>::Resolve resolve,
Promise<AudioResourceMetaList>::Reject /*reject*/) {
ONLY_AUDIO_WORKER_THREAD;
if (type == AudioFxType::Undefined) {
reject(static_cast<int>(Err::InvalidFxParams), "unable to get resources for undefined fx type");
}
resolve(fxResolver()->resolveAvailableResources(type));
resolve(fxResolver()->resolveAvailableResources());
}, AudioThread::ID);
}
@ -143,6 +139,7 @@ Promise<AudioSignalChanges> AudioOutputHandler::signalChanges(const TrackSequenc
if (!s) {
reject(static_cast<int>(Err::InvalidSequenceId), "invalid sequence id");
return;
}
resolve({ s->audioIO()->signalAmplitudeChanged(trackId), s->audioIO()->volumePressureChanged(trackId) });

View file

@ -47,7 +47,7 @@ public:
void setMasterOutputParams(const AudioOutputParams& params) override;
async::Channel<AudioOutputParams> masterOutputParamsChanged() const override;
async::Promise<AudioResourceIdList> availableOutputResources(const AudioFxType type) const override;
async::Promise<AudioResourceMetaList> availableOutputResources() const override;
async::Promise<AudioSignalChanges> signalChanges(const TrackSequenceId sequenceId, const TrackId trackId) const override;
async::Promise<AudioSignalChanges> masterSignalChanges() const override;

View file

@ -150,17 +150,13 @@ Channel<TrackSequenceId, TrackId> TracksHandler::trackRemoved() const
return m_trackRemoved;
}
Promise<AudioResourceIdList> TracksHandler::availableInputResources(const AudioSourceType type) const
Promise<AudioResourceMetaList> TracksHandler::availableInputResources() const
{
return Promise<AudioResourceIdList>([this, type](Promise<AudioResourceIdList>::Resolve resolve,
Promise<AudioResourceIdList>::Reject reject) {
return Promise<AudioResourceMetaList>([this](Promise<AudioResourceMetaList>::Resolve resolve,
Promise<AudioResourceMetaList>::Reject /*reject*/) {
ONLY_AUDIO_WORKER_THREAD;
if (type == AudioSourceType::Undefined) {
reject(static_cast<int>(Err::InvalidAudioSourceParams), "unable to get resources for undefined audio source type");
}
resolve(resolver()->resolveAvailableResources(type));
resolve(resolver()->resolveAvailableResources());
}, AudioThread::ID);
}

View file

@ -39,6 +39,7 @@ public:
~TracksHandler();
async::Promise<TrackIdList> trackIdList(const TrackSequenceId sequenceId) const override;
async::Promise<TrackName> trackName(const TrackSequenceId sequenceId, const TrackId trackId) const override;
async::Promise<TrackId> addTrack(const TrackSequenceId sequenceId, const std::string& trackName, midi::MidiData&& playbackData,
AudioParams&& params) override;
async::Promise<TrackId> addTrack(const TrackSequenceId sequenceId, const std::string& trackName, io::Device* playbackData,
@ -49,7 +50,7 @@ public:
async::Channel<TrackSequenceId, TrackId> trackAdded() const override;
async::Channel<TrackSequenceId, TrackId> trackRemoved() const override;
async::Promise<AudioResourceIdList> availableInputResources(const AudioSourceType type) const override;
async::Promise<AudioResourceMetaList> availableInputResources() const override;
async::Promise<AudioInputParams> inputParams(const TrackSequenceId sequenceId, const TrackId trackId) const override;
void setInputParams(const TrackSequenceId sequenceId, const TrackId trackId, const AudioInputParams& params) override;

View file

@ -49,12 +49,16 @@ void VstPluginListModelExample::load()
<< "error text: " << text;
});
playback()->tracks()->availableInputResources(audio::AudioSourceType::Vsti)
.onResolve(this, [this](AudioResourceIdList idList) {
playback()->tracks()->availableInputResources()
.onResolve(this, [this](AudioResourceMetaList resourceList) {
QVariantList list;
for (const AudioResourceId& id : idList) {
QVariantMap item = { { "value", QString::fromStdString(id) } };
for (const auto& meta : resourceList) {
if (meta.type != AudioResourceType::VstPlugin) {
continue;
}
QVariantMap item = { { "value", QString::fromStdString(meta.id) } };
list << item;
}
setAvailableSynthResources(list);
@ -65,12 +69,12 @@ void VstPluginListModelExample::load()
<< "error text: " << text;
});
playback()->audioOutput()->availableOutputResources(audio::AudioFxType::Vst)
.onResolve(this, [this](AudioResourceIdList idList) {
playback()->audioOutput()->availableOutputResources()
.onResolve(this, [this](AudioResourceMetaList resources) {
QVariantList list;
for (const AudioResourceId& id : idList) {
QVariantMap item = { { "value", QString::fromStdString(id) } };
for (const auto& meta : resources) {
QVariantMap item = { { "value", QString::fromStdString(meta.id) } };
list << item;
}
setAvailableFxResources(list);
@ -209,8 +213,7 @@ const QString& VstPluginListModelExample::currentSynthResource() const
void VstPluginListModelExample::applyNewInputParams()
{
AudioInputParams inputParams;
inputParams.type = AudioSourceType::Vsti;
inputParams.resourceId = m_currentSynthResource.toStdString();
inputParams.resourceMeta.id = m_currentSynthResource.toStdString();
playback()->tracks()->setInputParams(m_currentSequenceId, m_currentTrackId, inputParams);
}
@ -218,11 +221,10 @@ void VstPluginListModelExample::applyNewInputParams()
void VstPluginListModelExample::applyNewOutputParams()
{
AudioFxParams fxParams;
fxParams.type = AudioFxType::Vst;
fxParams.resourceId = m_currentFxResource.toStdString();
fxParams.resourceMeta.id = m_currentFxResource.toStdString();
AudioOutputParams outputParams;
outputParams.fxParams.emplace(AudioFxType::Vst, std::vector<AudioFxParams>({ fxParams }));
outputParams.fxParams.emplace(AudioFxType::VstFx, std::vector<AudioFxParams>({ fxParams }));
playback()->audioOutput()->setOutputParams(m_currentSequenceId, m_currentTrackId, outputParams);
}

View file

@ -33,12 +33,12 @@ VstFxProcessor::VstFxProcessor(VstPluginPtr&& pluginPtr)
void VstFxProcessor::init()
{
m_vstAudioClient->init(m_pluginPtr);
m_vstAudioClient->init(VstPluginType::Fx, m_pluginPtr);
}
AudioFxType VstFxProcessor::type() const
{
return audio::AudioFxType::Vst;
return audio::AudioFxType::VstFx;
}
void VstFxProcessor::setSampleRate(unsigned int sampleRate)

View file

@ -35,18 +35,12 @@ std::vector<IFxProcessorPtr> VstFxResolver::resolveFxList(const audio::TrackId t
return {};
}
AudioResourceIdList newResourcesidList;
for (const auto& param : fxParams) {
newResourcesidList.emplace_back(param.resourceId);
}
FxMap& fxMap = m_tracksFxMap[trackId];
updateTrackFxMap(fxMap, trackId, newResourcesidList);
updateTrackFxMap(fxMap, trackId, fxParams);
std::vector<IFxProcessorPtr> result;
for (const auto& pair : m_masterFxMap) {
for (const auto& pair : fxMap) {
result.emplace_back(pair.second);
}
@ -60,13 +54,7 @@ std::vector<IFxProcessorPtr> VstFxResolver::resolveMasterFxList(const std::vecto
return {};
}
AudioResourceIdList newResourcesidList;
for (const auto& param : fxParams) {
newResourcesidList.emplace_back(param.resourceId);
}
updateMasterFxMap(newResourcesidList);
updateMasterFxMap(fxParams);
std::vector<IFxProcessorPtr> result;
@ -77,9 +65,9 @@ std::vector<IFxProcessorPtr> VstFxResolver::resolveMasterFxList(const std::vecto
return result;
}
AudioResourceIdList VstFxResolver::resolveResources() const
AudioResourceMetaList VstFxResolver::resolveResources() const
{
return pluginModulesRepo()->moduleIdList(VstPluginType::Fx);
return pluginModulesRepo()->fxModulesMeta();
}
void VstFxResolver::refresh()
@ -121,15 +109,20 @@ VstFxPtr VstFxResolver::createTrackFx(const audio::TrackId trackId, const audio:
return fx;
}
void VstFxResolver::updateTrackFxMap(FxMap& fxMap, const audio::TrackId trackId, const audio::AudioResourceIdList& newResourceIdList)
void VstFxResolver::updateTrackFxMap(FxMap& fxMap, const audio::TrackId trackId, const std::vector<AudioFxParams>& fxParams)
{
AudioResourceIdList currentResourceIdList;
for (const auto& pair : fxMap) {
currentResourceIdList.emplace_back(pair.first);
}
AudioResourceIdList newResourcesidList;
for (const auto& param : fxParams) {
newResourcesidList.emplace_back(param.resourceMeta.id);
}
audio::AudioResourceIdList idListToRemove;
fxListToRemove(newResourceIdList, currentResourceIdList, idListToRemove);
fxListToRemove(newResourcesidList, currentResourceIdList, idListToRemove);
for (const auto& idToRemove : idListToRemove) {
pluginsRegister()->unregisterFxPlugin(trackId, idToRemove);
@ -137,22 +130,32 @@ void VstFxResolver::updateTrackFxMap(FxMap& fxMap, const audio::TrackId trackId,
}
audio::AudioResourceIdList idListToCreate;
fxListToCreate(newResourceIdList, currentResourceIdList, idListToCreate);
fxListToCreate(newResourcesidList, currentResourceIdList, idListToCreate);
for (const auto& idToCreate : idListToCreate) {
fxMap.emplace(idToCreate, createTrackFx(trackId, idToCreate));
}
for (const auto& param : fxParams) {
VstFxPtr& fxPtr = fxMap[param.resourceMeta.id];
fxPtr->setActive(param.active);
}
}
void VstFxResolver::updateMasterFxMap(const audio::AudioResourceIdList& newResourceIdList)
void VstFxResolver::updateMasterFxMap(const std::vector<AudioFxParams>& fxParams)
{
AudioResourceIdList currentResourceIdList;
for (const auto& pair : m_masterFxMap) {
currentResourceIdList.emplace_back(pair.first);
}
AudioResourceIdList newResourcesidList;
for (const auto& param : fxParams) {
newResourcesidList.emplace_back(param.resourceMeta.id);
}
audio::AudioResourceIdList idListToRemove;
fxListToRemove(newResourceIdList, currentResourceIdList, idListToRemove);
fxListToRemove(newResourcesidList, currentResourceIdList, idListToRemove);
for (const auto& idToRemove : idListToRemove) {
pluginsRegister()->unregisterMasterFxPlugin(idToRemove);
@ -160,11 +163,16 @@ void VstFxResolver::updateMasterFxMap(const audio::AudioResourceIdList& newResou
}
audio::AudioResourceIdList idListToCreate;
fxListToCreate(newResourceIdList, currentResourceIdList, idListToCreate);
fxListToCreate(newResourcesidList, currentResourceIdList, idListToCreate);
for (const auto& idToCreate : idListToCreate) {
m_masterFxMap.emplace(idToCreate, createMasterFx(idToCreate));
}
for (const auto& param : fxParams) {
VstFxPtr& fxPtr = m_masterFxMap[param.resourceMeta.id];
fxPtr->setActive(param.active);
}
}
void VstFxResolver::fxListToRemove(const AudioResourceIdList& currentResourceIdList,

View file

@ -47,7 +47,7 @@ public:
std::vector<audio::IFxProcessorPtr> resolveFxList(const audio::TrackId trackId,
const std::vector<audio::AudioFxParams>& fxParams) override;
std::vector<audio::IFxProcessorPtr> resolveMasterFxList(const std::vector<audio::AudioFxParams>& fxParams) override;
audio::AudioResourceIdList resolveResources() const override;
audio::AudioResourceMetaList resolveResources() const override;
void refresh() override;
private:
@ -56,8 +56,8 @@ private:
VstFxPtr createMasterFx(const audio::AudioResourceId& resourceId) const;
VstFxPtr createTrackFx(const audio::TrackId trackId, const audio::AudioResourceId& resourceId) const;
void updateMasterFxMap(const audio::AudioResourceIdList& newResourceIdList);
void updateTrackFxMap(FxMap& fxMap, const audio::TrackId trackId, const audio::AudioResourceIdList& newResourceIdList);
void updateMasterFxMap(const std::vector<audio::AudioFxParams>& fxParams);
void updateTrackFxMap(FxMap& fxMap, const audio::TrackId trackId, const std::vector<audio::AudioFxParams>& fxParams);
void fxListToRemove(const audio::AudioResourceIdList& currentResourceIdList, const audio::AudioResourceIdList& newResourceIdList,
audio::AudioResourceIdList& resultList);

View file

@ -67,7 +67,7 @@ VstSynthPtr VstiResolver::createSynth(const audio::TrackId trackId, const audio:
return synth;
}
AudioResourceIdList VstiResolver::resolveResources() const
AudioResourceMetaList VstiResolver::resolveResources() const
{
return pluginModulesRepo()->moduleIdList(VstPluginType::Instrument);
return pluginModulesRepo()->instrumentModulesMeta();
}

View file

@ -39,7 +39,7 @@ class VstiResolver : public audio::synth::ISynthResolver::IResolver
INJECT(vst, IVstPluginsRegister, pluginsRegister)
public:
audio::synth::ISynthesizerPtr resolveSynth(const audio::TrackId trackId, const audio::AudioResourceId& resourceId) const override;
audio::AudioResourceIdList resolveResources() const override;
audio::AudioResourceMetaList resolveResources() const override;
void refresh() override;
private:

View file

@ -65,36 +65,22 @@ PluginModulePtr VstModulesRepository::pluginModule(const audio::AudioResourceId&
return nullptr;
}
audio::AudioResourceIdList VstModulesRepository::moduleIdList(const VstPluginType& type) const
audio::AudioResourceMetaList VstModulesRepository::instrumentModulesMeta() const
{
ONLY_AUDIO_THREAD(threadSecurer);
std::lock_guard lock(m_mutex);
audio::AudioResourceIdList result;
return modulesMetaList(VstPluginType::Instrument);
}
if (type == VstPluginType::Undefined) {
return result;
}
audio::AudioResourceMetaList VstModulesRepository::fxModulesMeta() const
{
ONLY_AUDIO_THREAD(threadSecurer);
for (const auto& pair : m_modules) {
PluginModulePtr module = pair.second;
std::lock_guard lock(m_mutex);
const auto& factory = module->getFactory();
for (auto& classInfo : factory.classInfos()) {
if (classInfo.category() != kVstAudioEffectClass) {
continue;
}
std::string subCategoriesStr = classInfo.subCategoriesString();
if (subCategoriesStr.find(PLUGIN_TYPE_MAP.at(type)) != std::string::npos) {
result.emplace_back(pair.first);
}
}
}
return result;
return modulesMetaList(VstPluginType::Fx);
}
void VstModulesRepository::refresh()
@ -128,6 +114,45 @@ void VstModulesRepository::addModule(const io::path& path)
m_modules.emplace(io::basename(path).toStdString(), module);
}
audio::AudioResourceMetaList VstModulesRepository::modulesMetaList(const VstPluginType& type) const
{
audio::AudioResourceMetaList result;
static auto hasNativeEditorSupport = []() {
#ifdef Q_OS_LINUX
//!Note Host applications on Linux should provide their own event loop via VST3 API,
//! otherwise it'll be impossible to launch native VST editor views
return false;
#else
return true;
#endif
};
for (const auto& pair : m_modules) {
PluginModulePtr module = pair.second;
const auto& factory = module->getFactory();
for (auto& classInfo : factory.classInfos()) {
if (classInfo.category() != kVstAudioEffectClass) {
continue;
}
std::string subCategoriesStr = classInfo.subCategoriesString();
if (subCategoriesStr.find(PLUGIN_TYPE_MAP.at(type)) != std::string::npos) {
audio::AudioResourceMeta meta;
meta.id = pair.first;
meta.type = audio::AudioResourceType::VstPlugin;
meta.vendor = factory.info().vendor();
meta.hasNativeEditorSupport = hasNativeEditorSupport();
result.emplace_back(std::move(meta));
break;
}
}
}
return result;
}
RetVal<io::paths> VstModulesRepository::pluginPathsFromCustomLocation(const io::path& customPath) const
{
RetVal<io::paths> pluginPaths = fileSystem()->scanFiles(customPath, QStringList(QString::fromStdString(VST3_PACKAGE_EXTENSION)));

View file

@ -48,11 +48,14 @@ public:
void init();
PluginModulePtr pluginModule(const audio::AudioResourceId& resourceId) const override;
audio::AudioResourceIdList moduleIdList(const VstPluginType& type) const override;
audio::AudioResourceMetaList instrumentModulesMeta() const override;
audio::AudioResourceMetaList fxModulesMeta() const override;
void refresh() override;
private:
void addModule(const io::path& path);
audio::AudioResourceMetaList modulesMetaList(const VstPluginType& type) const;
RetVal<io::paths> pluginPathsFromCustomLocation(const io::path& customPath) const;
PluginModule::PathList pluginPathsFromDefaultLocation() const;

View file

@ -37,7 +37,8 @@ public:
virtual ~IVstModulesRepository() = default;
virtual PluginModulePtr pluginModule(const audio::AudioResourceId& resourceId) const = 0;
virtual audio::AudioResourceIdList moduleIdList(const VstPluginType& type) const = 0;
virtual audio::AudioResourceMetaList instrumentModulesMeta() const = 0;
virtual audio::AudioResourceMetaList fxModulesMeta() const = 0;
virtual void refresh() = 0;
};
}

View file

@ -74,8 +74,7 @@ void ProjectAudioSettings::makeDefault()
AudioInputParams ProjectAudioSettings::inputParamsFromJson(const QJsonObject& object) const
{
AudioInputParams result;
result.type = sourceTypeFromString(object.value("type").toString());
result.resourceId = object.value("resourceId").toString().toStdString();
result.resourceMeta.id = object.value("resourceId").toString().toStdString();
return result;
}
@ -93,8 +92,8 @@ AudioOutputParams ProjectAudioSettings::outputParamsFromJson(const QJsonObject&
QJsonObject ProjectAudioSettings::inputParamsToJson(const audio::AudioInputParams& params) const
{
QJsonObject result;
result.insert("type", sourceTypeToString(params.type));
result.insert("resourceId", QString::fromStdString(params.resourceId));
result.insert("type", sourceTypeToString(params.type()));
result.insert("resourceId", QString::fromStdString(params.resourceMeta.id));
return result;
}