andrewm@0
|
1 /*
|
andrewm@0
|
2 TouchKeys: multi-touch musical keyboard control software
|
andrewm@0
|
3 Copyright (c) 2013 Andrew McPherson
|
andrewm@0
|
4
|
andrewm@0
|
5 This program is free software: you can redistribute it and/or modify
|
andrewm@0
|
6 it under the terms of the GNU General Public License as published by
|
andrewm@0
|
7 the Free Software Foundation, either version 3 of the License, or
|
andrewm@0
|
8 (at your option) any later version.
|
andrewm@0
|
9
|
andrewm@0
|
10 This program is distributed in the hope that it will be useful,
|
andrewm@0
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
andrewm@0
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
andrewm@0
|
13 GNU General Public License for more details.
|
andrewm@0
|
14
|
andrewm@0
|
15 You should have received a copy of the GNU General Public License
|
andrewm@0
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
andrewm@0
|
17
|
andrewm@0
|
18 =====================================================================
|
andrewm@0
|
19
|
andrewm@0
|
20 MappingFactory.h: base class for creating mappings. A factory is a singular
|
andrewm@0
|
21 object, attached to a particular keyboard segment, which in turn allocates
|
andrewm@0
|
22 and destroys individual Mapping objects for each active note. The factory
|
andrewm@0
|
23 also is the usual point at which parameter changes are made.
|
andrewm@0
|
24 */
|
andrewm@0
|
25
|
andrewm@0
|
26 #ifndef __touchkeys__MappingFactory__
|
andrewm@0
|
27 #define __touchkeys__MappingFactory__
|
andrewm@0
|
28
|
andrewm@0
|
29 #include <map>
|
andrewm@0
|
30 #include <boost/bind.hpp>
|
andrewm@0
|
31 #include "Mapping.h"
|
andrewm@0
|
32 #include "../GUI/MappingEditorComponent.h"
|
andrewm@0
|
33
|
andrewm@0
|
34 // This virtual base class defines a singular factory object from which individual
|
andrewm@0
|
35 // instances of mapping objects can be created and destroyed. How the mappings are
|
andrewm@0
|
36 // allocated and when is up to the factory, which also keeps track of which ones
|
andrewm@0
|
37 // are active. The PianoKey class will call into any active factories when certain
|
andrewm@0
|
38 // events occur: touch on/off, MIDI on/off, key idle/active.
|
andrewm@0
|
39
|
andrewm@0
|
40 class MappingFactory {
|
andrewm@0
|
41 public:
|
andrewm@0
|
42 // States for bypass status
|
andrewm@0
|
43 enum {
|
andrewm@0
|
44 kBypassOff = 0,
|
andrewm@0
|
45 kBypassOn,
|
andrewm@0
|
46 kBypassMixed
|
andrewm@0
|
47 };
|
andrewm@0
|
48
|
andrewm@0
|
49 // ***** Constructor *****
|
andrewm@0
|
50
|
andrewm@0
|
51 // Default constructor, containing a reference to the PianoKeyboard class.
|
andrewm@0
|
52 MappingFactory(PianoKeyboard &keyboard) : keyboard_(keyboard) {}
|
andrewm@0
|
53
|
andrewm@0
|
54 // ***** Destructor *****
|
andrewm@0
|
55
|
andrewm@0
|
56 virtual ~MappingFactory() {}
|
andrewm@0
|
57
|
andrewm@0
|
58 // ***** Accessors / Modifiers *****
|
andrewm@0
|
59
|
andrewm@0
|
60 // Generic name for this type of factory
|
andrewm@0
|
61 virtual const std::string factoryTypeName() { return "Unknown\nMapping"; }
|
andrewm@0
|
62
|
andrewm@0
|
63 // Specific name for this particular factory
|
andrewm@0
|
64 virtual string const getName() { return ""; }
|
andrewm@49
|
65 virtual string const getShortName() { return ""; }
|
andrewm@0
|
66 virtual void setName(const string& name) {}
|
andrewm@0
|
67
|
andrewm@0
|
68 virtual Mapping* mapping(int noteNumber) = 0; // Look up a mapping with the given note number
|
andrewm@0
|
69 virtual std::vector<int> activeMappings() = 0; // Return a list of all active notes
|
andrewm@0
|
70
|
andrewm@0
|
71 virtual void removeAllMappings() = 0; // Remove all active mappings
|
andrewm@0
|
72 virtual void mappingFinished(int noteNumber) = 0; // Callback from mapping to say it's done
|
andrewm@0
|
73
|
andrewm@0
|
74 // Suspending mappings is a state managed internally by the TouchKeys
|
andrewm@0
|
75 // controllers, for example to turn off a mapping of an older note in monophonic
|
andrewm@0
|
76 // mode. By contrast, bypassing a mapping is intended to be manipulated from
|
andrewm@0
|
77 // an external UI.
|
andrewm@0
|
78
|
andrewm@0
|
79 virtual void suspendMapping(int noteNumber) = 0; // Suspend messages from a particular note
|
andrewm@0
|
80 virtual void suspendAllMappings() = 0; // ... or all notes
|
andrewm@0
|
81 virtual void resumeMapping(int noteNumber, bool resend) = 0; // Resume messages from a particular note
|
andrewm@0
|
82 virtual void resumeAllMappings(bool resend) = 0; // ... or all notes
|
andrewm@0
|
83
|
andrewm@0
|
84 virtual int bypassed() = 0; // Whether this mapping is bypassed
|
andrewm@0
|
85 virtual void setBypassed(bool bypass) = 0; // Set whether the mapping is bypassed or not
|
andrewm@0
|
86
|
andrewm@0
|
87 // ***** State Updaters *****
|
andrewm@0
|
88
|
andrewm@0
|
89 // These are called by PianoKey whenever certain events occur that might
|
andrewm@0
|
90 // merit the start and stop of a mapping. What is done with them depends on
|
andrewm@0
|
91 // the particular factory subclass. The relevant buffers are passed in each
|
andrewm@0
|
92 // time so the factory or the mapping can make use of them
|
andrewm@0
|
93
|
andrewm@0
|
94 // Touch becomes active on a key where it wasn't previously
|
andrewm@0
|
95 virtual void touchBegan(int noteNumber, bool midiNoteIsOn, bool keyMotionActive,
|
andrewm@0
|
96 Node<KeyTouchFrame>* touchBuffer,
|
andrewm@0
|
97 Node<key_position>* positionBuffer,
|
andrewm@0
|
98 KeyPositionTracker* positionTracker) = 0;
|
andrewm@0
|
99 // Touch ends on a key where it wasn't previously
|
andrewm@0
|
100 virtual void touchEnded(int noteNumber, bool midiNoteIsOn, bool keyMotionActive,
|
andrewm@0
|
101 Node<KeyTouchFrame>* touchBuffer,
|
andrewm@0
|
102 Node<key_position>* positionBuffer,
|
andrewm@0
|
103 KeyPositionTracker* positionTracker) = 0;
|
andrewm@0
|
104 // MIDI note on for a key
|
andrewm@0
|
105 virtual void midiNoteOn(int noteNumber, bool touchIsOn, bool keyMotionActive,
|
andrewm@0
|
106 Node<KeyTouchFrame>* touchBuffer,
|
andrewm@0
|
107 Node<key_position>* positionBuffer,
|
andrewm@0
|
108 KeyPositionTracker* positionTracker) = 0;
|
andrewm@0
|
109 // MIDI note off for a key
|
andrewm@0
|
110 virtual void midiNoteOff(int noteNumber, bool touchIsOn, bool keyMotionActive,
|
andrewm@0
|
111 Node<KeyTouchFrame>* touchBuffer,
|
andrewm@0
|
112 Node<key_position>* positionBuffer,
|
andrewm@0
|
113 KeyPositionTracker* positionTracker) = 0;
|
andrewm@0
|
114 // Key goes active from continuous key position
|
andrewm@0
|
115 virtual void keyMotionActive(int noteNumber, bool midiNoteIsOn, bool touchIsOn,
|
andrewm@0
|
116 Node<KeyTouchFrame>* touchBuffer,
|
andrewm@0
|
117 Node<key_position>* positionBuffer,
|
andrewm@0
|
118 KeyPositionTracker* positionTracker) = 0;
|
andrewm@0
|
119 // Key goes idle from continuous key position
|
andrewm@0
|
120 virtual void keyMotionIdle(int noteNumber, bool midiNoteIsOn, bool touchIsOn,
|
andrewm@0
|
121 Node<KeyTouchFrame>* touchBuffer,
|
andrewm@0
|
122 Node<key_position>* positionBuffer,
|
andrewm@0
|
123 KeyPositionTracker* positionTracker) = 0;
|
andrewm@0
|
124
|
andrewm@0
|
125 // Notification from key that a note is about to be sent out
|
andrewm@0
|
126 virtual void noteWillBegin(int noteNumber, int midiChannel, int midiVelocity) = 0;
|
andrewm@0
|
127
|
andrewm@49
|
128 #ifndef TOUCHKEYS_NO_GUI
|
andrewm@0
|
129 // ***** GUI Support *****
|
andrewm@0
|
130 // There are two types of editors for a mapping: one is a small editor that fits in the
|
andrewm@0
|
131 // list view for adjusting the most important parameters, the other goes in a window of
|
andrewm@0
|
132 // its own to adjust every parameter.
|
andrewm@0
|
133
|
andrewm@0
|
134 virtual bool hasBasicEditor() { return false; }
|
andrewm@0
|
135 virtual MappingEditorComponent* createBasicEditor() { return nullptr; }
|
andrewm@0
|
136 virtual bool hasExtendedEditor() { return false; }
|
andrewm@0
|
137 virtual MappingEditorComponent* createExtendedEditor() { return nullptr; }
|
andrewm@49
|
138 #endif
|
andrewm@49
|
139
|
andrewm@49
|
140 // ****** OSC Control ******
|
andrewm@49
|
141 // As an alternative to GUI control, the mapping factories can receive OSC messages
|
andrewm@49
|
142 // from the keyboard segment to which they are attached.
|
andrewm@49
|
143 virtual OscMessage* oscControlMethod(const char *path, const char *types,
|
andrewm@49
|
144 int numValues, lo_arg **values, void *data) {
|
andrewm@49
|
145 // Nothing to do here in this virtual base class
|
andrewm@49
|
146 return 0;
|
andrewm@49
|
147 }
|
andrewm@0
|
148
|
andrewm@33
|
149 // ****** Preset Save/Load ******
|
andrewm@33
|
150 // These methods generate XML settings files and reload values from them
|
andrewm@33
|
151 // The specific implementation is up to the subclass
|
andrewm@33
|
152
|
andrewm@33
|
153 virtual XmlElement* getPreset() = 0;
|
andrewm@33
|
154 virtual bool loadPreset(XmlElement const* preset) = 0;
|
andrewm@33
|
155
|
andrewm@0
|
156 protected:
|
andrewm@0
|
157 // ***** Member Variables *****
|
andrewm@0
|
158
|
andrewm@0
|
159 PianoKeyboard& keyboard_; // Reference to the main keyboard controller
|
andrewm@0
|
160
|
andrewm@0
|
161 private:
|
andrewm@0
|
162 //JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MappingFactory)
|
andrewm@0
|
163 };
|
andrewm@0
|
164
|
andrewm@0
|
165 #endif /* defined(__touchkeys__MappingFactory__) */
|