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 TouchkeyPitchBendMappingFactory.cpp: factory for the pitch-bend mapping,
|
andrewm@0
|
21 which handles changing pitch based on relative finger motion.
|
andrewm@0
|
22 */
|
andrewm@0
|
23
|
andrewm@0
|
24 #include "TouchkeyPitchBendMappingFactory.h"
|
andrewm@0
|
25 #include "TouchkeyPitchBendMappingShortEditor.h"
|
andrewm@0
|
26
|
andrewm@0
|
27 // Default constructor, containing a reference to the PianoKeyboard class.
|
andrewm@0
|
28
|
andrewm@0
|
29 TouchkeyPitchBendMappingFactory::TouchkeyPitchBendMappingFactory(PianoKeyboard &keyboard, MidiKeyboardSegment& segment) :
|
andrewm@0
|
30 TouchkeyBaseMappingFactory<TouchkeyPitchBendMapping>(keyboard, segment),
|
andrewm@0
|
31 bendRangeSemitones_(TouchkeyPitchBendMapping::kDefaultBendRangeSemitones),
|
andrewm@0
|
32 bendThresholdSemitones_(TouchkeyPitchBendMapping::kDefaultBendThresholdSemitones),
|
andrewm@0
|
33 bendThresholdKeyLength_(TouchkeyPitchBendMapping::kDefaultBendThresholdKeyLength),
|
andrewm@0
|
34 bendMode_(TouchkeyPitchBendMapping::kDefaultPitchBendMode),
|
andrewm@0
|
35 fixedModeMinEnableDistance_(TouchkeyPitchBendMapping::kDefaultFixedModeEnableDistance),
|
andrewm@0
|
36 fixedModeBufferDistance_(TouchkeyPitchBendMapping::kDefaultFixedModeBufferDistance),
|
andrewm@0
|
37 bendIgnoresTwoFingers_(TouchkeyPitchBendMapping::kDefaultIgnoresTwoFingers),
|
andrewm@0
|
38 bendIgnoresThreeFingers_(TouchkeyPitchBendMapping::kDefaultIgnoresThreeFingers)
|
andrewm@0
|
39 {
|
andrewm@0
|
40 // Set up the MIDI converter to use pitch wheel
|
andrewm@0
|
41 // setName("/touchkeys/pitchbend");
|
andrewm@0
|
42 setBendParameters();
|
andrewm@0
|
43 }
|
andrewm@0
|
44
|
andrewm@0
|
45 // ***** Destructor *****
|
andrewm@0
|
46
|
andrewm@0
|
47 TouchkeyPitchBendMappingFactory::~TouchkeyPitchBendMappingFactory() {
|
andrewm@0
|
48
|
andrewm@0
|
49 }
|
andrewm@0
|
50
|
andrewm@0
|
51 // ***** Accessors / Modifiers *****
|
andrewm@0
|
52
|
andrewm@0
|
53 void TouchkeyPitchBendMappingFactory::setName(const string& name) {
|
andrewm@0
|
54 TouchkeyBaseMappingFactory<TouchkeyPitchBendMapping>::setName(name);
|
andrewm@0
|
55 setBendParameters();
|
andrewm@0
|
56 }
|
andrewm@0
|
57
|
andrewm@0
|
58
|
andrewm@0
|
59 // ***** Bend Methods *****
|
andrewm@0
|
60
|
andrewm@0
|
61 void TouchkeyPitchBendMappingFactory::setBendRange(float rangeSemitones, bool updateCurrent) {
|
andrewm@0
|
62 /*if(updateCurrent) {
|
andrewm@0
|
63 // Send new range to all active mappings
|
andrewm@0
|
64 // TODO: mutex protect
|
andrewm@0
|
65 std::map<int, mapping_pair>::iterator it = mappings_.begin();
|
andrewm@0
|
66 while(it != mappings_.end()) {
|
andrewm@0
|
67 // Tell this mapping to update its range
|
andrewm@0
|
68 TouchkeyPitchBendMapping *mapping = it->second.second;
|
andrewm@0
|
69 mapping->setRange(rangeSemitones);
|
andrewm@0
|
70 it++;
|
andrewm@0
|
71 }
|
andrewm@0
|
72 }*/
|
andrewm@0
|
73
|
andrewm@0
|
74 bendRangeSemitones_ = rangeSemitones;
|
andrewm@0
|
75 }
|
andrewm@0
|
76
|
andrewm@0
|
77 void TouchkeyPitchBendMappingFactory::setBendThresholdSemitones(float thresholdSemitones) {
|
andrewm@0
|
78 bendThresholdSemitones_ = thresholdSemitones;
|
andrewm@0
|
79 }
|
andrewm@0
|
80
|
andrewm@0
|
81 void TouchkeyPitchBendMappingFactory::setBendThresholdKeyLength(float thresholdKeyLength) {
|
andrewm@0
|
82 bendThresholdKeyLength_ = thresholdKeyLength;
|
andrewm@0
|
83 }
|
andrewm@0
|
84
|
andrewm@0
|
85 void TouchkeyPitchBendMappingFactory::setBendThresholds(float thresholdSemitones, float thresholdKeyLength, bool updateCurrent) {
|
andrewm@0
|
86 /*if(updateCurrent) {
|
andrewm@0
|
87 // Send new range to all active mappings
|
andrewm@0
|
88 // TODO: mutex protect
|
andrewm@0
|
89 std::map<int, mapping_pair>::iterator it = mappings_.begin();
|
andrewm@0
|
90 while(it != mappings_.end()) {
|
andrewm@0
|
91 // Tell this mapping to update its range
|
andrewm@0
|
92 TouchkeyPitchBendMapping *mapping = it->second.second;
|
andrewm@0
|
93 mapping->setThresholds(thresholdSemitones, thresholdKeyLength);
|
andrewm@0
|
94 it++;
|
andrewm@0
|
95 }
|
andrewm@0
|
96 }*/
|
andrewm@0
|
97
|
andrewm@0
|
98 bendThresholdSemitones_ = thresholdSemitones;
|
andrewm@0
|
99 bendThresholdKeyLength_ = thresholdKeyLength;
|
andrewm@0
|
100 }
|
andrewm@0
|
101
|
andrewm@0
|
102 // Set the mode to bend a fixed amount up and down the key, regardless of where
|
andrewm@0
|
103 // the touch starts. minimumDistanceToEnable sets a floor below which the bend isn't
|
andrewm@0
|
104 // possible (for starting very close to an edge) and bufferAtEnd sets the amount
|
andrewm@0
|
105 // of key length beyond which no further bend takes place.
|
andrewm@0
|
106 void TouchkeyPitchBendMappingFactory::setBendFixedEndpoints(float minimumDistanceToEnable, float bufferAtEnd) {
|
andrewm@0
|
107 bendMode_ = TouchkeyPitchBendMapping::kPitchBendModeFixedEndpoints;
|
andrewm@0
|
108 fixedModeMinEnableDistance_ = minimumDistanceToEnable;
|
andrewm@0
|
109 fixedModeBufferDistance_ = bufferAtEnd;
|
andrewm@0
|
110 }
|
andrewm@0
|
111
|
andrewm@0
|
112 // Set the mode to bend an amount proportional to distance, which means
|
andrewm@0
|
113 // that the total range of bend will depend on where the finger started.
|
andrewm@0
|
114 void TouchkeyPitchBendMappingFactory::setBendVariableEndpoints() {
|
andrewm@0
|
115 bendMode_ = TouchkeyPitchBendMapping::kPitchBendModeVariableEndpoints;
|
andrewm@0
|
116 }
|
andrewm@0
|
117
|
andrewm@0
|
118 void TouchkeyPitchBendMappingFactory::setBendIgnoresMultipleFingers(bool ignoresTwo, bool ignoresThree) {
|
andrewm@0
|
119 // TODO: update current
|
andrewm@0
|
120 bendIgnoresTwoFingers_ = ignoresTwo;
|
andrewm@0
|
121 bendIgnoresThreeFingers_ = ignoresThree;
|
andrewm@0
|
122 }
|
andrewm@0
|
123
|
andrewm@0
|
124 // ***** GUI Support *****
|
andrewm@0
|
125 MappingEditorComponent* TouchkeyPitchBendMappingFactory::createBasicEditor() {
|
andrewm@0
|
126 return new TouchkeyPitchBendMappingShortEditor(*this);
|
andrewm@0
|
127 }
|
andrewm@0
|
128
|
andrewm@0
|
129 // ***** Private Methods *****
|
andrewm@0
|
130
|
andrewm@0
|
131 // Set the initial parameters for a new mapping
|
andrewm@0
|
132 void TouchkeyPitchBendMappingFactory::initializeMappingParameters(int noteNumber, TouchkeyPitchBendMapping *mapping) {
|
andrewm@0
|
133 mapping->setRange(bendRangeSemitones_);
|
andrewm@0
|
134 mapping->setThresholds(bendThresholdSemitones_, bendThresholdKeyLength_);
|
andrewm@0
|
135 if(bendMode_ == TouchkeyPitchBendMapping::kPitchBendModeFixedEndpoints) {
|
andrewm@0
|
136 mapping->setFixedEndpoints(fixedModeMinEnableDistance_, fixedModeBufferDistance_);
|
andrewm@0
|
137 }
|
andrewm@0
|
138 else
|
andrewm@0
|
139 mapping->setVariableEndpoints();
|
andrewm@0
|
140 mapping->setIgnoresMultipleFingers(bendIgnoresTwoFingers_, bendIgnoresThreeFingers_);
|
andrewm@0
|
141 }
|
andrewm@0
|
142
|
andrewm@0
|
143 void TouchkeyPitchBendMappingFactory::setBendParameters() {
|
andrewm@7
|
144 // Range of 0 indicates special case of using global pitch wheel range
|
andrewm@7
|
145 setMidiParameters(MidiKeyboardSegment::kControlPitchWheel, 0.0, 0.0, 0.0);
|
andrewm@0
|
146
|
andrewm@0
|
147 if(midiConverter_ != 0) {
|
andrewm@0
|
148 midiConverter_->listenToIncomingControl(MidiKeyboardSegment::kControlPitchWheel);
|
andrewm@0
|
149 }
|
andrewm@0
|
150 }
|