LCOV - code coverage report
Current view: top level - muse/framework/audio/engine/internal/nodes - eventaudionode.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 108 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              : 
      23              : #include "eventaudionode.h"
      24              : 
      25              : #include "audio/common/audiosanitizer.h"
      26              : 
      27              : #include "log.h"
      28              : 
      29              : using namespace muse;
      30              : using namespace muse::audio;
      31              : using namespace muse::audio::engine;
      32              : using namespace muse::audio::synth;
      33              : using namespace muse::mpe;
      34              : 
      35            0 : EventAudioNode::EventAudioNode(TrackId trackId, const mpe::PlaybackData& playbackData,
      36            0 :                                OnOffStreamEventsReceived onOffStreamReceived)
      37            0 :     : m_trackId(trackId), m_playbackData(playbackData)
      38              : {
      39              :     ONLY_AUDIO_ENGINE_THREAD;
      40              : 
      41            0 :     if (onOffStreamReceived) {
      42            0 :         m_playbackData.offStream.onReceive(this, [onOffStreamReceived](const PlaybackEventsMap&,
      43              :                                                                        bool) {
      44            0 :             onOffStreamReceived();
      45            0 :         });
      46              :     }
      47            0 : }
      48              : 
      49            0 : EventAudioNode::~EventAudioNode()
      50              : {
      51            0 :     m_playbackData.offStream.disconnect(this);
      52            0 : }
      53              : 
      54            0 : void EventAudioNode::onModeChanged(const ProcessMode mode)
      55              : {
      56              :     ONLY_AUDIO_ENGINE_THREAD;
      57              : 
      58            0 :     if (!m_synth) {
      59            0 :         return;
      60              :     }
      61              : 
      62            0 :     m_synth->setMode(mode);
      63            0 :     m_synth->flushSound();
      64              : }
      65              : 
      66            0 : void EventAudioNode::onOutputSpecChanged(const OutputSpec& spec)
      67              : {
      68              :     ONLY_AUDIO_ENGINE_THREAD;
      69            0 :     if (!m_synth) {
      70            0 :         return;
      71              :     }
      72              : 
      73            0 :     m_synth->setOutputSpec(spec);
      74              : }
      75              : 
      76            0 : void EventAudioNode::doSelfProcess(float* buffer, samples_t samplesPerChannel)
      77              : {
      78              :     ONLY_AUDIO_PROC_THREAD;
      79            0 :     if (!m_synth) {
      80            0 :         return;
      81              :     }
      82              : 
      83            0 :     m_synth->process(buffer, samplesPerChannel);
      84              : }
      85              : 
      86            0 : void EventAudioNode::seek(const TimePosition& position, const bool flushSound)
      87              : {
      88              :     ONLY_AUDIO_ENGINE_THREAD;
      89              : 
      90            0 :     IF_ASSERT_FAILED(m_synth) {
      91            0 :         return;
      92              :     }
      93              : 
      94            0 :     if (m_synth->playbackPosition() == position) {
      95            0 :         return;
      96              :     }
      97              : 
      98            0 :     m_synth->setPlaybackPosition(position);
      99              : 
     100            0 :     if (flushSound) {
     101            0 :         m_synth->flushSound();
     102              :     }
     103              : }
     104              : 
     105            0 : void EventAudioNode::flush()
     106              : {
     107              :     ONLY_AUDIO_ENGINE_THREAD;
     108              : 
     109            0 :     IF_ASSERT_FAILED(m_synth) {
     110            0 :         return;
     111              :     }
     112              : 
     113            0 :     m_synth->flushSound();
     114              : }
     115              : 
     116            0 : const AudioInputParams& EventAudioNode::inputParams() const
     117              : {
     118            0 :     return m_params;
     119              : }
     120              : 
     121            0 : void EventAudioNode::applyInputParams(const AudioInputParams& requiredParams)
     122              : {
     123            0 :     IF_ASSERT_FAILED(m_outputSpec.isValid()) {
     124            0 :         return;
     125              :     }
     126              : 
     127            0 :     if (m_params.isValid() && m_params == requiredParams) {
     128            0 :         return;
     129              :     }
     130              : 
     131            0 :     SynthCtx ctx = currentSynthCtx();
     132              : 
     133            0 :     if (m_synth) {
     134            0 :         m_playbackData = m_synth->playbackData();
     135              :     }
     136              : 
     137            0 :     RetVal<synth::ISynthesizerPtr> synth = audioFactory()->makeSynth(m_trackId, requiredParams, m_playbackData.setupData);
     138              : 
     139            0 :     if (!synth.ret) {
     140            0 :         synth = audioFactory()->makeDefaultSynth(m_trackId);
     141            0 :         IF_ASSERT_FAILED(synth.val) {
     142            0 :             LOGE() << "Default synth not found!";
     143            0 :             return;
     144              :         }
     145              :     }
     146              : 
     147            0 :     m_synth = synth.val;
     148              : 
     149            0 :     m_synth->paramsChanged().onReceive(this, [this](const AudioInputParams& params) {
     150            0 :         m_paramsChanges.send(params);
     151            0 :     });
     152              : 
     153            0 :     setupSource();
     154              : 
     155            0 :     if (ctx.isValid()) {
     156            0 :         restoreSynthCtx(ctx);
     157              :     } else {
     158            0 :         m_synth->setMode(ProcessMode::Idle);
     159              :     }
     160              : 
     161            0 :     setName(std::string("Source[") + m_synth->name() + "]");
     162              : 
     163            0 :     m_params = m_synth->params();
     164            0 :     m_paramsChanges.send(m_params);
     165            0 : }
     166              : 
     167            0 : async::Channel<AudioInputParams> EventAudioNode::inputParamsChanged() const
     168              : {
     169            0 :     return m_paramsChanges;
     170              : }
     171              : 
     172            0 : void EventAudioNode::prepareToPlay()
     173              : {
     174              :     ONLY_AUDIO_ENGINE_THREAD;
     175              : 
     176            0 :     IF_ASSERT_FAILED(m_synth) {
     177            0 :         return;
     178              :     }
     179              : 
     180            0 :     m_synth->prepareToPlay();
     181              : }
     182              : 
     183            0 : bool EventAudioNode::readyToPlay() const
     184              : {
     185              :     ONLY_AUDIO_ENGINE_THREAD;
     186              : 
     187            0 :     IF_ASSERT_FAILED(m_synth) {
     188            0 :         return false;
     189              :     }
     190              : 
     191            0 :     return m_synth->readyToPlay();
     192              : }
     193              : 
     194            0 : async::Notification EventAudioNode::readyToPlayChanged() const
     195              : {
     196              :     ONLY_AUDIO_ENGINE_THREAD;
     197              : 
     198            0 :     IF_ASSERT_FAILED(m_synth) {
     199            0 :         return {};
     200              :     }
     201              : 
     202            0 :     return m_synth->readyToPlayChanged();
     203              : }
     204              : 
     205            0 : bool EventAudioNode::hasPendingChunks() const
     206              : {
     207              :     ONLY_AUDIO_ENGINE_THREAD;
     208              : 
     209            0 :     IF_ASSERT_FAILED(m_synth) {
     210            0 :         return false;
     211              :     }
     212              : 
     213            0 :     return m_synth->hasPendingChunks();
     214              : }
     215              : 
     216            0 : void EventAudioNode::processInput()
     217              : {
     218              :     ONLY_AUDIO_ENGINE_THREAD;
     219              : 
     220            0 :     IF_ASSERT_FAILED(m_synth) {
     221            0 :         return;
     222              :     }
     223              : 
     224            0 :     m_synth->processInput();
     225              : }
     226              : 
     227            0 : InputProcessingProgress EventAudioNode::inputProcessingProgress() const
     228              : {
     229              :     ONLY_AUDIO_ENGINE_THREAD;
     230              : 
     231            0 :     IF_ASSERT_FAILED(m_synth) {
     232            0 :         return {};
     233              :     }
     234              : 
     235            0 :     return m_synth->inputProcessingProgress();
     236            0 : }
     237              : 
     238            0 : void EventAudioNode::clearCache()
     239              : {
     240              :     ONLY_AUDIO_ENGINE_THREAD;
     241              : 
     242            0 :     IF_ASSERT_FAILED(m_synth) {
     243            0 :         return;
     244              :     }
     245              : 
     246            0 :     m_synth->clearCache();
     247              : }
     248              : 
     249            0 : EventAudioNode::SynthCtx EventAudioNode::currentSynthCtx() const
     250              : {
     251            0 :     if (!m_synth) {
     252            0 :         return SynthCtx();
     253              :     }
     254              : 
     255            0 :     return { m_synth->mode(), m_synth->playbackPosition() };
     256              : }
     257              : 
     258            0 : void EventAudioNode::restoreSynthCtx(const SynthCtx& ctx)
     259              : {
     260            0 :     m_synth->setPlaybackPosition(ctx.playbackPosition);
     261            0 :     m_synth->setMode(ctx.mode);
     262            0 : }
     263              : 
     264            0 : void EventAudioNode::setupSource()
     265              : {
     266              :     ONLY_AUDIO_ENGINE_THREAD;
     267              : 
     268            0 :     IF_ASSERT_FAILED(m_synth) {
     269            0 :         return;
     270              :     }
     271              : 
     272            0 :     m_synth->setOutputSpec(m_outputSpec);
     273            0 :     m_synth->setup(m_playbackData);
     274              : }
        

Generated by: LCOV version 2.0-1