1 #pragma once
2 
3 #include <QObject>
4 #include <QString>
5 #include <QSharedPointer>
6 #include <QHash>
7 
8 #include "control/controlobject.h"
9 #include "engine/channelhandle.h"
10 #include "effects/defs.h"
11 
12 class EngineEffectRack;
13 class EffectsManager;
14 class EffectChainManager;
15 
16 #include "effects/effectchainslot.h"
17 
18 //TODO(Be): Remove these superfluous classes.
19 class EffectRack : public QObject {
20     Q_OBJECT
21   public:
22     EffectRack(EffectsManager* pEffectsManager,
23                EffectChainManager* pChainManager,
24                const unsigned int iRackNumber,
25                const QString& group, SignalProcessingStage stage);
26     virtual ~EffectRack();
27 
28     void addToEngine();
29     void removeFromEngine();
30     EngineEffectRack* getEngineEffectRack();
31 
32     void registerInputChannel(const ChannelHandleAndGroup& handle_group);
33     int numEffectChainSlots() const;
34     EffectChainSlotPointer getEffectChainSlot(int i);
35 
36     void maybeLoadEffect(const unsigned int iChainSlotNumber,
37                          const unsigned int iEffectSlotNumber,
38                          const QString& id);
39 
getRackNumber()40     unsigned int getRackNumber() const {
41         return m_iRackNumber;
42     }
43 
getGroup()44     const QString& getGroup() const {
45         return m_group;
46     }
47 
48     void refresh();
49 
50     QDomElement toXml(QDomDocument* doc) const;
51 
52     virtual bool isAdoptMetaknobValueEnabled() const;
53 
54   public slots:
55     void slotClearRack(double v);
56 
57     void loadNextChain(const unsigned int iChainSlotNumber,
58                        EffectChainPointer pLoadedChain);
59     void loadPrevChain(const unsigned int iChainSlotNumber,
60                        EffectChainPointer pLoadedChain);
61 
62     void loadNextEffect(const unsigned int iChainSlotNumber,
63                         const unsigned int iEffectSlotNumber,
64                         EffectPointer pEffect);
65     void loadPrevEffect(const unsigned int iChainSlotNumber,
66                         const unsigned int iEffectSlotNumber,
67                         EffectPointer pEffect);
68 
69   protected:
70     void addEffectChainSlotInternal(EffectChainSlotPointer pChainSlot);
71 
72     EngineEffectRack* m_pEngineEffectRack;
73 
74     // We could make accessors for these for sub-classes. Doesn't really matter.
75     EffectsManager* m_pEffectsManager;
76     EffectChainManager* m_pEffectChainManager;
77 
78   private:
79     SignalProcessingStage m_signalProcessingStage;
80     const unsigned int m_iRackNumber;
81     const QString m_group;
82     QList<EffectChainSlotPointer> m_effectChainSlots;
83     ControlObject m_controlNumEffectChainSlots;
84     ControlObject m_controlClearRack;
85 };
86 
87 class StandardEffectRack : public EffectRack {
88     Q_OBJECT
89   public:
90     StandardEffectRack(EffectsManager* pEffectsManager,
91                        EffectChainManager* pChainManager,
92                        const unsigned int iRackNumber);
~StandardEffectRack()93     virtual ~StandardEffectRack() {}
94 
formatGroupString(const unsigned int iRackNumber)95     static QString formatGroupString(const unsigned int iRackNumber) {
96         return QString("[EffectRack%1]").arg(QString::number(iRackNumber + 1));
97     }
98 
formatEffectChainSlotGroupString(const unsigned int iRackNumber,const unsigned int iChainSlotNumber)99     static QString formatEffectChainSlotGroupString(const unsigned int iRackNumber,
100                                                     const unsigned int iChainSlotNumber) {
101         return QString("[EffectRack%1_EffectUnit%2]")
102                 .arg(QString::number(iRackNumber + 1),
103                         QString::number(iChainSlotNumber + 1));
104     }
105 
formatEffectSlotGroupString(const unsigned int iRackNumber,const unsigned int iChainSlotNumber,const unsigned int iEffectSlotNumber)106     static QString formatEffectSlotGroupString(const unsigned int iRackNumber,
107                                                const unsigned int iChainSlotNumber,
108                                                const unsigned int iEffectSlotNumber) {
109         return QString("[EffectRack%1_EffectUnit%2_Effect%3]")
110                 .arg(QString::number(iRackNumber + 1),
111                         QString::number(iChainSlotNumber + 1),
112                         QString::number(iEffectSlotNumber + 1));
113     }
114 
115     EffectChainSlotPointer addEffectChainSlot();
116 };
117 
118 class OutputEffectRack : public EffectRack {
119     Q_OBJECT
120   public:
121     OutputEffectRack(EffectsManager* pEffectsManager,
122                      EffectChainManager* pChainManager);
~OutputEffectRack()123     virtual ~OutputEffectRack() {};
124 };
125 
126 class PerGroupRack : public EffectRack {
127     Q_OBJECT
128   public:
129     PerGroupRack(EffectsManager* pEffectsManager,
130                  EffectChainManager* pChainManager,
131                  const unsigned int iRackNumber,
132                  const QString& group);
~PerGroupRack()133     virtual ~PerGroupRack() {}
134 
135 
136     void setupForGroup(const QString& group);
137     EffectChainSlotPointer getGroupEffectChainSlot(const QString& group);
138     virtual bool loadEffectToGroup(const QString& group, EffectPointer pEffect);
139 
140   protected:
141     virtual void configureEffectChainSlotForGroup(EffectChainSlotPointer pSlot,
142                                                   const QString& group) = 0;
143 
144     virtual QString formatEffectChainSlotGroupForGroup(const unsigned int iRackNumber,
145                                                        const unsigned int iChainSlotNumber,
146                                                        const QString& group) const = 0;
147 
148     virtual QString formatEffectSlotGroupString(const unsigned int iEffectSlotNumber,
149                                                 const QString& group) const = 0;
150 
151   private:
152     QHash<QString, EffectChainSlotPointer> m_groupToChainSlot;
153 };
154 
155 class QuickEffectRack : public PerGroupRack {
156     Q_OBJECT
157   public:
158     QuickEffectRack(EffectsManager* pEffectsManager,
159                     EffectChainManager* pChainManager,
160                     const unsigned int iRackNumber);
~QuickEffectRack()161     virtual ~QuickEffectRack() {}
162 
163     bool loadEffectToGroup(const QString& group, EffectPointer pEffect) override;
164 
formatGroupString(const unsigned int iRackNumber)165     static QString formatGroupString(const unsigned int iRackNumber) {
166         return QString("[QuickEffectRack%1]").arg(QString::number(iRackNumber + 1));
167     }
168 
formatEffectChainSlotGroupString(const unsigned int iRackNumber,const QString & group)169     static QString formatEffectChainSlotGroupString(const unsigned int iRackNumber,
170                                                     const QString& group) {
171         return QString("[QuickEffectRack%1_%2]").arg(QString::number(iRackNumber + 1), group);
172     }
173 
formatEffectSlotGroupString(const unsigned int iRackNumber,const unsigned int iEffectSlotNumber,const QString & group)174     static QString formatEffectSlotGroupString(const unsigned int iRackNumber,
175                                                const unsigned int iEffectSlotNumber,
176                                                const QString& group) {
177         return QString("[QuickEffectRack%1_%2_Effect%3]")
178                 .arg(QString::number(iRackNumber + 1),
179                         group,
180                         QString::number(iEffectSlotNumber + 1));
181     }
182 
formatEffectSlotGroupString(const unsigned int iEffectSlotNumber,const QString & group)183     QString formatEffectSlotGroupString(const unsigned int iEffectSlotNumber,
184                                         const QString& group) const override {
185         return formatEffectSlotGroupString(getRackNumber(), iEffectSlotNumber,
186                                            group);
187     }
188 
isAdoptMetaknobValueEnabled()189     bool isAdoptMetaknobValueEnabled() const override {
190         // No visible Metaknobs to adopt
191         return false;
192     }
193 
194   protected:
195     void configureEffectChainSlotForGroup(EffectChainSlotPointer pSlot,
196                                           const QString& group) override;
197 
formatEffectChainSlotGroupForGroup(const unsigned int iRackNumber,const unsigned int iChainSlotNumber,const QString & group)198     QString formatEffectChainSlotGroupForGroup(const unsigned int iRackNumber,
199                                                const unsigned int iChainSlotNumber,
200                                                const QString& group) const override {
201         Q_UNUSED(iChainSlotNumber);
202         return formatEffectChainSlotGroupString(iRackNumber, group);
203     }
204 };
205 
206 class EqualizerRack : public PerGroupRack {
207     Q_OBJECT
208   public:
209     EqualizerRack(EffectsManager* pEffectsManager,
210                   EffectChainManager* pChainManager,
211                   const unsigned int iRackNumber);
~EqualizerRack()212     virtual ~EqualizerRack() {}
213 
formatGroupString(const unsigned int iRackNumber)214     static QString formatGroupString(const unsigned int iRackNumber) {
215         return QString("[EqualizerRack%1]").arg(QString::number(iRackNumber + 1));
216     }
217 
formatEffectChainSlotGroupString(const unsigned int iRackNumber,const QString & group)218     static QString formatEffectChainSlotGroupString(const unsigned int iRackNumber,
219                                                     const QString& group) {
220         return QString("[EqualizerRack%1_%2]").arg(QString::number(iRackNumber + 1), group);
221     }
222 
formatEffectSlotGroupString(const unsigned int iRackNumber,const unsigned int iEffectSlotNumber,const QString & group)223     static QString formatEffectSlotGroupString(const unsigned int iRackNumber,
224                                                const unsigned int iEffectSlotNumber,
225                                                const QString& group) {
226         return QString("[EqualizerRack%1_%2_Effect%3]")
227                 .arg(QString::number(iRackNumber + 1),
228                         group,
229                         QString::number(iEffectSlotNumber + 1));
230     }
231 
formatEffectSlotGroupString(const unsigned int iEffectSlotNumber,const QString & group)232     QString formatEffectSlotGroupString(const unsigned int iEffectSlotNumber,
233                                         const QString& group) const override {
234         return formatEffectSlotGroupString(getRackNumber(), iEffectSlotNumber,
235                                            group);
236     }
237 
isAdoptMetaknobValueEnabled()238     bool isAdoptMetaknobValueEnabled() const override {
239         // No visible Metaknobs to adopt
240         return false;
241     }
242 
243   protected:
244     void configureEffectChainSlotForGroup(EffectChainSlotPointer pSlot,
245                                           const QString& group) override;
formatEffectChainSlotGroupForGroup(const unsigned int iRackNumber,const unsigned int iChainSlotNumber,const QString & group)246     QString formatEffectChainSlotGroupForGroup(const unsigned int iRackNumber,
247                                                const unsigned int iChainSlotNumber,
248                                                const QString& group) const override {
249         Q_UNUSED(iChainSlotNumber);
250         return formatEffectChainSlotGroupString(iRackNumber, group);
251     }
252 };
253