annotate Source/TouchKeys/OscMidiConverter.h @ 56:b4a2d2ae43cf tip

merge
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Fri, 23 Nov 2018 15:48:14 +0000
parents 85577160a0d4
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 OscMidiConverter.h: converts incoming OSC messages to outgoing MIDI
andrewm@0 21 messages with adjustable ranges and parameters.
andrewm@0 22 */
andrewm@0 23
andrewm@0 24 #ifndef __touchkeys__OscMidiConverter__
andrewm@0 25 #define __touchkeys__OscMidiConverter__
andrewm@0 26
andrewm@0 27 #include <vector>
andrewm@0 28 #include "Osc.h"
andrewm@0 29 #include "MidiOutputController.h"
andrewm@0 30 #include "PianoKeyboard.h"
andrewm@0 31 #include "MidiKeyboardSegment.h"
andrewm@0 32
andrewm@0 33 /* OscMidiConverter
andrewm@0 34 *
andrewm@0 35 * This class handles the sending of MIDI output messages of a particular type
andrewm@0 36 * (control change, aftertouch, pitch wheel) in response to incoming OSC messages.
andrewm@0 37 * Each object takes responsibility for one type of MIDI output but can take
andrewm@0 38 * several types of OSC message to control it.
andrewm@0 39 */
andrewm@0 40
andrewm@0 41 class OscMidiConverter : public OscHandler {
andrewm@0 42 public:
andrewm@0 43 // Behavior for out-of-range inputs.
andrewm@0 44 enum {
andrewm@41 45 kOutOfRangeIgnore = 1,
andrewm@0 46 kOutOfRangeClip,
andrewm@0 47 kOutOfRangeExtrapolate
andrewm@0 48 };
andrewm@0 49
andrewm@0 50 private:
andrewm@0 51 // Structure holding information about a given OSC source
andrewm@0 52 struct OscInput {
andrewm@0 53 int uniqueId; // ID to keep track of recent values
andrewm@0 54 int oscParamNumber; // Parameter number in the OSC message we map
andrewm@0 55 float oscMinValue; // Min and max of its input range
andrewm@0 56 float oscMaxValue;
andrewm@0 57 float oscScaledCenterValue; // Value of the input that should correspond to control center,
andrewm@0 58 // pre-normalized to 0-1 range
andrewm@0 59 int outOfRangeBehavior; // What happens at the edge of the range
andrewm@0 60 };
andrewm@0 61
andrewm@0 62 public:
andrewm@0 63 // Constructor
andrewm@0 64 OscMidiConverter(PianoKeyboard& keyboard, MidiKeyboardSegment& segment, int controllerId);
andrewm@0 65
andrewm@0 66 // ***** MIDI methods *****
andrewm@0 67
andrewm@0 68 // Provide a reference to the MidiOutputController which actually sends the messages
andrewm@0 69 void setMidiOutputController(MidiOutputController* m) { midiOutputController_ = m; }
andrewm@0 70
andrewm@0 71 // Set which control this object is handling. If minimum or maximum values are specified,
andrewm@0 72 // then the control will never exceed this range no matter what OSC messages come in.
andrewm@0 73 // use14BitControl specifies whether a 14-bit (paired) MIDI CC message should be used,
andrewm@0 74 // for relevant values of message.
andrewm@0 75 void setMidiMessageType(int defaultValue = -1, int minValue = -1,
andrewm@0 76 int maxValue = -1, int centerValue = -1, bool use14BitControl = false);
andrewm@0 77
andrewm@0 78 // Set whether this converter passes through incoming CC messages from the MIDI input,
andrewm@0 79 // and if so, which one. Doesn't need to be the same CC coming in as going out.
andrewm@0 80 void listenToIncomingControl(int controller, int centerValue = -1, bool use14BitControl = false);
andrewm@0 81
andrewm@0 82 // Force a resend of the current value
andrewm@0 83 void resend(int channel);
andrewm@0 84
andrewm@0 85 // Send the default controller value on the specified channel. Typically used
andrewm@0 86 // before note onset.
andrewm@0 87 void sendDefaultValue(int channel);
andrewm@0 88
andrewm@0 89 // Return the current value of the MIDI controller without sending it
andrewm@0 90 int currentControllerValue(int channel);
andrewm@0 91
andrewm@0 92 // ***** OSC methods *****
andrewm@0 93
andrewm@0 94 // This message specifies an OSC path to be mapped to MIDI, along with its input ranges which
andrewm@0 95 // correspond to the complete specified MIDI range.
andrewm@0 96 void addControl(const string& oscPath, int oscParamNumber, float oscMinValue, float oscMaxValue,
andrewm@0 97 float oscCenterValue, int outOfRangeBehavior);
andrewm@0 98 void removeControl(const string& oscPath);
andrewm@0 99 void removeAllControls();
andrewm@0 100
andrewm@0 101 // These methods update the range for an existing control
andrewm@0 102 void setControlMinValue(const string& oscPath, float newValue);
andrewm@0 103 void setControlMaxValue(const string& oscPath, float newValue);
andrewm@0 104 void setControlCenterValue(const string& oscPath, float newValue);
andrewm@0 105 void setControlOutOfRangeBehavior(const string& oscPath, int newBehavior);
andrewm@0 106
andrewm@0 107 // Reset any active previous values on the given channel
andrewm@0 108 void clearLastValues(int channel, bool send = true);
andrewm@0 109
andrewm@0 110 // OSC Handler Method: called by PianoKeyboard (or other OSC source)
andrewm@0 111 bool oscHandlerMethod(const char *path, const char *types, int numValues, lo_arg **values, void *data);
andrewm@0 112
andrewm@0 113 // Destructor
andrewm@0 114 ~OscMidiConverter() {}
andrewm@0 115
andrewm@0 116 private:
andrewm@0 117 // ***** Private Methods *****
andrewm@0 118 int idWithChannel(int channel, int inputId) { return (inputId << 4) + channel; }
andrewm@0 119 void sendCurrentValue(int port, int channel, int note, bool force);
andrewm@0 120
andrewm@0 121 // ***** Member Variables *****
andrewm@0 122
andrewm@0 123 PianoKeyboard& keyboard_; // Main piano keyboard controller
andrewm@0 124 MidiKeyboardSegment& keyboardSegment_; // Which segment of the keyboard this mapping is using
andrewm@0 125 MidiOutputController* midiOutputController_; // Class handling MIDI output
andrewm@0 126
andrewm@0 127 int controller_; // Which MIDI control to use
andrewm@0 128 bool controllerIs14Bit_; // Whether to use a paired MIDI CC
andrewm@0 129 int controlMinValue_, controlMaxValue_; // Ranges control can take
andrewm@0 130 int controlCenterValue_; // The center value to use when all OSC inputs are 0
andrewm@0 131 int controlDefaultValue_; // Default value for the control on new notes
andrewm@0 132
andrewm@0 133 int lastUniqueId_; // Global unique ID for input messages
andrewm@0 134
andrewm@0 135 int incomingController_; // Which controller we listen to from the MIDI input
andrewm@0 136 bool incomingControllerIs14Bit_; // Whether the input controller is 14 bit
andrewm@0 137 int incomingControllerCenterValue_; // The center value to subtract from the incoming controller
andrewm@0 138
andrewm@0 139 std::map<std::string, OscInput> inputs_; // OSC sources for this MIDI output
andrewm@0 140 std::map<int, float> lastValues_; // Recently received values from each OSC input
andrewm@0 141
andrewm@0 142 float currentValue_[16]; // Current sum value of all inputs for each channel
andrewm@0 143 int lastOutputValue_[16]; // The last value we sent out; saved to avoid duplicate messages
andrewm@0 144 };
andrewm@0 145
andrewm@0 146 #endif /* defined(__touchkeys__OscMidiConverter__) */