andrewm@0: /*
andrewm@0: TouchKeys: multi-touch musical keyboard control software
andrewm@0: Copyright (c) 2013 Andrew McPherson
andrewm@0:
andrewm@0: This program is free software: you can redistribute it and/or modify
andrewm@0: it under the terms of the GNU General Public License as published by
andrewm@0: the Free Software Foundation, either version 3 of the License, or
andrewm@0: (at your option) any later version.
andrewm@0:
andrewm@0: This program is distributed in the hope that it will be useful,
andrewm@0: but WITHOUT ANY WARRANTY; without even the implied warranty of
andrewm@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
andrewm@0: GNU General Public License for more details.
andrewm@0:
andrewm@0: You should have received a copy of the GNU General Public License
andrewm@0: along with this program. If not, see .
andrewm@0:
andrewm@0: =====================================================================
andrewm@0:
andrewm@0: MappingFactorySplitter.h: MappingFactory subclass which in turn contains
andrewm@0: several factories, routing all incoming method calls to each of them.
andrewm@0: */
andrewm@0:
andrewm@0: #ifndef __touchkeys__TouchkeyMappingFactorySplitter__
andrewm@0: #define __touchkeys__TouchkeyMappingFactorySplitter__
andrewm@0:
andrewm@0: #include
andrewm@0: #include
andrewm@0: #include "MappingFactory.h"
andrewm@0:
andrewm@0: // Factory class to produce Touchkey vibrato (pitch-bend) mappings
andrewm@0: // This class keeps track of all the active mappings and responds
andrewm@0: // whenever touches or notes begin or end
andrewm@0:
andrewm@0: class MappingFactorySplitter : public MappingFactory {
andrewm@0: public:
andrewm@0: // ***** Constructor *****
andrewm@0:
andrewm@0: // Default constructor, containing a reference to the PianoKeyboard class.
andrewm@0: MappingFactorySplitter(PianoKeyboard &keyboard) : MappingFactory(keyboard), bypassNewMappings_(false) {}
andrewm@0:
andrewm@0: // ***** Destructor *****
andrewm@0:
andrewm@0: ~MappingFactorySplitter() {
andrewm@0: removeAllFactories();
andrewm@0: }
andrewm@0:
andrewm@0: // ***** Accessors / Modifiers *****
andrewm@0:
andrewm@0: Mapping* mapping(int noteNumber); // Look up a mapping with the given note number
andrewm@0: std::vector activeMappings(); // Return a list of all active notes
andrewm@0:
andrewm@0: void removeAllMappings(); // Remove all active mappings
andrewm@0: void mappingFinished(int noteNumber) {} // Callback from a mapping to say it's finished.
andrewm@0: // Nobody should ever call this since we don't have our own mappings
andrewm@0:
andrewm@0: void suspendMapping(int noteNumber); // Suspend messages from a particular note
andrewm@0: void suspendAllMappings(); // ... or all notes
andrewm@0: void resumeMapping(int noteNumber, bool resend); // Resume messages from a particular note
andrewm@0: void resumeAllMappings(bool resend); // ... or all notes
andrewm@0:
andrewm@0: int bypassed(); // Whether this mapping is bypassed
andrewm@0: void setBypassed(bool bypass); // Set whether the mapping is bypassed or not
andrewm@0:
andrewm@0: // ***** Specific Methods *****
andrewm@0:
andrewm@0: void addFactory(MappingFactory* factory);
andrewm@0: void removeFactory(MappingFactory* factory);
andrewm@0: void removeAllFactories();
andrewm@33:
andrewm@33: // ****** Preset Save/Load ******
andrewm@33: // These methods generate XML settings files and reload values from them
andrewm@33: // The specific implementation is up to the subclass
andrewm@33:
andrewm@33: XmlElement* getPreset();
andrewm@33: bool loadPreset(XmlElement const* preset);
andrewm@0:
andrewm@0: // ***** State Updaters *****
andrewm@0:
andrewm@0: // These are called by PianoKey whenever certain events occur that might
andrewm@0: // merit the start and stop of a mapping. What is done with them depends on
andrewm@0: // the particular factory subclass.
andrewm@0:
andrewm@0: // Touch becomes active on a key where it wasn't previously
andrewm@0: void touchBegan(int noteNumber, bool midiNoteIsOn, bool keyMotionActive,
andrewm@0: Node* touchBuffer,
andrewm@0: Node* positionBuffer,
andrewm@0: KeyPositionTracker* positionTracker);
andrewm@0: // Touch ends on a key where it wasn't previously
andrewm@0: void touchEnded(int noteNumber, bool midiNoteIsOn, bool keyMotionActive,
andrewm@0: Node* touchBuffer,
andrewm@0: Node* positionBuffer,
andrewm@0: KeyPositionTracker* positionTracker);
andrewm@0: // MIDI note on for a key
andrewm@0: void midiNoteOn(int noteNumber, bool touchIsOn, bool keyMotionActive,
andrewm@0: Node* touchBuffer,
andrewm@0: Node* positionBuffer,
andrewm@0: KeyPositionTracker* positionTracker);
andrewm@0: // MIDI note off for a key
andrewm@0: void midiNoteOff(int noteNumber, bool touchIsOn, bool keyMotionActive,
andrewm@0: Node* touchBuffer,
andrewm@0: Node* positionBuffer,
andrewm@0: KeyPositionTracker* positionTracker);
andrewm@0: // Key goes active from continuous key position
andrewm@0: void keyMotionActive(int noteNumber, bool midiNoteIsOn, bool touchIsOn,
andrewm@0: Node* touchBuffer,
andrewm@0: Node* positionBuffer,
andrewm@0: KeyPositionTracker* positionTracker);
andrewm@0: // Key goes idle from continuous key position
andrewm@0: void keyMotionIdle(int noteNumber, bool midiNoteIsOn, bool touchIsOn,
andrewm@0: Node* touchBuffer,
andrewm@0: Node* positionBuffer,
andrewm@0: KeyPositionTracker* positionTracker);
andrewm@0: // MIDI note about to begin
andrewm@0: void noteWillBegin(int noteNumber, int midiChannel, int midiVelocity);
andrewm@0:
andrewm@0: private:
andrewm@0:
andrewm@0: // State variables
andrewm@0: std::list factories_; // List of child factories
andrewm@0: bool bypassNewMappings_; // Whether to bypass mappings that are added
andrewm@0: };
andrewm@0:
andrewm@0: #endif /* defined(__touchkeys__TouchkeyMappingFactorySplitter__) */