Line data Source code
1 : #include "outputresourceitem.h"
2 :
3 : #include <QList>
4 :
5 : #include "audio/common/audioutils.h"
6 : #include "vst/vstpluginattrs.h"
7 :
8 : #include "log.h"
9 : #include "translation.h"
10 : #include "stringutils.h"
11 :
12 : using namespace mu::playback;
13 : using namespace muse;
14 : using namespace muse::audio;
15 :
16 0 : static const QString& NO_FX_MENU_ITEM_ID()
17 : {
18 0 : static std::string id = muse::trc("playback", "No effect");
19 0 : static QString resultStr = QString::fromStdString(id);
20 0 : return resultStr;
21 : }
22 :
23 : static const QString GET_MORE_EFFECTS("getMoreEffects");
24 :
25 0 : OutputResourceItem::OutputResourceItem(QObject* parent, const audio::AudioFxParams& params)
26 : : AbstractAudioResourceItem(parent),
27 0 : m_currentFxParams(params)
28 : {
29 0 : }
30 :
31 0 : void OutputResourceItem::requestAvailableResources()
32 : {
33 0 : playback()->availableOutputResources()
34 0 : .onResolve(this, [this](const AudioResourceMetaList& availableFxResources) {
35 0 : updateAvailableFxVendorsMap(availableFxResources);
36 :
37 0 : QVariantList result;
38 :
39 0 : if (!isBlank()) {
40 0 : const QString& currentResourceId = QString::fromStdString(m_currentFxParams.resourceMeta.id);
41 0 : result << buildMenuItem(currentResourceId,
42 : currentResourceId,
43 : /*checked*/ true,
44 0 : /*subItems*/ QVariantList(),
45 0 : /*includeInFilteredLists*/ false);
46 :
47 0 : result << buildSeparator();
48 0 : }
49 :
50 : // add "no fx" item
51 0 : result << buildMenuItem(NO_FX_MENU_ITEM_ID(),
52 : NO_FX_MENU_ITEM_ID(),
53 0 : m_currentFxParams.resourceMeta.id.empty(),
54 0 : /*subItems*/ QVariantList(),
55 0 : /*includeInFilteredLists*/ false);
56 :
57 0 : if (!m_fxByVendorMap.empty()) {
58 0 : result << buildSeparator();
59 : }
60 :
61 0 : for (const auto& pair : m_fxByVendorMap) {
62 0 : const QString& vendor = QString::fromStdString(pair.first);
63 :
64 0 : QVariantList subItems;
65 :
66 0 : for (const AudioResourceMeta& fxResourceMeta : pair.second) {
67 0 : const QString& resourceId = QString::fromStdString(fxResourceMeta.id);
68 0 : subItems << buildMenuItem(resourceId,
69 : resourceId,
70 0 : m_currentFxParams.resourceMeta.id == fxResourceMeta.id);
71 0 : }
72 :
73 0 : result << buildMenuItem(vendor,
74 : vendor,
75 0 : m_currentFxParams.resourceMeta.vendor == pair.first,
76 : subItems,
77 : /*includeInFilteredLists*/ false,
78 0 : /*isFilterCategory*/ true);
79 0 : }
80 :
81 0 : result << buildSeparator();
82 0 : QVariantMap getMore = buildExternalLinkMenuItem(GET_MORE_EFFECTS, muse::qtrc("playback", "Get more effects"));
83 0 : getMore["alwaysAppend"] = true; // Always add this to the end of our lists, ignoring filters
84 0 : result << getMore;
85 :
86 0 : emit availableResourceListResolved(result);
87 0 : })
88 0 : .onReject(this, [](const int errCode, const std::string& errText) {
89 0 : LOGE() << "Unable to resolve available output resources"
90 0 : << " , errCode:" << errCode
91 0 : << " , errText:" << errText;
92 0 : });
93 0 : }
94 :
95 0 : void OutputResourceItem::handleMenuItem(const QString& menuItemId)
96 : {
97 0 : if (menuItemId == NO_FX_MENU_ITEM_ID()) {
98 0 : updateCurrentFxParams(AudioResourceMeta());
99 0 : return;
100 0 : } else if (menuItemId == GET_MORE_EFFECTS) {
101 0 : const QString url = QString::fromStdString(globalConfiguration()->museHubWebUrl());
102 0 : const QString urlParams("plugins?utm_source=mss-mixer-fx&utm_medium=mh-fx&utm_campaign=mss-mixer-fx-mainpage");
103 0 : platformInteractive()->openUrl(url + urlParams);
104 0 : return;
105 0 : }
106 :
107 0 : const audioplugins::PluginResourceId& newSelectedResourceId = menuItemId.toStdString();
108 :
109 0 : for (const auto& pair : m_fxByVendorMap) {
110 0 : for (const AudioResourceMeta& fxResourceMeta : pair.second) {
111 0 : if (newSelectedResourceId != fxResourceMeta.id) {
112 0 : continue;
113 : }
114 :
115 0 : updateCurrentFxParams(fxResourceMeta);
116 : }
117 : }
118 0 : }
119 :
120 0 : const AudioFxParams& OutputResourceItem::params() const
121 : {
122 0 : return m_currentFxParams;
123 : }
124 :
125 0 : void OutputResourceItem::setParams(const audio::AudioFxParams& params)
126 : {
127 0 : if (m_currentFxParams == params) {
128 0 : return;
129 : }
130 :
131 0 : bool activeChanged = m_currentFxParams.active != params.active;
132 0 : bool resourceChanged = m_currentFxParams.resourceMeta.id != params.resourceMeta.id;
133 0 : bool blankChanged = m_currentFxParams.isValid() != params.isValid();
134 :
135 0 : m_currentFxParams = params;
136 0 : emit fxParamsChanged();
137 :
138 0 : if (activeChanged) {
139 0 : emit isActiveChanged();
140 : }
141 :
142 0 : if (resourceChanged) {
143 0 : emit titleChanged();
144 : }
145 :
146 0 : if (blankChanged) {
147 0 : emit isBlankChanged();
148 : }
149 : }
150 :
151 0 : QString OutputResourceItem::title() const
152 : {
153 0 : return QString::fromStdString(m_currentFxParams.resourceMeta.id);
154 : }
155 :
156 0 : bool OutputResourceItem::isActive() const
157 : {
158 0 : return m_currentFxParams.active;
159 : }
160 :
161 0 : QString OutputResourceItem::id() const
162 : {
163 0 : return QString::number(m_currentFxParams.chainOrder);
164 : }
165 :
166 0 : void OutputResourceItem::setIsActive(bool newIsActive)
167 : {
168 0 : if (m_currentFxParams.active == newIsActive) {
169 0 : return;
170 : }
171 :
172 0 : m_currentFxParams.active = newIsActive;
173 :
174 0 : emit isActiveChanged();
175 0 : emit fxParamsChanged();
176 : }
177 :
178 0 : void OutputResourceItem::updateCurrentFxParams(const AudioResourceMeta& newMeta)
179 : {
180 0 : if (m_currentFxParams.resourceMeta == newMeta) {
181 0 : return;
182 : }
183 :
184 0 : requestToCloseNativeEditorView();
185 :
186 0 : audio::AudioFxParams newParams = m_currentFxParams;
187 0 : newParams.categories = audio::audioFxCategoriesFromString(newMeta.attributeVal(vst::CATEGORIES_ATTRIBUTE));
188 0 : newParams.resourceMeta = newMeta;
189 0 : newParams.configuration.clear();
190 0 : newParams.active = newMeta.isValid();
191 :
192 0 : setParams(newParams);
193 0 : requestToLaunchNativeEditorView();
194 0 : }
195 :
196 0 : void OutputResourceItem::updateAvailableFxVendorsMap(const audio::AudioResourceMetaList& availableFxResources)
197 : {
198 0 : m_fxByVendorMap.clear();
199 :
200 0 : for (const auto& meta : availableFxResources) {
201 0 : AudioResourceMetaList& fxResourceList = m_fxByVendorMap[meta.vendor];
202 0 : fxResourceList.push_back(meta);
203 : }
204 :
205 0 : for (auto& [vendor, fxResourceList] : m_fxByVendorMap) {
206 0 : sortResourcesList(fxResourceList);
207 : }
208 0 : }
209 :
210 0 : bool OutputResourceItem::isBlank() const
211 : {
212 0 : return !m_currentFxParams.isValid();
213 : }
214 :
215 0 : bool OutputResourceItem::hasNativeEditorSupport() const
216 : {
217 0 : return muse::audio::hasNativeEditorSupport(m_currentFxParams.resourceMeta);
218 : }
|