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 :
23 : #pragma once
24 :
25 : #include <QObject>
26 : #include <qqmlintegration.h>
27 :
28 : #include "async/asyncable.h"
29 :
30 : #include "modularity/ioc.h"
31 : #include "rcommand/icommanddispatcher.h"
32 : #include "project/iprojectsession.h"
33 : #include "interactive/iinteractive.h"
34 : #include "iplaybackconfiguration.h"
35 :
36 : #include "ui/qml/Muse/Ui/navigationpanel.h"
37 :
38 : #include "audio/common/audiotypes.h"
39 : #include "project/iprojectaudiosettings.h"
40 : #include "inputresourceitem.h"
41 : #include "outputresourceitem.h"
42 : #include "auxsenditem.h"
43 :
44 : namespace mu::playback {
45 : class MixerChannelItem : public QObject, public muse::async::Asyncable, public muse::Contextable
46 : {
47 : Q_OBJECT
48 :
49 : Q_PROPERTY(Type type READ type CONSTANT)
50 : Q_PROPERTY(bool outputOnly READ outputOnly CONSTANT)
51 :
52 : Q_PROPERTY(QString title READ title NOTIFY titleChanged)
53 :
54 : Q_PROPERTY(mu::playback::InputResourceItem * inputResourceItem READ inputResourceItem NOTIFY inputResourceItemChanged)
55 : Q_PROPERTY(
56 : QList<mu::playback::OutputResourceItem*> outputResourceItemList READ outputResourceItemList NOTIFY outputResourceItemListChanged)
57 : Q_PROPERTY(QList<mu::playback::AuxSendItem*> auxSendItemList READ auxSendItemList NOTIFY auxSendItemListChanged)
58 :
59 : Q_PROPERTY(float leftChannelPressure READ leftChannelPressure NOTIFY leftChannelPressureChanged)
60 : Q_PROPERTY(float rightChannelPressure READ rightChannelPressure NOTIFY rightChannelPressureChanged)
61 :
62 : Q_PROPERTY(float volumeLevel READ volumeLevel WRITE setVolumeLevel NOTIFY volumeLevelChanged)
63 : Q_PROPERTY(float volumeLevelMin READ volumeLevelMin CONSTANT)
64 : Q_PROPERTY(float volumeLevelMax READ volumeLevelMax CONSTANT)
65 : Q_PROPERTY(int balance READ balance WRITE setBalance NOTIFY balanceChanged)
66 : Q_PROPERTY(int balanceMin READ balanceMin CONSTANT)
67 : Q_PROPERTY(int balanceMax READ balanceMax CONSTANT)
68 : Q_PROPERTY(bool hasVolumeAutomation READ hasVolumeAutomation NOTIFY hasVolumeAutomationChanged)
69 : Q_PROPERTY(bool hasBalanceAutomation READ hasBalanceAutomation NOTIFY hasBalanceAutomationChanged)
70 : Q_PROPERTY(bool solo READ solo WRITE setSolo NOTIFY soloChanged)
71 : Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged)
72 : Q_PROPERTY(bool forceMute READ forceMute NOTIFY forceMuteChanged)
73 :
74 : Q_PROPERTY(muse::ui::NavigationPanel * panel READ panel NOTIFY panelChanged)
75 :
76 : QML_ELEMENT;
77 : QML_UNCREATABLE("Must be created in C++ only")
78 :
79 : muse::GlobalInject<IPlaybackConfiguration> configuration;
80 : muse::ContextInject<muse::IInteractive> interactive = { this };
81 : muse::ContextInject<muse::rcommand::ICommandDispatcher> commandDispatcher = { this };
82 : muse::ContextInject<project::IProjectSession> context = { this };
83 :
84 : public:
85 : enum class Type {
86 : Unknown,
87 : PrimaryInstrument,
88 : SecondaryInstrument,
89 : Metronome,
90 : Aux,
91 : Master,
92 : };
93 0 : Q_ENUM(Type)
94 :
95 0 : MixerChannelItem()
96 0 : : muse::Contextable(muse::iocCtxForQmlObject(this)) {}
97 : MixerChannelItem(QObject* parent, Type type, bool outputOnly = false, muse::audio::TrackId trackId = -1);
98 :
99 : ~MixerChannelItem() override;
100 :
101 : Type type() const;
102 :
103 : muse::audio::TrackId trackId() const;
104 :
105 : const engraving::InstrumentTrackId& instrumentTrackId() const;
106 : void setInstrumentTrackId(const engraving::InstrumentTrackId& instrumentTrackId);
107 :
108 : QString title() const;
109 :
110 : float leftChannelPressure() const;
111 : float rightChannelPressure() const;
112 :
113 : float volumeLevel() const;
114 : float volumeLevelMin() const;
115 : float volumeLevelMax() const;
116 : int balance() const;
117 : int balanceMin() const;
118 : int balanceMax() const;
119 : bool hasVolumeAutomation() const;
120 : bool hasBalanceAutomation() const;
121 : bool solo() const;
122 : bool muted() const;
123 : bool forceMute() const;
124 :
125 : muse::ui::NavigationPanel* panel() const;
126 : void setPanelOrder(int panelOrder);
127 : void setPanelSection(muse::ui::INavigationSection* section);
128 :
129 : void updateHasAutomationFlags();
130 :
131 : void setOutputResourceItemCount(size_t count);
132 :
133 : void loadInputParams(const project::AudioInputParams& newParams);
134 : void loadOutputParams(const project::AudioOutputParams& newParams);
135 : void loadSoloMuteState(const notation::INotationSoloMuteState::SoloMuteState& newState);
136 :
137 : void subscribeOnAudioSignalChanges(muse::audio::AudioSignalChanges& audioSignalChanges);
138 : void subscribeOnAutomatedControlParamsChanges(muse::audio::AutomatedControlParamsChanges& changes);
139 :
140 : bool outputOnly() const;
141 :
142 : const project::AudioInputParams& inputParams() const;
143 : const project::AudioOutputParams& outputParams() const;
144 :
145 : InputResourceItem* inputResourceItem() const;
146 : QList<OutputResourceItem*> outputResourceItemList() const;
147 : QList<AuxSendItem*> auxSendItemList() const;
148 :
149 : const QMap<muse::audio::aux_channel_idx_t, AuxSendItem*>& auxSendItems() const;
150 :
151 : public slots:
152 : void setTitle(QString title);
153 :
154 : void setLeftChannelPressure(float leftChannelPressure);
155 : void setRightChannelPressure(float rightChannelPressure);
156 :
157 : void setVolumeLevel(float volumeLevel);
158 : void setBalance(int balance);
159 : void setSolo(bool solo);
160 : void setMuted(bool mute);
161 :
162 : signals:
163 : void titleChanged(QString title);
164 :
165 : void leftChannelPressureChanged(float leftChannelPressure);
166 : void rightChannelPressureChanged(float rightChannelPressure);
167 :
168 : void volumeLevelChanged(float volumeLevel);
169 : void balanceChanged(int balance);
170 : void hasVolumeAutomationChanged();
171 : void hasBalanceAutomationChanged();
172 : void soloChanged();
173 : void mutedChanged();
174 : void forceMuteChanged();
175 :
176 : void panelChanged(muse::ui::NavigationPanel* panel);
177 :
178 : void inputParamsChanged(const project::AudioInputParams& params);
179 : void controlParamsChanged(const project::AudioOutputParams& params);
180 : void fxChainParamsChanged(const project::AudioOutputParams& params);
181 : void auxSendsParamsChanged(const project::AudioOutputParams& params);
182 : void soloMuteStateChanged(const notation::INotationSoloMuteState::SoloMuteState& state);
183 :
184 : void inputResourceItemChanged();
185 : void outputResourceItemListChanged();
186 : void auxSendItemListChanged();
187 :
188 : protected:
189 : notation::INotationPlaybackPtr notationPlayback() const;
190 :
191 : void setAudioChannelVolumePressure(const muse::audio::audioch_t chNum, const float newValue);
192 : void resetAudioChannelsVolumePressure();
193 :
194 : void applyMuteToOutputParams(const bool isMuted);
195 :
196 : void loadOutputResourceItems(const muse::audio::AudioFxChain& fxChain);
197 : void loadAuxSendItems(const muse::audio::AuxSendsParams& auxSends);
198 :
199 : InputResourceItem* buildInputResourceItem();
200 : OutputResourceItem* buildOutputResourceItem(const muse::audio::AudioFxParams& fxParams);
201 : AuxSendItem* buildAuxSendItem(muse::audio::aux_channel_idx_t index, const muse::audio::AuxSendParams& params);
202 :
203 : void addBlankSlots(size_t count);
204 : void removeBlankSlotsFromEnd(size_t count);
205 :
206 : muse::audio::AudioFxChainOrder resolveNewBlankOutputResourceItemOrder() const;
207 :
208 : void openEditor(AbstractAudioResourceItem* item, const muse::rcommand::CommandQuery& command);
209 : void closeEditor(AbstractAudioResourceItem* item);
210 :
211 : bool askAboutChangingSound();
212 :
213 : void setDisplayedVolumeLevel(float volumeLevel);
214 : void setDisplayedBalance(int balance);
215 :
216 : Type m_type = Type::Unknown;
217 :
218 : muse::audio::TrackId m_trackId = -1;
219 : engraving::InstrumentTrackId m_instrumentTrackId;
220 :
221 : project::AudioInputParams m_inputParams;
222 : project::AudioOutputParams m_outParams;
223 :
224 : float m_volumeLevel = 0.f;
225 : int m_balance = 0;
226 :
227 : bool m_hasVolumeAutomation = false;
228 : bool m_hasBalanceAutomation = false;
229 :
230 : InputResourceItem* m_inputResourceItem = nullptr;
231 : QMap<muse::audio::AudioFxChainOrder, OutputResourceItem*> m_outputResourceItems;
232 : QMap<muse::audio::aux_channel_idx_t, AuxSendItem*> m_auxSendItems;
233 :
234 : muse::audio::AudioSignalChanges m_audioSignalChanges;
235 : muse::audio::AutomatedControlParamsChanges m_automatedControlParamsChanges;
236 :
237 : QString m_title;
238 : bool m_outputOnly = false;
239 :
240 : float m_leftChannelPressure = 0.0;
241 : float m_rightChannelPressure = 0.0;
242 :
243 : muse::ui::NavigationPanel* m_panel = nullptr;
244 :
245 : bool m_outputResourceItemsLoading = false;
246 : };
247 : }
|