annotate Source/Mappings/MappingFactorySplitter.cpp @ 56:b4a2d2ae43cf tip

merge
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Fri, 23 Nov 2018 15:48:14 +0000
parents e8965409903e
children
rev   line source
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 MappingFactorySplitter.cpp: MappingFactory subclass which in turn contains
andrewm@0 21 several factories, routing all incoming method calls to each of them.
andrewm@0 22 */
andrewm@0 23
andrewm@0 24 #include "MappingFactorySplitter.h"
andrewm@0 25
andrewm@0 26 // Look up a mapping with the given note number
andrewm@0 27 Mapping* MappingFactorySplitter::mapping(int noteNumber) {
andrewm@0 28 // TODO: find a mapping in any of the factories
andrewm@0 29 if(factories_.empty())
andrewm@0 30 return 0;
andrewm@0 31 return (*factories_.begin())->mapping(noteNumber);
andrewm@0 32 }
andrewm@0 33
andrewm@0 34 // Return a list of all active notes
andrewm@0 35 std::vector<int> MappingFactorySplitter::activeMappings() {
andrewm@0 36 // TODO: merge all active factories
andrewm@0 37 if(factories_.empty()) {
andrewm@0 38 return std::vector<int>();
andrewm@0 39 }
andrewm@0 40 return (*factories_.begin())->activeMappings();
andrewm@0 41 }
andrewm@0 42
andrewm@0 43 // Remove all active mappings
andrewm@0 44 void MappingFactorySplitter::removeAllMappings() {
andrewm@0 45 std::list<MappingFactory*>::iterator it;
andrewm@0 46
andrewm@0 47 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 48 (*it)->removeAllMappings();
andrewm@0 49 }
andrewm@0 50 }
andrewm@0 51
andrewm@0 52 // Suspend messages from a particular note
andrewm@0 53 void MappingFactorySplitter::suspendMapping(int noteNumber) {
andrewm@0 54 std::list<MappingFactory*>::iterator it;
andrewm@0 55
andrewm@0 56 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 57 (*it)->suspendMapping(noteNumber);
andrewm@0 58 }
andrewm@0 59 }
andrewm@0 60
andrewm@0 61 // Suspend messages from all notes
andrewm@0 62 void MappingFactorySplitter::suspendAllMappings() {
andrewm@0 63 std::list<MappingFactory*>::iterator it;
andrewm@0 64
andrewm@0 65 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 66 (*it)->suspendAllMappings();
andrewm@0 67 }
andrewm@0 68 }
andrewm@0 69
andrewm@0 70 // Resume messages from a particular note
andrewm@0 71 void MappingFactorySplitter::resumeMapping(int noteNumber, bool resend) {
andrewm@0 72 std::list<MappingFactory*>::iterator it;
andrewm@0 73
andrewm@0 74 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 75 (*it)->resumeMapping(noteNumber, resend);
andrewm@0 76 }
andrewm@0 77 }
andrewm@0 78
andrewm@0 79 // Resume messages from all notes
andrewm@0 80 void MappingFactorySplitter::resumeAllMappings(bool resend) {
andrewm@0 81 std::list<MappingFactory*>::iterator it;
andrewm@0 82
andrewm@0 83 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 84 (*it)->resumeAllMappings(resend);
andrewm@0 85 }
andrewm@0 86 }
andrewm@0 87
andrewm@0 88 // Whether the component parts of this mapping are bypassed
andrewm@0 89 int MappingFactorySplitter::bypassed() {
andrewm@0 90 if(factories_.empty())
andrewm@0 91 return bypassNewMappings_;
andrewm@0 92 bool bypassOn = false, bypassOff = false;
andrewm@0 93
andrewm@0 94 std::list<MappingFactory*>::iterator it;
andrewm@0 95 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 96 if((*it)->bypassed())
andrewm@0 97 bypassOn = true;
andrewm@0 98 else
andrewm@0 99 bypassOff = true;
andrewm@0 100 }
andrewm@0 101
andrewm@0 102 // Three states: all on, all off, or some on + some off (mixed)
andrewm@0 103 if(bypassOn && !bypassOff)
andrewm@0 104 return kBypassOn;
andrewm@0 105 if(bypassOff && !bypassOn)
andrewm@0 106 return kBypassOff;
andrewm@0 107 return kBypassMixed;
andrewm@0 108 }
andrewm@0 109
andrewm@0 110 // Set whether the component parts are bypassed
andrewm@0 111 void MappingFactorySplitter::setBypassed(bool bypass) {
andrewm@0 112 std::list<MappingFactory*>::iterator it;
andrewm@0 113 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 114 (*it)->setBypassed(bypass);
andrewm@0 115 }
andrewm@0 116 bypassNewMappings_ = bypass;
andrewm@0 117 }
andrewm@0 118
andrewm@0 119 // Add a factory to the list
andrewm@0 120 void MappingFactorySplitter::addFactory(MappingFactory* factory) {
andrewm@0 121 if(bypassNewMappings_)
andrewm@0 122 factory->setBypassed(true);
andrewm@0 123 factories_.push_back(factory);
andrewm@0 124 }
andrewm@0 125
andrewm@0 126 // Remove a factory from the list
andrewm@0 127 void MappingFactorySplitter::removeFactory(MappingFactory* factory) {
andrewm@0 128 // Assume allocation/deallocation takes place elsewhere
andrewm@0 129 std::list<MappingFactory*>::iterator it = factories_.begin();
andrewm@0 130
andrewm@0 131 while(it != factories_.end()) {
andrewm@0 132 if(*it == factory)
andrewm@0 133 factories_.erase(it++);
andrewm@0 134 else
andrewm@0 135 it++;
andrewm@0 136 }
andrewm@0 137 }
andrewm@0 138
andrewm@0 139 // Remove all factories from the list
andrewm@0 140 void MappingFactorySplitter::removeAllFactories() {
andrewm@0 141 // Assume allocation/deallocation takes place elsewhere
andrewm@0 142 factories_.clear();
andrewm@0 143 }
andrewm@0 144
andrewm@33 145 // Generate XML element with preset settings
andrewm@33 146 XmlElement* MappingFactorySplitter::getPreset() {
andrewm@33 147 XmlElement *preset = new XmlElement("MappingFactory");
andrewm@33 148 preset->setAttribute("type", "Splitter");
andrewm@33 149 return preset;
andrewm@33 150 }
andrewm@33 151
andrewm@33 152 bool MappingFactorySplitter::loadPreset(XmlElement const* preset) {
andrewm@33 153 return true;
andrewm@33 154 }
andrewm@33 155
andrewm@0 156 // Touch becomes active on a key where it wasn't previously
andrewm@0 157 void MappingFactorySplitter::touchBegan(int noteNumber, bool midiNoteIsOn, bool keyMotionActive,
andrewm@0 158 Node<KeyTouchFrame>* touchBuffer,
andrewm@0 159 Node<key_position>* positionBuffer,
andrewm@0 160 KeyPositionTracker* positionTracker) {
andrewm@0 161 std::list<MappingFactory*>::iterator it;
andrewm@0 162
andrewm@0 163 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 164 (*it)->touchBegan(noteNumber, midiNoteIsOn, keyMotionActive,
andrewm@0 165 touchBuffer, positionBuffer, positionTracker);
andrewm@0 166 }
andrewm@0 167 }
andrewm@0 168
andrewm@0 169 // Touch ends on a key where it wasn't previously
andrewm@0 170 void MappingFactorySplitter::touchEnded(int noteNumber, bool midiNoteIsOn, bool keyMotionActive,
andrewm@0 171 Node<KeyTouchFrame>* touchBuffer,
andrewm@0 172 Node<key_position>* positionBuffer,
andrewm@0 173 KeyPositionTracker* positionTracker) {
andrewm@0 174 std::list<MappingFactory*>::iterator it;
andrewm@0 175
andrewm@0 176 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 177 (*it)->touchEnded(noteNumber, midiNoteIsOn, keyMotionActive,
andrewm@0 178 touchBuffer, positionBuffer, positionTracker);
andrewm@0 179 }
andrewm@0 180 }
andrewm@0 181
andrewm@0 182 // MIDI note on for a key
andrewm@0 183 void MappingFactorySplitter::midiNoteOn(int noteNumber, bool touchIsOn, bool keyMotionActive,
andrewm@0 184 Node<KeyTouchFrame>* touchBuffer,
andrewm@0 185 Node<key_position>* positionBuffer,
andrewm@0 186 KeyPositionTracker* positionTracker) {
andrewm@0 187
andrewm@0 188 std::list<MappingFactory*>::iterator it;
andrewm@0 189
andrewm@0 190 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 191 (*it)->midiNoteOn(noteNumber, touchIsOn, keyMotionActive,
andrewm@0 192 touchBuffer, positionBuffer, positionTracker);
andrewm@0 193 }
andrewm@0 194 }
andrewm@0 195
andrewm@0 196 // MIDI note off for a key
andrewm@0 197 void MappingFactorySplitter::midiNoteOff(int noteNumber, bool touchIsOn, bool keyMotionActive,
andrewm@0 198 Node<KeyTouchFrame>* touchBuffer,
andrewm@0 199 Node<key_position>* positionBuffer,
andrewm@0 200 KeyPositionTracker* positionTracker) {
andrewm@0 201 std::list<MappingFactory*>::iterator it;
andrewm@0 202
andrewm@0 203 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 204 (*it)->midiNoteOff(noteNumber, touchIsOn, keyMotionActive,
andrewm@0 205 touchBuffer, positionBuffer, positionTracker);
andrewm@0 206 }
andrewm@0 207 }
andrewm@0 208
andrewm@0 209 // Key goes active from continuous key position
andrewm@0 210 void MappingFactorySplitter::keyMotionActive(int noteNumber, bool midiNoteIsOn, bool touchIsOn,
andrewm@0 211 Node<KeyTouchFrame>* touchBuffer,
andrewm@0 212 Node<key_position>* positionBuffer,
andrewm@0 213 KeyPositionTracker* positionTracker) {
andrewm@0 214 std::list<MappingFactory*>::iterator it;
andrewm@0 215
andrewm@0 216 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 217 (*it)->keyMotionActive(noteNumber, midiNoteIsOn, touchIsOn,
andrewm@0 218 touchBuffer, positionBuffer, positionTracker);
andrewm@0 219 }
andrewm@0 220 }
andrewm@0 221
andrewm@0 222 // Key goes idle from continuous key position
andrewm@0 223 void MappingFactorySplitter::keyMotionIdle(int noteNumber, bool midiNoteIsOn, bool touchIsOn,
andrewm@0 224 Node<KeyTouchFrame>* touchBuffer,
andrewm@0 225 Node<key_position>* positionBuffer,
andrewm@0 226 KeyPositionTracker* positionTracker) {
andrewm@0 227 std::list<MappingFactory*>::iterator it;
andrewm@0 228
andrewm@0 229 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 230 (*it)->keyMotionIdle(noteNumber, midiNoteIsOn, touchIsOn,
andrewm@0 231 touchBuffer, positionBuffer, positionTracker);
andrewm@0 232 }
andrewm@0 233 }
andrewm@0 234
andrewm@0 235 // MIDI note about to begin
andrewm@0 236 void MappingFactorySplitter::noteWillBegin(int noteNumber, int midiChannel, int midiVelocity) {
andrewm@0 237 std::list<MappingFactory*>::iterator it;
andrewm@0 238
andrewm@0 239 for(it = factories_.begin(); it != factories_.end(); ++it) {
andrewm@0 240 (*it)->noteWillBegin(noteNumber, midiChannel, midiVelocity);
andrewm@0 241 }
andrewm@0 242 }