LCOV - code coverage report
Current view: top level - src/project/internal - projectaudiosettings.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 348 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "projectaudiosettings.h"
      23              : 
      24              : #include <map>
      25              : #include <QJsonDocument>
      26              : #include <QJsonArray>
      27              : #include <QJsonObject>
      28              : 
      29              : #include "types/bytearray.h"
      30              : 
      31              : #include "audio/common/audioutils.h"
      32              : #include "vst/vstpluginattrs.h"
      33              : 
      34              : using namespace mu::project;
      35              : using namespace muse;
      36              : using namespace muse::audio;
      37              : using namespace mu::engraving;
      38              : using namespace mu::playback;
      39              : 
      40              : static const std::map<AudioSourceType, QString> SOURCE_TYPE_MAP = {
      41              :     { AudioSourceType::Undefined, "undefined" },
      42              :     { AudioSourceType::MuseSampler, "musesampler" },
      43              :     { AudioSourceType::Fluid, "fluid" },
      44              :     { AudioSourceType::Vsti, "vsti" }
      45              : };
      46              : 
      47            0 : static void doCompatibilityConversions(AudioResourceMeta& meta)
      48              : {
      49            0 :     if (isResourceType(meta, AudioResourceType::MuseSamplerSoundPack)) {
      50              :         // MS 4.5: resource name and category have been excluded from ID
      51              :         // Old format: category\\name\\uid
      52            0 :         if (meta.id.find("\\") == std::string::npos) {
      53            0 :             return;
      54              :         }
      55              : 
      56            0 :         const String& museUID = meta.attributeVal(u"museUID");
      57            0 :         if (!museUID.empty()) {
      58            0 :             meta.id = museUID.toStdString();
      59              :         }
      60              :     }
      61              : }
      62              : 
      63            0 : bool ProjectAudioSettings::hasAnyAudioSettings() const
      64              : {
      65            0 :     return !m_trackInputParamsMap.empty() || !m_trackOutputParamsMap.empty() || !m_auxOutputParams.empty();
      66              : }
      67              : 
      68            0 : const AudioOutputParams& ProjectAudioSettings::masterAudioOutputParams() const
      69              : {
      70            0 :     return m_masterOutputParams;
      71              : }
      72              : 
      73            0 : void ProjectAudioSettings::setMasterAudioOutputParams(const AudioOutputParams& params)
      74              : {
      75            0 :     if (m_masterOutputParams == params) {
      76            0 :         return;
      77              :     }
      78              : 
      79            0 :     m_masterOutputParams = params;
      80            0 :     m_settingsChanged.notify();
      81              : }
      82              : 
      83            0 : bool ProjectAudioSettings::containsAuxOutputParams(aux_channel_idx_t index) const
      84              : {
      85            0 :     return muse::contains(m_auxOutputParams, index);
      86              : }
      87              : 
      88            0 : const AudioOutputParams& ProjectAudioSettings::auxOutputParams(aux_channel_idx_t index) const
      89              : {
      90            0 :     if (index < m_auxOutputParams.size()) {
      91            0 :         return m_auxOutputParams.at(index);
      92              :     }
      93              : 
      94            0 :     static const AudioOutputParams _dummy;
      95            0 :     return _dummy;
      96              : }
      97              : 
      98            0 : void ProjectAudioSettings::setAuxOutputParams(aux_channel_idx_t index, const AudioOutputParams& params, bool notifySettingsChanged)
      99              : {
     100            0 :     auto it = m_auxOutputParams.find(index);
     101            0 :     if (it != m_auxOutputParams.end() && it->second == params) {
     102            0 :         return;
     103              :     }
     104              : 
     105            0 :     m_auxOutputParams.insert_or_assign(index, params);
     106              : 
     107            0 :     if (notifySettingsChanged) {
     108            0 :         m_settingsChanged.notify();
     109              :     }
     110              : }
     111              : 
     112            0 : const TrackInputParamsMap& ProjectAudioSettings::allTrackInputParams() const
     113              : {
     114            0 :     return m_trackInputParamsMap;
     115              : }
     116              : 
     117            0 : const AudioInputParams& ProjectAudioSettings::trackInputParams(const InstrumentTrackId& partId) const
     118              : {
     119            0 :     auto it = m_trackInputParamsMap.find(partId);
     120            0 :     if (it == m_trackInputParamsMap.end()) {
     121            0 :         static const AudioInputParams _dummy;
     122            0 :         return _dummy;
     123              :     }
     124              : 
     125            0 :     return it->second;
     126              : }
     127              : 
     128            0 : void ProjectAudioSettings::setTrackInputParams(const InstrumentTrackId& partId, const AudioInputParams& params,
     129              :                                                bool notifySettingsChanged)
     130              : {
     131            0 :     auto it = m_trackInputParamsMap.find(partId);
     132            0 :     if (it != m_trackInputParamsMap.end() && it->second == params) {
     133            0 :         return;
     134              :     }
     135              : 
     136            0 :     m_trackInputParamsMap.insert_or_assign(partId, params);
     137            0 :     m_trackInputParamsChanged.send(partId);
     138              : 
     139            0 :     if (notifySettingsChanged) {
     140            0 :         m_settingsChanged.notify();
     141              :     }
     142              : }
     143              : 
     144            0 : void ProjectAudioSettings::clearTrackInputParams()
     145              : {
     146            0 :     if (m_trackInputParamsMap.empty()) {
     147            0 :         return;
     148              :     }
     149              : 
     150            0 :     auto it = m_trackInputParamsMap.begin();
     151            0 :     while (it != m_trackInputParamsMap.end()) {
     152            0 :         InstrumentTrackId id = it->first;
     153            0 :         it = m_trackInputParamsMap.erase(it);
     154            0 :         m_trackInputParamsChanged.send(id);
     155            0 :     }
     156              : 
     157            0 :     m_settingsChanged.notify();
     158              : }
     159              : 
     160            0 : muse::async::Channel<mu::engraving::InstrumentTrackId> ProjectAudioSettings::trackInputParamsChanged() const
     161              : {
     162            0 :     return m_trackInputParamsChanged;
     163              : }
     164              : 
     165            0 : bool ProjectAudioSettings::trackHasExistingOutputParams(const InstrumentTrackId& partId) const
     166              : {
     167            0 :     return muse::contains(m_trackOutputParamsMap, partId);
     168              : }
     169              : 
     170            0 : const AudioOutputParams& ProjectAudioSettings::trackOutputParams(const InstrumentTrackId& partId) const
     171              : {
     172            0 :     auto search = m_trackOutputParamsMap.find(partId);
     173              : 
     174            0 :     if (search == m_trackOutputParamsMap.end()) {
     175            0 :         static const AudioOutputParams _dummy;
     176            0 :         return _dummy;
     177              :     }
     178              : 
     179            0 :     return search->second;
     180              : }
     181              : 
     182            0 : void ProjectAudioSettings::setTrackOutputParams(const InstrumentTrackId& partId, const AudioOutputParams& params,
     183              :                                                 bool notifySettingsChanged)
     184              : {
     185            0 :     auto it = m_trackOutputParamsMap.find(partId);
     186            0 :     bool paramsChanged = it == m_trackOutputParamsMap.cend();
     187              : 
     188            0 :     if (!paramsChanged) {
     189            0 :         paramsChanged |= !muse::RealIsEqual(it->second.volume, params.volume);
     190            0 :         paramsChanged |= !muse::RealIsEqual(it->second.balance, params.balance);
     191            0 :         paramsChanged |= (it->second.fxChain != params.fxChain);
     192            0 :         paramsChanged |= (it->second.auxSends != params.auxSends);
     193              :     }
     194              : 
     195            0 :     m_trackOutputParamsMap.insert_or_assign(partId, params);
     196              : 
     197            0 :     if (paramsChanged && notifySettingsChanged) {
     198            0 :         m_settingsChanged.notify();
     199              :     }
     200            0 : }
     201              : 
     202            0 : const IProjectAudioSettings::SoloMuteState& ProjectAudioSettings::auxSoloMuteState(aux_channel_idx_t index) const
     203              : {
     204            0 :     auto it = m_auxSoloMuteStatesMap.find(index);
     205            0 :     if (it == m_auxSoloMuteStatesMap.end()) {
     206              :         static const IProjectAudioSettings::SoloMuteState _dummy;
     207            0 :         return _dummy;
     208              :     }
     209              : 
     210            0 :     return it->second;
     211              : }
     212              : 
     213            0 : void ProjectAudioSettings::setAuxSoloMuteState(aux_channel_idx_t index, const SoloMuteState& state)
     214              : {
     215            0 :     auto it = m_auxSoloMuteStatesMap.find(index);
     216            0 :     if (it != m_auxSoloMuteStatesMap.end() && it->second == state) {
     217            0 :         return;
     218              :     }
     219              : 
     220            0 :     m_auxSoloMuteStatesMap.insert_or_assign(index, state);
     221            0 :     m_auxSoloMuteStateChanged.send(index, state);
     222            0 :     m_settingsChanged.notify();
     223              : }
     224              : 
     225            0 : muse::async::Channel<aux_channel_idx_t, IProjectAudioSettings::SoloMuteState> ProjectAudioSettings::auxSoloMuteStateChanged() const
     226              : {
     227            0 :     return m_auxSoloMuteStateChanged;
     228              : }
     229              : 
     230            0 : void ProjectAudioSettings::removeTrackParams(const InstrumentTrackId& partId)
     231              : {
     232            0 :     auto inSearch = m_trackInputParamsMap.find(partId);
     233            0 :     if (inSearch != m_trackInputParamsMap.end()) {
     234            0 :         m_trackInputParamsMap.erase(inSearch);
     235            0 :         m_trackInputParamsChanged.send(partId);
     236            0 :         m_settingsChanged.notify();
     237              :     }
     238              : 
     239            0 :     auto outSearch = m_trackOutputParamsMap.find(partId);
     240            0 :     if (outSearch != m_trackOutputParamsMap.end()) {
     241            0 :         m_trackOutputParamsMap.erase(outSearch);
     242            0 :         m_settingsChanged.notify();
     243              :     }
     244            0 : }
     245              : 
     246            0 : const SoundProfileName& ProjectAudioSettings::activeSoundProfile() const
     247              : {
     248            0 :     return m_activeSoundProfileName;
     249              : }
     250              : 
     251            0 : void ProjectAudioSettings::setActiveSoundProfile(const playback::SoundProfileName& profileName)
     252              : {
     253            0 :     if (m_activeSoundProfileName == profileName) {
     254            0 :         return;
     255              :     }
     256              : 
     257            0 :     m_activeSoundProfileName = profileName;
     258            0 :     m_settingsChanged.notify();
     259              : }
     260              : 
     261            0 : muse::async::Notification ProjectAudioSettings::settingsChanged() const
     262              : {
     263            0 :     return m_settingsChanged;
     264              : }
     265              : 
     266            0 : Ret ProjectAudioSettings::read(const engraving::MscReader& reader)
     267              : {
     268            0 :     ByteArray json = reader.readAudioSettingsJsonFile();
     269            0 :     if (json.empty()) {
     270            0 :         return make_ret(Ret::Code::UnknownError);
     271              :     }
     272              : 
     273            0 :     QJsonObject rootObj = QJsonDocument::fromJson(json.toQByteArrayNoCopy()).object();
     274              : 
     275            0 :     QJsonObject masterObj = rootObj.value("master").toObject();
     276            0 :     m_masterOutputParams = outputParamsFromJson(masterObj);
     277              : 
     278            0 :     QJsonArray auxArray = rootObj.value("aux").toArray();
     279            0 :     for (aux_channel_idx_t i = 0; i < static_cast<aux_channel_idx_t>(auxArray.size()); ++i) {
     280            0 :         QJsonObject auxObject = auxArray[i].toObject();
     281              : 
     282            0 :         AudioOutputParams outParams = outputParamsFromJson(auxObject.value("out").toObject());
     283            0 :         SoloMuteState soloMuteState = soloMuteStateFromJson(auxObject.value("soloMuteState").toObject());
     284              : 
     285            0 :         m_auxOutputParams.emplace(i, std::move(outParams));
     286            0 :         m_auxSoloMuteStatesMap.emplace(i, std::move(soloMuteState));
     287            0 :     }
     288              : 
     289            0 :     QJsonArray tracksArray = rootObj.value("tracks").toArray();
     290              : 
     291            0 :     for (const QJsonValue value : tracksArray) {
     292            0 :         QJsonObject trackObject = value.toObject();
     293              : 
     294              :         InstrumentTrackId id = {
     295            0 :             trackObject.value("partId").toString(),
     296            0 :             trackObject.value("instrumentId").toString()
     297            0 :         };
     298              : 
     299            0 :         AudioInputParams inParams = inputParamsFromJson(trackObject.value("in").toObject());
     300            0 :         AudioOutputParams outParams = outputParamsFromJson(trackObject.value("out").toObject());
     301              : 
     302            0 :         doCompatibilityConversions(inParams.resourceMeta);
     303              : 
     304            0 :         m_trackInputParamsMap.emplace(id, std::move(inParams));
     305            0 :         m_trackOutputParamsMap.emplace(id, std::move(outParams));
     306            0 :     }
     307              : 
     308            0 :     m_activeSoundProfileName = rootObj.value("activeSoundProfile").toString();
     309            0 :     if (m_activeSoundProfileName.empty()) {
     310            0 :         m_activeSoundProfileName = playbackConfig()->defaultProfileForNewProjects();
     311            0 :     } else if (m_activeSoundProfileName == playbackConfig()->compatMuseSoundsProfileName()) {
     312            0 :         m_activeSoundProfileName = playbackConfig()->museSoundsProfileName();
     313              :     }
     314              : 
     315            0 :     return make_ret(Ret::Code::Ok);
     316            0 : }
     317              : 
     318            0 : Ret ProjectAudioSettings::write(engraving::MscWriter& writer, notation::INotationSoloMuteStatePtr masterSoloMuteStatePtr)
     319              : {
     320            0 :     QJsonObject rootObj;
     321            0 :     rootObj["master"] = outputParamsToJson(m_masterOutputParams);
     322              : 
     323            0 :     QJsonArray auxArray;
     324            0 :     for (const auto& pair : m_auxOutputParams) {
     325            0 :         auxArray.append(buildAuxObject(pair.first, pair.second));
     326              :     }
     327              : 
     328            0 :     rootObj["aux"] = auxArray;
     329              : 
     330            0 :     QJsonArray tracksArray;
     331            0 :     for (const auto& pair : m_trackInputParamsMap) {
     332            0 :         tracksArray.append(buildTrackObject(masterSoloMuteStatePtr, pair.first));
     333              :     }
     334              : 
     335            0 :     rootObj["tracks"] = tracksArray;
     336            0 :     rootObj["activeSoundProfile"] = m_activeSoundProfileName.toQString();
     337              : 
     338            0 :     QByteArray json = QJsonDocument(rootObj).toJson();
     339            0 :     writer.writeAudioSettingsJsonFile(ByteArray::fromQByteArrayNoCopy(json));
     340              : 
     341            0 :     return make_ret(Ret::Code::Ok);
     342            0 : }
     343              : 
     344            0 : void ProjectAudioSettings::makeDefault()
     345              : {
     346            0 :     m_activeSoundProfileName = playbackConfig()->defaultProfileForNewProjects();
     347            0 : }
     348              : 
     349            0 : AudioInputParams ProjectAudioSettings::inputParamsFromJson(const QJsonObject& object) const
     350              : {
     351            0 :     AudioInputParams result;
     352            0 :     result.resourceMeta = resourceMetaFromJson(object.value("resourceMeta").toObject());
     353            0 :     result.configuration = unitConfigFromJson(object.value("unitConfiguration").toObject());
     354              : 
     355            0 :     return result;
     356            0 : }
     357              : 
     358            0 : AudioOutputParams ProjectAudioSettings::outputParamsFromJson(const QJsonObject& object) const
     359              : {
     360            0 :     AudioOutputParams result;
     361            0 :     result.fxChain = fxChainFromJson(object.value("fxChain").toObject());
     362            0 :     result.balance = object.value("balance").toVariant().toFloat();
     363            0 :     result.volume = object.value("volumeDb").toVariant().toFloat();
     364            0 :     result.auxSends = auxSendsFromJson(object.value("auxSends").toArray());
     365              : 
     366            0 :     return result;
     367            0 : }
     368              : 
     369            0 : IProjectAudioSettings::SoloMuteState ProjectAudioSettings::soloMuteStateFromJson(const QJsonObject& object) const
     370              : {
     371            0 :     SoloMuteState result;
     372            0 :     result.mute = object.value("mute").toBool();
     373            0 :     result.solo = object.value("solo").toBool();
     374              : 
     375            0 :     return result;
     376              : }
     377              : 
     378            0 : AudioFxChain ProjectAudioSettings::fxChainFromJson(const QJsonObject& fxChainObject) const
     379              : {
     380            0 :     AudioFxChain result;
     381              : 
     382            0 :     for (const QString& key : fxChainObject.keys()) {
     383            0 :         AudioFxParams params = fxParamsFromJson(fxChainObject.value(key).toObject());
     384            0 :         result.emplace(static_cast<AudioFxChainOrder>(key.toInt()), std::move(params));
     385            0 :     }
     386              : 
     387            0 :     return result;
     388            0 : }
     389              : 
     390            0 : AudioFxParams ProjectAudioSettings::fxParamsFromJson(const QJsonObject& object) const
     391              : {
     392            0 :     AudioFxParams result;
     393            0 :     result.active = object.value("active").toBool();
     394            0 :     result.chainOrder = static_cast<AudioFxChainOrder>(object.value("chainOrder").toInt());
     395            0 :     result.resourceMeta = resourceMetaFromJson(object.value("resourceMeta").toObject());
     396            0 :     result.configuration = unitConfigFromJson(object.value("unitConfiguration").toObject());
     397            0 :     result.categories = audioFxCategoriesFromString(result.resourceMeta.attributeVal(vst::CATEGORIES_ATTRIBUTE));
     398              : 
     399            0 :     return result;
     400            0 : }
     401              : 
     402            0 : AuxSendsParams ProjectAudioSettings::auxSendsFromJson(const QJsonArray& objectList) const
     403              : {
     404            0 :     AuxSendsParams result;
     405              : 
     406            0 :     for (const QJsonValue value : objectList) {
     407            0 :         AuxSendParams params = auxSendParamsFromJson(value.toObject());
     408            0 :         result.emplace_back(std::move(params));
     409            0 :     }
     410              : 
     411            0 :     return result;
     412            0 : }
     413              : 
     414            0 : AuxSendParams ProjectAudioSettings::auxSendParamsFromJson(const QJsonObject& object) const
     415              : {
     416            0 :     AuxSendParams result;
     417            0 :     result.signalAmount = object.value("signalAmount").toVariant().toFloat();
     418            0 :     result.active = object.value("active").toBool();
     419              : 
     420            0 :     return result;
     421              : }
     422              : 
     423            0 : AudioResourceMeta ProjectAudioSettings::resourceMetaFromJson(const QJsonObject& object) const
     424              : {
     425            0 :     AudioResourceMeta result;
     426            0 :     result.id = object.value("id").toString().toStdString();
     427            0 :     result.vendor = object.value("vendor").toString().toStdString();
     428            0 :     result.type = resourceTypeFromString(object.value("type").toString());
     429            0 :     result.attributes = attributesFromJson(object.value("attributes").toObject());
     430              : 
     431              :     // migrate legacy top-level hasNativeEditorSupport into attributes
     432            0 :     const QString nativeEditorKey = audio::HAS_NATIVE_EDITOR_SUPPORT_ATTRIBUTE.toQString();
     433            0 :     if (object.contains(nativeEditorKey) && !result.attributes.count(audio::HAS_NATIVE_EDITOR_SUPPORT_ATTRIBUTE)) {
     434            0 :         const bool b = object.value(nativeEditorKey).toBool();
     435            0 :         result.attributes.emplace(audio::HAS_NATIVE_EDITOR_SUPPORT_ATTRIBUTE, b ? u"true" : u"false");
     436              :     }
     437              : 
     438            0 :     return result;
     439            0 : }
     440              : 
     441            0 : AudioUnitConfig ProjectAudioSettings::unitConfigFromJson(const QJsonObject& object) const
     442              : {
     443            0 :     AudioUnitConfig result;
     444              : 
     445            0 :     for (const QString& key : object.keys()) {
     446            0 :         QByteArray base = QByteArray::fromBase64(object.value(key).toString().toUtf8());
     447            0 :         result.emplace(key.toStdString(), base.toStdString());
     448            0 :     }
     449              : 
     450            0 :     return result;
     451            0 : }
     452              : 
     453            0 : AudioResourceAttributes ProjectAudioSettings::attributesFromJson(const QJsonObject& object) const
     454              : {
     455            0 :     AudioResourceAttributes result;
     456              : 
     457            0 :     for (const QString& key : object.keys()) {
     458            0 :         result.emplace(String::fromQString(key), String::fromQString(object.value(key).toString()));
     459            0 :     }
     460              : 
     461            0 :     return result;
     462            0 : }
     463              : 
     464            0 : QJsonObject ProjectAudioSettings::inputParamsToJson(const AudioInputParams& params) const
     465              : {
     466            0 :     QJsonObject result;
     467            0 :     result.insert("resourceMeta", resourceMetaToJson(params.resourceMeta));
     468            0 :     result.insert("unitConfiguration", unitConfigToJson(params.configuration));
     469              : 
     470            0 :     return result;
     471            0 : }
     472              : 
     473            0 : QJsonObject ProjectAudioSettings::outputParamsToJson(const AudioOutputParams& params) const
     474              : {
     475            0 :     QJsonObject result;
     476            0 :     result.insert("fxChain", fxChainToJson(params.fxChain));
     477            0 :     result.insert("balance", params.balance.raw());
     478            0 :     result.insert("volumeDb", params.volume.raw());
     479              : 
     480            0 :     if (!params.auxSends.empty()) {
     481            0 :         result.insert("auxSends", auxSendsToJson(params.auxSends));
     482              :     }
     483              : 
     484            0 :     return result;
     485            0 : }
     486              : 
     487            0 : QJsonObject ProjectAudioSettings::soloMuteStateToJson(const SoloMuteState& state) const
     488              : {
     489            0 :     QJsonObject result;
     490            0 :     result.insert("mute", state.mute);
     491            0 :     result.insert("solo", state.solo);
     492              : 
     493            0 :     return result;
     494            0 : }
     495              : 
     496            0 : QJsonObject ProjectAudioSettings::fxChainToJson(const AudioFxChain& fxChain) const
     497              : {
     498            0 :     QJsonObject result;
     499              : 
     500            0 :     for (const auto& pair : fxChain) {
     501            0 :         result.insert(QString::number(static_cast<int>(pair.first)), fxParamsToJson(pair.second));
     502              :     }
     503              : 
     504            0 :     return result;
     505            0 : }
     506              : 
     507            0 : QJsonArray ProjectAudioSettings::auxSendsToJson(const AuxSendsParams& auxSends) const
     508              : {
     509            0 :     QJsonArray result;
     510              : 
     511            0 :     for (const AuxSendParams& auxSend : auxSends) {
     512            0 :         result.push_back(auxSendParamsToJson(auxSend));
     513              :     }
     514              : 
     515            0 :     return result;
     516            0 : }
     517              : 
     518            0 : QJsonObject ProjectAudioSettings::auxSendParamsToJson(const AuxSendParams& auxParams) const
     519              : {
     520            0 :     QJsonObject result;
     521            0 :     result.insert("active", auxParams.active);
     522            0 :     result.insert("signalAmount", auxParams.signalAmount);
     523              : 
     524            0 :     return result;
     525            0 : }
     526              : 
     527            0 : QJsonObject ProjectAudioSettings::fxParamsToJson(const AudioFxParams& fxParams) const
     528              : {
     529            0 :     QJsonObject result;
     530            0 :     result.insert("active", fxParams.active);
     531            0 :     result.insert("chainOrder", static_cast<int>(fxParams.chainOrder));
     532            0 :     result.insert("resourceMeta", resourceMetaToJson(fxParams.resourceMeta));
     533            0 :     result.insert("unitConfiguration", unitConfigToJson(fxParams.configuration));
     534              : 
     535            0 :     return result;
     536            0 : }
     537              : 
     538            0 : QJsonObject ProjectAudioSettings::resourceMetaToJson(const AudioResourceMeta& meta) const
     539              : {
     540            0 :     QJsonObject result;
     541            0 :     result.insert("id", QString::fromStdString(meta.id));
     542            0 :     result.insert("vendor", QString::fromStdString(meta.vendor));
     543            0 :     result.insert("type", audioResourceTypeToString(meta.type).toQString());
     544            0 :     result.insert("attributes", attributesToJson(meta.attributes));
     545              : 
     546            0 :     return result;
     547            0 : }
     548              : 
     549            0 : QJsonObject ProjectAudioSettings::unitConfigToJson(const AudioUnitConfig& config) const
     550              : {
     551            0 :     QJsonObject result;
     552              : 
     553            0 :     for (const auto& pair : config) {
     554            0 :         QByteArray byteArray = QByteArray::fromRawData(pair.second.c_str(), static_cast<int>(pair.second.size()));
     555            0 :         result.insert(QString::fromStdString(pair.first), QString(byteArray.toBase64()));
     556            0 :     }
     557              : 
     558            0 :     return result;
     559            0 : }
     560              : 
     561            0 : QJsonObject ProjectAudioSettings::attributesToJson(const AudioResourceAttributes& attributes) const
     562              : {
     563            0 :     QJsonObject result;
     564              : 
     565            0 :     for (const auto& pair : attributes) {
     566            0 :         result.insert(pair.first.toQString(), pair.second.toQString());
     567              :     }
     568              : 
     569            0 :     return result;
     570            0 : }
     571              : 
     572            0 : AudioSourceType ProjectAudioSettings::sourceTypeFromString(const QString& string) const
     573              : {
     574            0 :     for (const auto& pair : SOURCE_TYPE_MAP) {
     575            0 :         if (pair.second == string) {
     576            0 :             return pair.first;
     577              :         }
     578              :     }
     579              : 
     580            0 :     return AudioSourceType::Undefined;
     581              : }
     582              : 
     583            0 : audioplugins::PluginType ProjectAudioSettings::resourceTypeFromString(const QString& string) const
     584              : {
     585            0 :     for (const auto& pair : RESOURCE_TYPE_MAP) {
     586            0 :         if (pair.second == string) {
     587            0 :             return audio::resourceTypeName(pair.first);
     588              :         }
     589              :     }
     590              : 
     591            0 :     return audioplugins::PluginType();
     592              : }
     593              : 
     594            0 : QString ProjectAudioSettings::sourceTypeToString(const AudioSourceType& type) const
     595              : {
     596            0 :     auto search = SOURCE_TYPE_MAP.find(type);
     597              : 
     598            0 :     if (search != SOURCE_TYPE_MAP.end()) {
     599            0 :         return search->second;
     600              :     }
     601              : 
     602            0 :     return SOURCE_TYPE_MAP.at(AudioSourceType::Undefined);
     603              : }
     604              : 
     605            0 : QJsonObject ProjectAudioSettings::buildAuxObject(aux_channel_idx_t index, const AudioOutputParams& params) const
     606              : {
     607            0 :     QJsonObject result;
     608              : 
     609            0 :     result.insert("out", outputParamsToJson(params));
     610              : 
     611            0 :     auto soloMuteSearch = m_auxSoloMuteStatesMap.find(index);
     612            0 :     if (soloMuteSearch != m_auxSoloMuteStatesMap.end()) {
     613            0 :         result.insert("soloMuteState", soloMuteStateToJson(soloMuteSearch->second));
     614              :     }
     615              : 
     616            0 :     return result;
     617            0 : }
     618              : 
     619            0 : QJsonObject ProjectAudioSettings::buildTrackObject(notation::INotationSoloMuteStatePtr masterSoloMuteStatePtr,
     620              :                                                    const InstrumentTrackId& id) const
     621              : {
     622            0 :     QJsonObject result;
     623              : 
     624            0 :     result.insert("partId", id.partId.toQString());
     625            0 :     result.insert("instrumentId", id.instrumentId.toQString());
     626              : 
     627            0 :     auto inputParamsSearch = m_trackInputParamsMap.find(id);
     628            0 :     if (inputParamsSearch != m_trackInputParamsMap.end()) {
     629            0 :         result.insert("in", inputParamsToJson(inputParamsSearch->second));
     630              :     }
     631              : 
     632            0 :     auto outputParamsSearch = m_trackOutputParamsMap.find(id);
     633            0 :     if (outputParamsSearch != m_trackOutputParamsMap.end()) {
     634            0 :         result.insert("out", outputParamsToJson(outputParamsSearch->second));
     635              :     }
     636              : 
     637            0 :     if (masterSoloMuteStatePtr && masterSoloMuteStatePtr->trackSoloMuteStateExists(id)) {
     638            0 :         const SoloMuteState& soloMuteState = masterSoloMuteStatePtr->trackSoloMuteState(id);
     639            0 :         result.insert("soloMuteState", soloMuteStateToJson(soloMuteState));
     640              :     }
     641              : 
     642            0 :     return result;
     643            0 : }
        

Generated by: LCOV version 2.0-1