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: MappingFactory.h: base class for creating mappings. A factory is a singular andrewm@0: object, attached to a particular keyboard segment, which in turn allocates andrewm@0: and destroys individual Mapping objects for each active note. The factory andrewm@0: also is the usual point at which parameter changes are made. andrewm@0: */ andrewm@0: andrewm@0: #ifndef __touchkeys__MappingFactory__ andrewm@0: #define __touchkeys__MappingFactory__ andrewm@0: andrewm@0: #include andrewm@0: #include andrewm@0: #include "Mapping.h" andrewm@0: #include "../GUI/MappingEditorComponent.h" andrewm@0: andrewm@0: // This virtual base class defines a singular factory object from which individual andrewm@0: // instances of mapping objects can be created and destroyed. How the mappings are andrewm@0: // allocated and when is up to the factory, which also keeps track of which ones andrewm@0: // are active. The PianoKey class will call into any active factories when certain andrewm@0: // events occur: touch on/off, MIDI on/off, key idle/active. andrewm@0: andrewm@0: class MappingFactory { andrewm@0: public: andrewm@0: // States for bypass status andrewm@0: enum { andrewm@0: kBypassOff = 0, andrewm@0: kBypassOn, andrewm@0: kBypassMixed andrewm@0: }; andrewm@0: andrewm@0: // ***** Constructor ***** andrewm@0: andrewm@0: // Default constructor, containing a reference to the PianoKeyboard class. andrewm@0: MappingFactory(PianoKeyboard &keyboard) : keyboard_(keyboard) {} andrewm@0: andrewm@0: // ***** Destructor ***** andrewm@0: andrewm@0: virtual ~MappingFactory() {} andrewm@0: andrewm@0: // ***** Accessors / Modifiers ***** andrewm@0: andrewm@0: // Generic name for this type of factory andrewm@0: virtual const std::string factoryTypeName() { return "Unknown\nMapping"; } andrewm@0: andrewm@0: // Specific name for this particular factory andrewm@0: virtual string const getName() { return ""; } andrewm@49: virtual string const getShortName() { return ""; } andrewm@0: virtual void setName(const string& name) {} andrewm@0: andrewm@0: virtual Mapping* mapping(int noteNumber) = 0; // Look up a mapping with the given note number andrewm@0: virtual std::vector activeMappings() = 0; // Return a list of all active notes andrewm@0: andrewm@0: virtual void removeAllMappings() = 0; // Remove all active mappings andrewm@0: virtual void mappingFinished(int noteNumber) = 0; // Callback from mapping to say it's done andrewm@0: andrewm@0: // Suspending mappings is a state managed internally by the TouchKeys andrewm@0: // controllers, for example to turn off a mapping of an older note in monophonic andrewm@0: // mode. By contrast, bypassing a mapping is intended to be manipulated from andrewm@0: // an external UI. andrewm@0: andrewm@0: virtual void suspendMapping(int noteNumber) = 0; // Suspend messages from a particular note andrewm@0: virtual void suspendAllMappings() = 0; // ... or all notes andrewm@0: virtual void resumeMapping(int noteNumber, bool resend) = 0; // Resume messages from a particular note andrewm@0: virtual void resumeAllMappings(bool resend) = 0; // ... or all notes andrewm@0: andrewm@0: virtual int bypassed() = 0; // Whether this mapping is bypassed andrewm@0: virtual void setBypassed(bool bypass) = 0; // Set whether the mapping is bypassed or not 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. The relevant buffers are passed in each andrewm@0: // time so the factory or the mapping can make use of them andrewm@0: andrewm@0: // Touch becomes active on a key where it wasn't previously andrewm@0: virtual void touchBegan(int noteNumber, bool midiNoteIsOn, bool keyMotionActive, andrewm@0: Node* touchBuffer, andrewm@0: Node* positionBuffer, andrewm@0: KeyPositionTracker* positionTracker) = 0; andrewm@0: // Touch ends on a key where it wasn't previously andrewm@0: virtual void touchEnded(int noteNumber, bool midiNoteIsOn, bool keyMotionActive, andrewm@0: Node* touchBuffer, andrewm@0: Node* positionBuffer, andrewm@0: KeyPositionTracker* positionTracker) = 0; andrewm@0: // MIDI note on for a key andrewm@0: virtual void midiNoteOn(int noteNumber, bool touchIsOn, bool keyMotionActive, andrewm@0: Node* touchBuffer, andrewm@0: Node* positionBuffer, andrewm@0: KeyPositionTracker* positionTracker) = 0; andrewm@0: // MIDI note off for a key andrewm@0: virtual void midiNoteOff(int noteNumber, bool touchIsOn, bool keyMotionActive, andrewm@0: Node* touchBuffer, andrewm@0: Node* positionBuffer, andrewm@0: KeyPositionTracker* positionTracker) = 0; andrewm@0: // Key goes active from continuous key position andrewm@0: virtual void keyMotionActive(int noteNumber, bool midiNoteIsOn, bool touchIsOn, andrewm@0: Node* touchBuffer, andrewm@0: Node* positionBuffer, andrewm@0: KeyPositionTracker* positionTracker) = 0; andrewm@0: // Key goes idle from continuous key position andrewm@0: virtual void keyMotionIdle(int noteNumber, bool midiNoteIsOn, bool touchIsOn, andrewm@0: Node* touchBuffer, andrewm@0: Node* positionBuffer, andrewm@0: KeyPositionTracker* positionTracker) = 0; andrewm@0: andrewm@0: // Notification from key that a note is about to be sent out andrewm@0: virtual void noteWillBegin(int noteNumber, int midiChannel, int midiVelocity) = 0; andrewm@0: andrewm@49: #ifndef TOUCHKEYS_NO_GUI andrewm@0: // ***** GUI Support ***** andrewm@0: // There are two types of editors for a mapping: one is a small editor that fits in the andrewm@0: // list view for adjusting the most important parameters, the other goes in a window of andrewm@0: // its own to adjust every parameter. andrewm@0: andrewm@0: virtual bool hasBasicEditor() { return false; } andrewm@0: virtual MappingEditorComponent* createBasicEditor() { return nullptr; } andrewm@0: virtual bool hasExtendedEditor() { return false; } andrewm@0: virtual MappingEditorComponent* createExtendedEditor() { return nullptr; } andrewm@49: #endif andrewm@49: andrewm@49: // ****** OSC Control ****** andrewm@49: // As an alternative to GUI control, the mapping factories can receive OSC messages andrewm@49: // from the keyboard segment to which they are attached. andrewm@49: virtual OscMessage* oscControlMethod(const char *path, const char *types, andrewm@49: int numValues, lo_arg **values, void *data) { andrewm@49: // Nothing to do here in this virtual base class andrewm@49: return 0; andrewm@49: } andrewm@0: 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: virtual XmlElement* getPreset() = 0; andrewm@33: virtual bool loadPreset(XmlElement const* preset) = 0; andrewm@33: andrewm@0: protected: andrewm@0: // ***** Member Variables ***** andrewm@0: andrewm@0: PianoKeyboard& keyboard_; // Reference to the main keyboard controller andrewm@0: andrewm@0: private: andrewm@0: //JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MappingFactory) andrewm@0: }; andrewm@0: andrewm@0: #endif /* defined(__touchkeys__MappingFactory__) */