Mercurial > hg > touchkeys
view Source/TouchKeys/MidiInputController.h @ 20:dfff66c07936
Lots of minor changes to support building on Visual Studio. A few MSVC-specific #ifdefs to eliminate things Visual Studio doesn't like. This version now compiles on Windows (provided liblo, Juce and pthread are present) but the TouchKeys device support is not yet enabled. Also, the code now needs to be re-checked on Mac and Linux.
author | Andrew McPherson <andrewm@eecs.qmul.ac.uk> |
---|---|
date | Sun, 09 Feb 2014 18:40:51 +0000 |
parents | 3580ffe87dc8 |
children | 88287c1c2c92 |
line wrap: on
line source
/* TouchKeys: multi-touch musical keyboard control software Copyright (c) 2013 Andrew McPherson This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ===================================================================== MidiInputController.h: handles incoming MIDI data and manages input ports. Detailed processing is broken down by keyboard segment; see MidiKeyboardSegment.h/cpp for more. */ #ifndef MIDI_INPUT_CONTROLLER_H #define MIDI_INPUT_CONTROLLER_H #include <iostream> #include <vector> #include <map> #include <set> #include "../JuceLibraryCode/JuceHeader.h" #include "PianoKeyboard.h" #include "Osc.h" #include "MidiKeyboardSegment.h" using namespace std; class MidiOutputController; // MIDI standard messages enum { kMidiMessageNoteOff = 0x80, kMidiMessageNoteOn = 0x90, kMidiMessageAftertouchPoly = 0xA0, kMidiMessageControlChange = 0xB0, kMidiMessageProgramChange = 0xC0, kMidiMessageAftertouchChannel = 0xD0, kMidiMessagePitchWheel = 0xE0, kMidiMessageSysex = 0xF0, kMidiMessageSysexEnd = 0xF7, kMidiMessageActiveSense = 0xFE, kMidiMessageReset = 0xFF }; enum { kMidiControlAllSoundOff = 120, kMidiControlAllControllersOff = 121, kMidiControlLocalControl = 122, kMidiControlAllNotesOff = 123 }; class MidiInputController : public MidiInputCallback { public: /* // Operating modes for MIDI input enum { ModeOff = 0, ModePassThrough, ModeMonophonic, ModePolyphonic, ModeChannelSelect, ModeConstantControllers }; // Switch types for Channel Select mode enum { ChannelSelectSwitchTypeUnknown = 0, ChannelSelectSwitchTypeLocation, ChannelSelectSwitchTypeSize, ChannelSelectSwitchTypeNumTouches, ChannelSelectSwitchTypeAngle }; */ public: // Constructor MidiInputController(PianoKeyboard& keyboard); // Query available devices vector<pair<int, string> > availableMidiDevices(); // Add/Remove MIDI input ports; // Enable methods return true on success (at least one port enabled) bool enablePort(int portNumber); bool enableAllPorts(); void disablePort(int portNumber); void disableAllPorts(); vector<int> activePorts(); //void touchkeyStandaloneTouchBegan(int noteNumber, Node<KeyTouchFrame>* touchBuffer); //void touchkeyStandaloneTouchEnded(int noteNumber); /* // Set which channels we listen to bool enableChannel(int channelNumber); bool enableAllChannels(); void disableChannel(int channelNumber); void disableAllChanels(); */ // Set/query the output controller MidiOutputController* midiOutputController() { return midiOutputController_; } void setMidiOutputController(MidiOutputController* ct); // All Notes Off: can be sent by MIDI or controlled programmatically void allNotesOff(); // Return the number of keyboard segments, and a specific segment int numSegments() { ScopedLock sl(segmentsMutex_); return segments_.size(); } MidiKeyboardSegment* segment(int num) { ScopedLock sl(segmentsMutex_); if(num < 0 || num >= segments_.size()) return 0; return segments_[num]; } // Return a unique signature which tells us when the MIDI segments have changed, // allowing any listeners to re-query all the segments. int segmentUniqueIdentifier() { return segmentUniqueIdentifier_; } // Add a new keyboard segment. Returns a pointer to the newly created segment MidiKeyboardSegment* addSegment(int outputPortNumber, int noteMin = 0, int noteMax = 127, int channelMask = 0xFFFF); // Remove a segment by index or by object void removeSegment(int index); void removeSegment(MidiKeyboardSegment* segment); void removeAllSegments(); /* // Change or query the operating mode of the controller int mode() { return mode_; } void setModeOff(); void setModePassThrough(); void setModeMonophonic(); void setModePolyphonic(); void setModeChannelSelect(int switchType, int numDivisions, int defaultChannel); int polyphony() { return retransmitMaxPolyphony_; } void setPolyphony(int polyphony); bool voiceStealingEnabled() { return useVoiceStealing_; } void setVoiceStealingEnabled(bool enable) { useVoiceStealing_ = enable; } */ // Juce MIDI callbacks void handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message); void handlePartialSysexMessage(MidiInput* source, const uint8* messageData, int numBytesSoFar, double timestamp) {} // OSC method: used to get touch callback data from the keyboard // bool oscHandlerMethod(const char *path, const char *types, int numValues, lo_arg **values, void *data); // for logging void createLogFile(string midiLog_filename, string path); void closeLogFile(); void startLogging(); void stopLogging(); bool logFileCreated; bool loggingActive; // Destructor ~MidiInputController(); private: // Filtering by channel: return whether this message concerns one of the active channels // we're listening to. // bool messageIsForActiveChannel(const MidiMessage& message); /* // Mode-specific MIDI input handlers void modePassThroughHandler(MidiInput* source, const MidiMessage& message); void modeMonophonicHandler(MidiInput* source, const MidiMessage& message); void modePolyphonicHandler(MidiInput* source, const MidiMessage& message); void modePolyphonicNoteOn(unsigned char note, unsigned char velocity); void modePolyphonicNoteOff(unsigned char note); void modePolyphonicNoteOnCallback(const char *path, const char *types, int numValues, lo_arg **values); void modeChannelSelectHandler(MidiInput* source, const MidiMessage& message); void modeChannelSelectNoteOn(unsigned char note, unsigned char velocity); void modeChannelSelectNoteOff(unsigned char note); void modeChannelSelectNoteOnCallback(const char *path, const char *types, int numValues, lo_arg **values); void modeConstantControllersHandler(MidiInput* source, const MidiMessage& message); // Helper functions for polyphonic mode void modePolyphonicSetupHelper(); int oldestNote(); int newestNote(); */ // ***** Member Variables ***** PianoKeyboard& keyboard_; // Reference to main keyboard data MidiOutputController *midiOutputController_; // Destination for MIDI output map<int, MidiInput*> activePorts_; // Sources of MIDI data vector<MidiKeyboardSegment*> segments_; // Segments of the keyboard CriticalSection segmentsMutex_; // Mutex protecting the segments list int segmentUniqueIdentifier_; // Identifier of when segment structure has changed /* // Current operating mode of the controller int mode_; // Mapping between input notes and output channels. Depending on the mode of operation, // each note may be rebroadcast on its own MIDI channel. Need to keep track of what goes where. // key is MIDI note #, value is output channel (0-15) map<int, int> retransmitChannelForNote_; set<int> retransmitChannelsAvailable_; int retransmitMaxPolyphony_; bool useVoiceStealing_; map<int, timestamp_type> noteOnsetTimestamps_; // When each currently active note began, for stealing // Parameters for Channel Select mode of operation int channelSelectSwitchType_; int channelSelectNumberOfDivisions_; int channelSelectDefaultChannel_; int channelSelectLastOnsetChannel_; */ // for logging ofstream midiLog; // for generating timestamps // Scheduler eventScheduler_; }; #endif /* MIDI_INPUT_CONTROLLER_H */