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) 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 :
23 : #pragma once
24 :
25 : #include <memory>
26 :
27 : #include "common/iaudiotaskscheduler.h"
28 : #include "global/modularity/ioc.h"
29 : #include "global/async/asyncable.h"
30 :
31 : #include "iaudiofactory.h"
32 :
33 : #include "nodes/trackchain.h"
34 :
35 : #include "muse_framework_config.h"
36 : namespace muse {
37 : class TaskScheduler;
38 : }
39 :
40 : namespace muse::audio {
41 : struct ContextMixerTag
42 : {
43 : static constexpr const char* name = "ContextMixer";
44 : };
45 : }
46 :
47 : namespace muse::audio::engine {
48 : class Mixer : public AudioNode<ContextMixerTag>, public async::Asyncable
49 : {
50 : GlobalInject<IAudioFactory> audioFactory;
51 : #ifdef MUSE_THREADS_SUPPORT
52 : GlobalInject<IAudioTaskScheduler> audioTaskScheduler;
53 : #endif
54 :
55 : public:
56 : ~Mixer() override;
57 :
58 : void init();
59 :
60 : Ret addTrack(TrackChainPtr trackChain, const AuxSendsParams& auxSends);
61 : Ret addAuxTrack(TrackChainPtr trackChain);
62 : Ret removeTrack(const TrackId trackId);
63 :
64 : void setAuxSends(const TrackId trackId, const AuxSendsParams& auxSends);
65 :
66 : void setTracksToProcessWhenIdle(const std::unordered_set<TrackId>& trackIds);
67 : void setNonMutedTrackCount(size_t count);
68 :
69 : void process(float* buffer, samples_t samplesPerChannel) override;
70 :
71 : std::string dump() const override;
72 :
73 : private:
74 :
75 : void onOutputSpecChanged(const OutputSpec& spec) override;
76 : void onModeChanged(const ProcessMode mode) override;
77 :
78 0 : void doSelfProcess(float*, samples_t) override {}
79 :
80 : void processTrackChannels(size_t outBufferSize, size_t samplesPerChannel);
81 : void mixOutputFromChannel(float* outBuffer, const float* inBuffer, size_t bufferSize) const;
82 : void prepareAuxBuffers(size_t outBufferSize);
83 : void writeTrackToAuxBuffers(const float* trackBuffer, size_t outBufferSize, const AuxSendsParams& auxSends);
84 : void processAuxChannels(float* buffer, samples_t samplesPerChannel);
85 :
86 : bool useMultithreading() const;
87 :
88 : struct TrackData {
89 : TrackId trackId;
90 : TrackChainPtr chain;
91 : std::vector<float> buffer;
92 : bool processed = false;
93 : };
94 :
95 : std::vector<TrackData> m_tracks;
96 : std::vector<TrackData> m_auxTracks;
97 : std::map<TrackId, AuxSendsParams> m_auxSends;
98 :
99 : std::vector<IAudioTaskScheduler::Task> m_trackTasks;
100 :
101 : size_t m_nonMutedTrackCount = 0;
102 : std::unordered_set<TrackId> m_tracksToProcessWhenIdle;
103 : };
104 :
105 : using MixerPtr = std::shared_ptr<Mixer>;
106 : }
|