LCOV - code coverage report
Current view: top level - muse/framework/audio/main/internal - audioconfiguration.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 120 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2025 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 "audioconfiguration.h"
      23              : 
      24              : //TODO: remove with global clearing of Q_OS_*** defines
      25              : #include <QtGlobal>
      26              : 
      27              : #include "global/settings.h"
      28              : 
      29              : #include "audio/common/soundfonttypes.h"
      30              : #include "audio/common/audioutils.h"
      31              : #include "audio/common/rpc/rpcpacker.h"
      32              : 
      33              : #include "log.h"
      34              : 
      35              : using namespace muse;
      36              : using namespace muse::audio;
      37              : using namespace muse::audio::synth;
      38              : 
      39              : static constexpr audioch_t AUDIO_CHANNELS = 2;
      40              : static constexpr samples_t DEFAULT_BUFFER_SIZE = 1024;
      41              : static constexpr sample_rate_t DEFAULT_SAMPLE_RATE = 44100;
      42              : 
      43              : //TODO: add other setting: audio device etc
      44              : static const Settings::Key AUDIO_DRIVER_KEY("audio", "io/audioDriver");
      45              : static const Settings::Key AUDIO_OUTPUT_DEVICE_ID_KEY("audio", "io/outputDevice");
      46              : static const Settings::Key AUDIO_BUFFER_SIZE_KEY("audio", "io/bufferSize");
      47              : static const Settings::Key AUDIO_SAMPLE_RATE_KEY("audio", "io/sampleRate");
      48              : static const Settings::Key AUDIO_MEASURE_INPUT_LAG("audio", "io/measureInputLag");
      49              : 
      50              : static const Settings::Key ONLINE_SOUNDS_PROCESS_IN_BACKGROUND("audio", "io/onlineSounds/processInBackground");
      51              : static const Settings::Key USE_SOUNDFONT_LOWPASS_FILTER("audio", "synthesizer/useSoundFontLowPassFilter");
      52              : 
      53              : static const Settings::Key USER_SOUNDFONTS_PATHS("midi", "application/paths/mySoundfonts");
      54              : 
      55            0 : void AudioConfiguration::init()
      56              : {
      57            0 :     settings()->setDefaultValue(AUDIO_BUFFER_SIZE_KEY, Val(static_cast<int>(DEFAULT_BUFFER_SIZE)));
      58            0 :     settings()->valueChanged(AUDIO_BUFFER_SIZE_KEY).onReceive(nullptr, [this](const Val&) {
      59            0 :         m_driverBufferSizeChanged.notify();
      60            0 :     });
      61              : 
      62              : #if defined(Q_OS_WIN)
      63              :     settings()->setDefaultValue(AUDIO_DRIVER_KEY, Val("WASAPI"));
      64              : #elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
      65            0 :     settings()->setDefaultValue(AUDIO_DRIVER_KEY, Val("ALSA"));
      66              : #elif defined(Q_OS_MACOS)
      67              :     settings()->setDefaultValue(AUDIO_DRIVER_KEY, Val("CoreAudio"));
      68              : #endif
      69            0 :     settings()->valueChanged(AUDIO_DRIVER_KEY).onReceive(nullptr, [this](const Val&) {
      70            0 :         m_currentAudioDriverChanged.notify();
      71            0 :     });
      72              : 
      73            0 :     settings()->setDefaultValue(AUDIO_OUTPUT_DEVICE_ID_KEY, Val(DEFAULT_DEVICE_ID));
      74            0 :     settings()->valueChanged(AUDIO_OUTPUT_DEVICE_ID_KEY).onReceive(nullptr, [this](const Val&) {
      75            0 :         m_audioOutputDeviceIdChanged.notify();
      76            0 :     });
      77              : 
      78            0 :     settings()->setDefaultValue(AUDIO_SAMPLE_RATE_KEY, Val(static_cast<int>(DEFAULT_SAMPLE_RATE)));
      79            0 :     settings()->setCanBeManuallyEdited(AUDIO_SAMPLE_RATE_KEY, false, Val(44100), Val(192000));
      80            0 :     settings()->valueChanged(AUDIO_SAMPLE_RATE_KEY).onReceive(nullptr, [this](const Val&) {
      81            0 :         m_driverSampleRateChanged.notify();
      82            0 :     });
      83              : 
      84            0 :     settings()->setDefaultValue(USER_SOUNDFONTS_PATHS, Val(globalConfiguration()->userDataPath() + "/SoundFonts"));
      85            0 :     settings()->valueChanged(USER_SOUNDFONTS_PATHS).onReceive(nullptr, [this](const Val&) {
      86            0 :         m_soundFontDirsChanged.send(soundFontDirectories());
      87            0 :     });
      88              : 
      89            0 :     for (const auto& path : userSoundFontDirectories()) {
      90            0 :         fileSystem()->makePath(path);
      91            0 :     }
      92              : 
      93            0 :     settings()->setDefaultValue(AUDIO_MEASURE_INPUT_LAG, Val(false));
      94              : 
      95            0 :     settings()->setDefaultValue(ONLINE_SOUNDS_PROCESS_IN_BACKGROUND, Val(true));
      96            0 :     settings()->valueChanged(ONLINE_SOUNDS_PROCESS_IN_BACKGROUND).onReceive(nullptr, [this](const Val& val) {
      97            0 :         m_autoProcessOnlineSoundsInBackgroundChanged.send(val.toBool());
      98            0 :     });
      99              : 
     100            0 :     settings()->setDefaultValue(USE_SOUNDFONT_LOWPASS_FILTER, Val(true));
     101            0 :     settings()->valueChanged(USE_SOUNDFONT_LOWPASS_FILTER).onReceive(nullptr, [this](const Val& val) {
     102            0 :         m_useSoundFontLowPassFilterChanged.send(val.toBool());
     103            0 :     });
     104            0 : }
     105              : 
     106            0 : AudioEngineConfig AudioConfiguration::engineConfig() const
     107              : {
     108            0 :     AudioEngineConfig conf;
     109            0 :     conf.autoProcessOnlineSoundsInBackground = autoProcessOnlineSoundsInBackground();
     110            0 :     conf.isLazyProcessingOfOnlineSoundsEnabled = conf.autoProcessOnlineSoundsInBackground;
     111            0 :     conf.useSoundFontLowPassFilter = useSoundFontLowPassFilter();
     112            0 :     return conf;
     113              : }
     114              : 
     115            0 : void AudioConfiguration::onEngineConfigChanged()
     116              : {
     117            0 :     rpcChannel()->send(rpc::make_notification(rpc::GLOBAL_CTX_ID, rpc::MsgCode::EngineConfigChanged, rpc::RpcPacker::pack(engineConfig())));
     118            0 : }
     119              : 
     120            0 : std::string AudioConfiguration::defaultAudioDriverName() const
     121              : {
     122            0 :     return settings()->defaultValue(AUDIO_DRIVER_KEY).toString();
     123              : }
     124              : 
     125            0 : std::string AudioConfiguration::currentAudioDriverName() const
     126              : {
     127            0 :     return settings()->value(AUDIO_DRIVER_KEY).toString();
     128              : }
     129              : 
     130            0 : void AudioConfiguration::setCurrentAudioDriverName(const std::string& name)
     131              : {
     132            0 :     settings()->setSharedValue(AUDIO_DRIVER_KEY, Val(name));
     133            0 : }
     134              : 
     135            0 : async::Notification AudioConfiguration::currentAudioDriverChanged() const
     136              : {
     137            0 :     return m_currentAudioDriverChanged;
     138              : }
     139              : 
     140            0 : std::string AudioConfiguration::audioOutputDeviceId() const
     141              : {
     142            0 :     return settings()->value(AUDIO_OUTPUT_DEVICE_ID_KEY).toString();
     143              : }
     144              : 
     145            0 : void AudioConfiguration::setAudioOutputDeviceId(const std::string& deviceId)
     146              : {
     147            0 :     settings()->setSharedValue(AUDIO_OUTPUT_DEVICE_ID_KEY, Val(deviceId));
     148            0 : }
     149              : 
     150            0 : async::Notification AudioConfiguration::audioOutputDeviceIdChanged() const
     151              : {
     152            0 :     return m_audioOutputDeviceIdChanged;
     153              : }
     154              : 
     155            0 : audioch_t AudioConfiguration::audioChannelsCount() const
     156              : {
     157            0 :     return AUDIO_CHANNELS;
     158              : }
     159              : 
     160            0 : unsigned int AudioConfiguration::driverBufferSize() const
     161              : {
     162            0 :     return settings()->value(AUDIO_BUFFER_SIZE_KEY).toInt();
     163              : }
     164              : 
     165            0 : void AudioConfiguration::setDriverBufferSize(unsigned int size)
     166              : {
     167            0 :     settings()->setSharedValue(AUDIO_BUFFER_SIZE_KEY, Val(static_cast<int>(size)));
     168            0 : }
     169              : 
     170            0 : async::Notification AudioConfiguration::driverBufferSizeChanged() const
     171              : {
     172            0 :     return m_driverBufferSizeChanged;
     173              : }
     174              : 
     175            0 : unsigned int AudioConfiguration::sampleRate() const
     176              : {
     177            0 :     return settings()->value(AUDIO_SAMPLE_RATE_KEY).toInt();
     178              : }
     179              : 
     180            0 : void AudioConfiguration::setSampleRate(unsigned int sampleRate)
     181              : {
     182            0 :     settings()->setSharedValue(AUDIO_SAMPLE_RATE_KEY, Val(static_cast<int>(sampleRate)));
     183            0 : }
     184              : 
     185            0 : async::Notification AudioConfiguration::sampleRateChanged() const
     186              : {
     187            0 :     return m_driverSampleRateChanged;
     188              : }
     189              : 
     190            0 : OutputSpec AudioConfiguration::defaultOutputSpec() const
     191              : {
     192            0 :     OutputSpec spec;
     193            0 :     spec.sampleRate = DEFAULT_SAMPLE_RATE;
     194            0 :     spec.samplesPerChannel = DEFAULT_BUFFER_SIZE;
     195            0 :     spec.audioChannelCount = AUDIO_CHANNELS;
     196            0 :     return spec;
     197              : }
     198              : 
     199            0 : OutputSpec AudioConfiguration::desiredOutputSpec() const
     200              : {
     201            0 :     OutputSpec spec;
     202            0 :     spec.sampleRate = sampleRate();
     203            0 :     spec.samplesPerChannel = driverBufferSize();
     204            0 :     spec.audioChannelCount = audioChannelsCount();
     205            0 :     return spec;
     206              : }
     207              : 
     208            0 : io::paths_t AudioConfiguration::soundFontDirectories() const
     209              : {
     210            0 :     io::paths_t paths = userSoundFontDirectories();
     211            0 :     paths.push_back(globalConfiguration()->appDataPath());
     212              : 
     213            0 :     return paths;
     214            0 : }
     215              : 
     216            0 : io::paths_t AudioConfiguration::userSoundFontDirectories() const
     217              : {
     218            0 :     std::string pathsStr = settings()->value(USER_SOUNDFONTS_PATHS).toString();
     219            0 :     return io::pathsFromString(pathsStr);
     220            0 : }
     221              : 
     222            0 : void AudioConfiguration::setUserSoundFontDirectories(const io::paths_t& paths)
     223              : {
     224            0 :     settings()->setSharedValue(USER_SOUNDFONTS_PATHS, Val(io::pathsToString(paths)));
     225            0 : }
     226              : 
     227            0 : async::Channel<io::paths_t> AudioConfiguration::soundFontDirectoriesChanged() const
     228              : {
     229            0 :     return m_soundFontDirsChanged;
     230              : }
     231              : 
     232            0 : bool AudioConfiguration::autoProcessOnlineSoundsInBackground() const
     233              : {
     234            0 :     return settings()->value(ONLINE_SOUNDS_PROCESS_IN_BACKGROUND).toBool();
     235              : }
     236              : 
     237            0 : void AudioConfiguration::setAutoProcessOnlineSoundsInBackground(bool value)
     238              : {
     239            0 :     settings()->setSharedValue(ONLINE_SOUNDS_PROCESS_IN_BACKGROUND, Val(value));
     240              : 
     241            0 :     onEngineConfigChanged();
     242            0 : }
     243              : 
     244            0 : async::Channel<bool> AudioConfiguration::autoProcessOnlineSoundsInBackgroundChanged() const
     245              : {
     246            0 :     return m_autoProcessOnlineSoundsInBackgroundChanged;
     247              : }
     248              : 
     249            0 : bool AudioConfiguration::useSoundFontLowPassFilter() const
     250              : {
     251            0 :     return settings()->value(USE_SOUNDFONT_LOWPASS_FILTER).toBool();
     252              : }
     253              : 
     254            0 : void AudioConfiguration::setUseSoundFontLowPassFilter(bool value)
     255              : {
     256            0 :     settings()->setSharedValue(USE_SOUNDFONT_LOWPASS_FILTER, Val(value));
     257              : 
     258            0 :     onEngineConfigChanged();
     259            0 : }
     260              : 
     261            0 : async::Channel<bool> AudioConfiguration::useSoundFontLowPassFilterChanged() const
     262              : {
     263            0 :     return m_useSoundFontLowPassFilterChanged;
     264              : }
     265              : 
     266            0 : bool AudioConfiguration::shouldMeasureInputLag() const
     267              : {
     268            0 :     return settings()->value(AUDIO_MEASURE_INPUT_LAG).toBool();
     269              : }
        

Generated by: LCOV version 2.0-1