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: TouchkeyKeyDivisionMappingFactory.h: factory for the split-key mapping andrewm@0: which triggers different actions or pitches depending on where the key andrewm@0: was struck. andrewm@0: */ andrewm@0: andrewm@0: #ifndef __TouchKeys__TouchkeyKeyDivisionMappingFactory__ andrewm@0: #define __TouchKeys__TouchkeyKeyDivisionMappingFactory__ andrewm@0: andrewm@0: #include "../TouchkeyBaseMappingFactory.h" andrewm@0: #include "TouchkeyKeyDivisionMapping.h" andrewm@0: andrewm@0: class TouchkeyKeyDivisionMappingFactory : public TouchkeyBaseMappingFactory { andrewm@0: private: andrewm@51: static const float kTuningsYarman24c[]; andrewm@51: static const int kMaxSegmentsPerKey; andrewm@0: andrewm@0: public: andrewm@51: enum { andrewm@51: kTuningPreset19TET = 0, andrewm@51: kTuningPreset24TET, andrewm@51: kTuningPreset31TET, andrewm@51: kTuningPreset36TET, andrewm@51: kTuningPresetYarman24c, andrewm@51: kTuningPresetMaxValue andrewm@51: }; andrewm@51: andrewm@0: // ***** Constructor ***** andrewm@0: andrewm@0: // Default constructor, containing a reference to the PianoKeyboard class. andrewm@0: TouchkeyKeyDivisionMappingFactory(PianoKeyboard &keyboard, MidiKeyboardSegment& segment); andrewm@0: andrewm@0: // ***** Destructor ***** andrewm@0: andrewm@44: ~TouchkeyKeyDivisionMappingFactory(); andrewm@0: andrewm@0: // ***** Accessors / Modifiers ***** andrewm@0: andrewm@0: virtual const std::string factoryTypeName() { return "Split\nKeys"; } andrewm@0: andrewm@0: void setName(const string& name); andrewm@0: andrewm@51: // ***** Split-Key Specific Methods ***** andrewm@51: andrewm@51: int getNumberOfSegments() { return numSegmentsPerKey_; } andrewm@51: timestamp_diff_type getTimeout() { return timeout_; } andrewm@51: int getDetectionParameter() { return detectionParameter_; } andrewm@51: bool getRetriggerable() { return retriggerable_; } andrewm@51: int getRetriggerNumFrames() { return retriggerNumFrames_; } andrewm@51: bool getRetriggerKeepsVelocity() { return retriggerKeepsVelocity_; } andrewm@51: int getReferenceNote() { return referenceNote_; } andrewm@51: float getGlobalOffset() { return globalOffsetCents_; } andrewm@51: int getTuningPreset() { return tuningPreset_; } andrewm@0: andrewm@0: void setNumberOfSegments(int segments) { andrewm@51: if(segments > 0 && segments <= kMaxSegmentsPerKey) andrewm@0: numSegmentsPerKey_ = segments; andrewm@0: } andrewm@0: andrewm@0: // Set the detection timeout value (how long from MIDI note on to touch) andrewm@0: void setTimeout(timestamp_diff_type timeout) { andrewm@0: timeout_ = timeout; andrewm@0: } andrewm@0: andrewm@0: // Set the detection parameter for choosing a segment andrewm@0: void setDetectionParameter(int detectionParameter) { andrewm@51: if(detectionParameter >= 1 && detectionParameter < TouchkeyKeyDivisionMapping::kDetectionParameterMaxValue) andrewm@51: detectionParameter_ = detectionParameter; andrewm@0: } andrewm@0: andrewm@0: // Set whether placing a second finger in the other segment triggers a andrewm@51: // new note with that segment. Two forms of this... andrewm@0: void setRetriggerable(bool retrigger, int numFrames, bool keepOriginalVelocity) { andrewm@0: retriggerable_ = retrigger; andrewm@0: retriggerNumFrames_ = numFrames; andrewm@0: retriggerKeepsVelocity_ = keepOriginalVelocity; andrewm@0: } andrewm@0: andrewm@51: void setRetriggerable(bool retrigger) { andrewm@51: retriggerable_ = retrigger; andrewm@51: } andrewm@51: andrewm@0: // Set the note that acts as the reference point in a microtonal scale andrewm@0: void setReferenceNote(int note) { andrewm@0: if(note >= 0) andrewm@0: referenceNote_ = note % 12; andrewm@0: } andrewm@0: andrewm@0: void setGlobalOffset(float offsetCents) { andrewm@0: globalOffsetCents_ = offsetCents; andrewm@0: } andrewm@0: andrewm@51: void setTuningPreset(int preset); andrewm@51: andrewm@51: #ifndef TOUCHKEYS_NO_GUI andrewm@51: // ***** GUI Support ***** andrewm@51: bool hasBasicEditor() { return true; } andrewm@51: MappingEditorComponent* createBasicEditor(); andrewm@51: bool hasExtendedEditor() { return false; } andrewm@51: MappingEditorComponent* createExtendedEditor() { return nullptr; } andrewm@51: #endif andrewm@51: andrewm@36: // ****** Preset Save/Load ****** andrewm@36: XmlElement* getPreset(); andrewm@36: bool loadPreset(XmlElement const* preset); andrewm@36: andrewm@0: private: andrewm@0: // ***** Private Methods ***** andrewm@0: void initializeMappingParameters(int noteNumber, TouchkeyKeyDivisionMapping *mapping); andrewm@0: void setBendParameters(); andrewm@0: andrewm@51: int tuningPreset_; // Number of the preset tuning, if active andrewm@51: float *tunings_; // Array of tuning values, set by preset andrewm@0: int numSegmentsPerKey_; // How many segments per key andrewm@0: timestamp_diff_type timeout_; // How long before timeout activates default segment andrewm@0: int detectionParameter_; // Which parameter separates it into segments andrewm@0: bool retriggerable_; // Whether a second touch can retrigger this note andrewm@0: int retriggerNumFrames_; // How many frames a new touch must be present to retrigger andrewm@0: bool retriggerKeepsVelocity_; // Whether a retriggered note keeps the original velocity or a default andrewm@0: int referenceNote_; // Which note acts as the reference point andrewm@0: float globalOffsetCents_; // Offset of every note in cents andrewm@51: andrewm@51: CriticalSection tuningMutex_; // Mutex to avoid triggers during tuning changes andrewm@0: }; andrewm@0: andrewm@0: #endif /* defined(__TouchKeys__TouchkeyKeyDivisionMappingFactory__) */