1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: ctrl.h,v 1.4.2.2 2006/10/29 07:54:51 terminator356 Exp $
5 //
6 //    controller for mixer automation
7 //
8 //  (C) Copyright 2003-2004 Werner Schweer (ws@seh.de)
9 //  (C) Copyright 2011-2013 Tim E. Real (terminator356 on users dot sourceforge dot net)
10 //
11 //  This program is free software; you can redistribute it and/or
12 //  modify it under the terms of the GNU General Public License
13 //  as published by the Free Software Foundation; version 2 of
14 //  the License, or (at your option) any later version.
15 //
16 //  This program is distributed in the hope that it will be useful,
17 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 //  GNU General Public License for more details.
20 //
21 //  You should have received a copy of the GNU General Public License
22 //  along with this program; if not, write to the Free Software
23 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
24 //
25 //=========================================================
26 
27 #ifndef __CTRL_H__
28 #define __CTRL_H__
29 
30 #include <map>
31 #include <list>
32 #include <vector>
33 #include <QColor>
34 #include <QString>
35 
36 #ifdef OSC_SUPPORT
37 #include <lo/lo_osc_types.h>
38 #else
39 #include <stdint.h>
40 #endif
41 
42 #define AC_PLUGIN_CTL_BASE         0x1000
43 #define AC_PLUGIN_CTL_BASE_POW     12
44 #define AC_PLUGIN_CTL_ID_MASK      0xFFF
45 
46 namespace MusECore {
47 
48 
49 // Forward declarations:
50 class Xml;
51 
52 const int AC_VOLUME = 0;
53 const int AC_PAN    = 1;
54 const int AC_MUTE   = 2;
55 
genACnum(unsigned long plugin,unsigned long ctrl)56 inline unsigned long genACnum(unsigned long plugin, unsigned long ctrl) { return (plugin + 1) * AC_PLUGIN_CTL_BASE + ctrl; }
57 
58 enum CtrlValueType { VAL_LOG, VAL_LINEAR, VAL_INT, VAL_BOOL, VAL_ENUM };
59 enum CtrlRecValueType { ARVT_VAL, ARVT_START, ARVT_STOP };
60 
61 typedef std::map<float, QString> CtrlEnumValues;
62 
63 //---------------------------------------------------------
64 //   CtrlInterpolate
65 //    Controller interpolation values.
66 //    For speed: Can be filled once by CtrlList::getInterpolation(),
67 //     then passed repeatedly to CtrlList::interpolate().
68 //---------------------------------------------------------
69 
70 struct CtrlInterpolate {
71       unsigned int sFrame; // Starting frame. Always valid. Can be less than any first CtrlList item's frame, or zero !
72       double sVal;       // Value at starting frame.
73       unsigned int eFrame; // Ending frame if eFrameValid is true.
74       bool   eFrameValid; // True if eFrame is valid. False if endless, eFrame is invalid.
75       double eVal;       // Value at ending frame, or sVal if eFrameValid is false.
76       bool   eStop;      // Whether to stop refreshing this struct from CtrlList upon eFrame. Control FIFO ring buffers
77                          //  set this true and replace eFrame and eVal. Upon the next run slice, if eStop is set, eval
78                          //  should be copied to sVal, eFrame to sFrame, doInterp cleared, and eFrame set to some frame or eFrameValid false.
79       bool   doInterp;   // Whether to actually interpolate whenever this struct is passed to CtrlList::interpolate().
80       CtrlInterpolate(unsigned int sframe = 0, unsigned int eframe = 0, bool eframevalid = false, double sval = 0.0, double eval = 0.0,
81                       bool end_stop = false, bool do_interpolate = false) {
82             sFrame = sframe;
83             sVal   = sval;
84             eFrame = eframe;
85             eFrameValid = eframevalid;
86             eVal   = eval;
87             eStop = end_stop;
88             doInterp = do_interpolate;
89             }
90       };
91 
92 //---------------------------------------------------------
93 //   CtrlVal
94 //    controller "event"
95 //---------------------------------------------------------
96 
97 struct CtrlVal {
98       unsigned int frame;
99       double val;
CtrlValCtrlVal100       CtrlVal(unsigned int f, double v) {
101             frame = f;
102             val   = v;
103             }
104       };
105 
106 //---------------------------------------------------------
107 //   CtrlRecVal
108 //    recorded controller event, mixer automation
109 //---------------------------------------------------------
110 
111 struct CtrlRecVal : public CtrlVal {
112       int id;
113       CtrlRecValueType type;   // 0 - ctrlVal, 1 - start, 2 - end
CtrlRecValCtrlRecVal114       CtrlRecVal(unsigned int f, int n, double v) : CtrlVal(f, v), id(n), type(ARVT_VAL) {}
CtrlRecValCtrlRecVal115       CtrlRecVal(unsigned int f, int n, double v, CtrlRecValueType t) : CtrlVal(f, v), id(n), type(t) {}
116       };
117 
118 //---------------------------------------------------------
119 //   CtrlRecList
120 //---------------------------------------------------------
121 
122 class CtrlRecList : public std::list<CtrlRecVal> {
123    public:
124       };
125 
126 typedef CtrlRecList::iterator iCtrlRec;
127 typedef CtrlRecList::const_iterator ciCtrlRec;
128 
129 //---------------------------------------------------------
130 //   MidiAudioCtrlMap
131 //    Describes midi control of audio controllers
132 //---------------------------------------------------------
133 
134 class MidiAudioCtrlStruct {
135         int _audio_ctrl_id;
136   public:
137         MidiAudioCtrlStruct();
138         MidiAudioCtrlStruct(int audio_ctrl_id);
audioCtrlId()139         int audioCtrlId() const        { return _audio_ctrl_id; }
setAudioCtrlId(int actrl)140         void setAudioCtrlId(int actrl) { _audio_ctrl_id = actrl; }
141       };
142 
143 typedef uint32_t MidiAudioCtrlMap_idx_t;
144 
145 typedef std::multimap<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct, std::less<MidiAudioCtrlMap_idx_t> >::iterator iMidiAudioCtrlMap;
146 typedef std::multimap<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct, std::less<MidiAudioCtrlMap_idx_t> >::const_iterator ciMidiAudioCtrlMap;
147 
148 // Reverse lookup based on audio control.
149 typedef std::vector<iMidiAudioCtrlMap>::iterator iAudioMidiCtrlStructMap;
150 typedef std::vector<iMidiAudioCtrlMap>::const_iterator ciAudioMidiCtrlStructMap;
151 class AudioMidiCtrlStructMap : public std::vector<iMidiAudioCtrlMap> {
152   public:
153 
154      };
155 
156 // Midi to audio controller map.
157 // The index is a hash of port, chan, and midi control number.
158 class MidiAudioCtrlMap : public std::multimap<MidiAudioCtrlMap_idx_t, MidiAudioCtrlStruct, std::less<MidiAudioCtrlMap_idx_t> > {
159   public:
160       MidiAudioCtrlMap_idx_t index_hash(int midi_port, int midi_chan, int midi_ctrl_num) const;
161       void hash_values(MidiAudioCtrlMap_idx_t hash, int* midi_port, int* midi_chan, int* midi_ctrl_num) const;
162       iMidiAudioCtrlMap add_ctrl_struct(int midi_port, int midi_chan, int midi_ctrl_num, const MidiAudioCtrlStruct& amcs);
163       void find_audio_ctrl_structs(int audio_ctrl_id, AudioMidiCtrlStructMap* amcs); // const;
164       void erase_ctrl_struct(int midi_port, int midi_chan, int midi_ctrl_num, int audio_ctrl_id);
165       void write(int level, Xml& xml) const;
166       void read(Xml& xml);
167       };
168 
169 
170 //---------------------------------------------------------
171 //   CtrlList
172 //    arrange controller events of a specific type in a
173 //    list for easy retrieval
174 //---------------------------------------------------------
175 
176 typedef std::map<unsigned int, CtrlVal, std::less<unsigned int> > CtrlList_t;
177 typedef std::pair<unsigned int, CtrlVal> CtrlListInsertPair_t;
178 
179 class CtrlList : public CtrlList_t {
180    public:
181       enum Mode { INTERPOLATE, DISCRETE};
182       enum AssignFlags { ASSIGN_PROPERTIES=1, ASSIGN_VALUES=2 };  // Can be or'd together.
183    private:
184       Mode _mode;
185       int _id;
186       double _default;
187       double _curVal;
188       void del(CtrlVal);
189       QString _name;
190       double _min, _max;
191       CtrlValueType _valueType;
192       QColor _displayColor;
193       bool _visible;
194       bool _dontShow; // when this is true the control exists but is not compatible with viewing in the arranger
195       volatile bool _guiUpdatePending; // Gui heartbeat routines read this. Checked and cleared in Song::beat().
196       void initColor(int i);
197 
198    public:
199       CtrlList(bool dontShow=false);
200       CtrlList(int id, bool dontShow=false);
201       CtrlList(int id, QString name, double min, double max, CtrlValueType v, bool dontShow=false);
202       CtrlList(const CtrlList& l, int flags);
203       void assign(const CtrlList& l, int flags);
204 
205       void swap(CtrlList&);
206       std::pair<iterator, bool> insert(const CtrlListInsertPair_t& p);
207       iterator insert(iterator ic, const CtrlListInsertPair_t& p);
208       void insert(iterator first, iterator last);
209       void erase(iterator ictl);
210       size_type erase(unsigned int frame);
211       void erase(iterator first, iterator last);
212       void clear();
213       CtrlList& operator=(const CtrlList&);
214 
mode()215       Mode mode() const          { return _mode; }
setMode(Mode m)216       void setMode(Mode m)       { _mode = m; }
getDefault()217       double getDefault() const   { return _default; }
setDefault(double val)218       void setDefault(double val) { _default = val; }
219       double curVal() const;
220       void updateCurValue(unsigned int frame);
221       void setCurVal(double val);
id()222       int id() const             { return _id; }
name()223       QString name() const       { return _name; }
setName(const QString & s)224       void setName(const QString& s) { _name = s; }
minVal()225       double minVal() const { return _min; }
maxVal()226       double maxVal() const { return _max; }
setRange(double min,double max)227       void setRange(double min, double max) {
228             _min = min;
229             _max = max;
230             }
range(double * min,double * max)231       void range(double* min, double* max) const {
232             *min = _min;
233             *max = _max;
234             }
valueType()235       CtrlValueType valueType() const { return _valueType; }
setValueType(CtrlValueType t)236       void setValueType(CtrlValueType t) { _valueType = t; }
237       void getInterpolation(unsigned int frame, bool cur_val_only, CtrlInterpolate* interp);
238       double interpolate(unsigned int frame, const CtrlInterpolate& interp);
239 
240       double value(unsigned int frame, bool cur_val_only = false,
241                    unsigned int* nextFrame = NULL, bool* nextFrameValid = NULL) const;
242       void add(unsigned int frame, double value);
243       void del(unsigned int frame);
244       void read(Xml& xml);
245 
setColor(QColor c)246       void setColor( QColor c ) { _displayColor = c;}
color()247       QColor color() const { return _displayColor; }
setVisible(bool v)248       void setVisible(bool v) { _visible = v; }
isVisible()249       bool isVisible() const { return _visible; }
dontShow()250       bool dontShow() const { return _dontShow; }
guiUpdatePending()251       bool guiUpdatePending() const { return _guiUpdatePending; }
setGuiUpdatePending(bool v)252       void setGuiUpdatePending(bool v) { _guiUpdatePending = v; }
253       };
254 
255 typedef CtrlList::iterator iCtrl;
256 typedef CtrlList::const_iterator ciCtrl;
257 
258 //---------------------------------------------------------
259 //   CtrlListList
260 //    List of controller value lists.
261 //    This list represents the controller state of a
262 //    mixer strip
263 //---------------------------------------------------------
264 
265 typedef std::map<int, CtrlList*, std::less<int> >::iterator iCtrlList;
266 typedef std::map<int, CtrlList*, std::less<int> >::const_iterator ciCtrlList;
267 
268 class CtrlListList : public std::map<int, CtrlList*, std::less<int> > {
269    private:
270       MidiAudioCtrlMap _midi_controls;  // For midi control of audio controllers.
271    public:
272       void add(CtrlList* vl);
clearDelete()273       void clearDelete() {
274             for(iCtrlList i = begin(); i != end(); ++i)
275               delete i->second;
276             clear();
277            }
278 
find(int id)279       iCtrlList find(int id) {
280             return std::map<int, CtrlList*, std::less<int> >::find(id);
281             }
find(int id)282       ciCtrlList find(int id) const {
283             return std::map<int, CtrlList*, std::less<int> >::find(id);
284             }
285 
midiControls()286       MidiAudioCtrlMap* midiControls() { return &_midi_controls; }
287 
288       double value(int ctrlId, unsigned int frame, bool cur_val_only = false,
289                    unsigned int* nextFrame = NULL, bool* nextFrameValid = NULL) const;
290       void updateCurValues(unsigned int frame);
clearAllAutomation()291       void clearAllAutomation() {
292             for(iCtrlList i = begin(); i != end(); ++i)
293               i->second->clear();
294            }
295       void write(int level, Xml& xml) const;
296       };
297 
298 extern double midi2AudioCtrlValue(const CtrlList* audio_ctrl_list, const MidiAudioCtrlStruct* mapper, int midi_ctlnum, int midi_val);
299 
300 } // namespace MusECore
301 
302 #endif
303 
304