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: MidiInputController.h: handles incoming MIDI data and manages input andrewm@0: ports. Detailed processing is broken down by keyboard segment; see andrewm@0: MidiKeyboardSegment.h/cpp for more. andrewm@0: */ andrewm@0: andrewm@0: andrewm@0: #ifndef MIDI_INPUT_CONTROLLER_H andrewm@0: #define MIDI_INPUT_CONTROLLER_H andrewm@0: andrewm@0: #include andrewm@0: #include andrewm@0: #include andrewm@0: #include andrewm@0: #include "../JuceLibraryCode/JuceHeader.h" andrewm@0: #include "PianoKeyboard.h" andrewm@0: #include "Osc.h" andrewm@0: #include "MidiKeyboardSegment.h" andrewm@0: andrewm@0: using namespace std; andrewm@0: andrewm@0: class MidiOutputController; andrewm@0: andrewm@0: // MIDI standard messages andrewm@0: andrewm@0: enum { andrewm@0: kMidiMessageNoteOff = 0x80, andrewm@0: kMidiMessageNoteOn = 0x90, andrewm@0: kMidiMessageAftertouchPoly = 0xA0, andrewm@0: kMidiMessageControlChange = 0xB0, andrewm@0: kMidiMessageProgramChange = 0xC0, andrewm@0: kMidiMessageAftertouchChannel = 0xD0, andrewm@0: kMidiMessagePitchWheel = 0xE0, andrewm@0: kMidiMessageSysex = 0xF0, andrewm@0: kMidiMessageSysexEnd = 0xF7, andrewm@0: kMidiMessageActiveSense = 0xFE, andrewm@0: kMidiMessageReset = 0xFF andrewm@0: }; andrewm@0: andrewm@0: enum { andrewm@0: kMidiControlAllSoundOff = 120, andrewm@0: kMidiControlAllControllersOff = 121, andrewm@0: kMidiControlLocalControl = 122, andrewm@0: kMidiControlAllNotesOff = 123 andrewm@0: }; andrewm@0: andrewm@0: class MidiInputController : public MidiInputCallback { andrewm@0: public: andrewm@0: // Constructor andrewm@0: MidiInputController(PianoKeyboard& keyboard); andrewm@0: andrewm@0: // Query available devices andrewm@0: vector > availableMidiDevices(); andrewm@0: andrewm@0: // Add/Remove MIDI input ports; andrewm@0: // Enable methods return true on success (at least one port enabled) andrewm@31: bool enablePort(int portNumber, bool isPrimary); andrewm@31: bool enableAllPorts(int primaryPortNumber); andrewm@0: void disablePort(int portNumber); andrewm@31: void disablePrimaryPort(); andrewm@31: void disableAllPorts(bool auxiliaryOnly); andrewm@31: int primaryActivePort(); andrewm@31: vector auxiliaryActivePorts(); andrewm@41: andrewm@41: // Get the name of a particular port index andrewm@41: String deviceName(int portNumber); andrewm@41: int indexOfDeviceNamed(String const& name); andrewm@0: andrewm@0: // Set/query the output controller andrewm@0: MidiOutputController* midiOutputController() { return midiOutputController_; } andrewm@0: void setMidiOutputController(MidiOutputController* ct); andrewm@0: andrewm@0: // All Notes Off: can be sent by MIDI or controlled programmatically andrewm@0: void allNotesOff(); andrewm@0: andrewm@0: // Return the number of keyboard segments, and a specific segment andrewm@0: int numSegments() { andrewm@0: ScopedLock sl(segmentsMutex_); andrewm@0: return segments_.size(); andrewm@0: } andrewm@0: MidiKeyboardSegment* segment(int num) { andrewm@0: ScopedLock sl(segmentsMutex_); andrewm@0: if(num < 0 || num >= segments_.size()) andrewm@0: return 0; andrewm@0: return segments_[num]; andrewm@0: } andrewm@0: // Return a unique signature which tells us when the MIDI segments have changed, andrewm@0: // allowing any listeners to re-query all the segments. andrewm@0: int segmentUniqueIdentifier() { andrewm@0: return segmentUniqueIdentifier_; andrewm@0: } andrewm@0: andrewm@0: // Add a new keyboard segment. Returns a pointer to the newly created segment andrewm@0: MidiKeyboardSegment* addSegment(int outputPortNumber, int noteMin = 0, int noteMax = 127, int channelMask = 0xFFFF); andrewm@0: andrewm@0: // Remove a segment by index or by object andrewm@49: bool removeSegment(int index); andrewm@49: bool removeSegment(MidiKeyboardSegment* segment); andrewm@0: void removeAllSegments(); andrewm@0: andrewm@33: // Preset save/load for keyboard segments andrewm@33: XmlElement* getSegmentPreset(); andrewm@33: bool loadSegmentPreset(XmlElement const* preset); andrewm@33: andrewm@49: // OSC handling for keyboard segments andrewm@49: OscMessage* oscControlMessageForSegment(int segment, const char *path, const char *types, int numValues, lo_arg **values, void *data); andrewm@49: andrewm@0: // Juce MIDI callbacks andrewm@0: void handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message); andrewm@0: void handlePartialSysexMessage(MidiInput* source, andrewm@0: const uint8* messageData, andrewm@0: int numBytesSoFar, andrewm@0: double timestamp) {} andrewm@0: andrewm@0: // OSC method: used to get touch callback data from the keyboard andrewm@0: // bool oscHandlerMethod(const char *path, const char *types, int numValues, lo_arg **values, void *data); andrewm@0: andrewm@0: // for logging andrewm@0: void createLogFile(string midiLog_filename, string path); andrewm@0: void closeLogFile(); andrewm@0: void startLogging(); andrewm@0: void stopLogging(); andrewm@0: andrewm@0: bool logFileCreated; andrewm@0: bool loggingActive; andrewm@0: andrewm@0: // Destructor andrewm@0: ~MidiInputController(); andrewm@0: andrewm@0: private: andrewm@0: // ***** Member Variables ***** andrewm@0: andrewm@0: PianoKeyboard& keyboard_; // Reference to main keyboard data andrewm@0: MidiOutputController *midiOutputController_; // Destination for MIDI output andrewm@0: andrewm@0: map activePorts_; // Sources of MIDI data andrewm@31: int primaryActivePort_; // Which source is primary andrewm@0: andrewm@0: vector segments_; // Segments of the keyboard andrewm@0: CriticalSection segmentsMutex_; // Mutex protecting the segments list andrewm@0: int segmentUniqueIdentifier_; // Identifier of when segment structure has changed andrewm@0: andrewm@0: // for logging andrewm@0: ofstream midiLog; andrewm@0: }; andrewm@0: andrewm@0: #endif /* MIDI_INPUT_CONTROLLER_H */