f@5: /* f@5: f@5: Copyright (C) 2016 Queen Mary University of London f@5: Author: Fiore Martin f@5: f@5: This file is part of Collidoscope. f@5: f@5: Collidoscope is free software: you can redistribute it and/or modify f@5: it under the terms of the GNU General Public License as published by f@5: the Free Software Foundation, either version 3 of the License, or f@5: (at your option) any later version. f@5: f@5: This program is distributed in the hope that it will be useful, f@5: but WITHOUT ANY WARRANTY; without even the implied warranty of f@5: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the f@5: GNU General Public License for more details. f@5: f@5: You should have received a copy of the GNU General Public License f@5: along with this program. If not, see . f@5: */ f@5: f@0: #pragma once f@0: f@0: #include "RtMidi.h" f@0: #include f@0: #include f@0: #include f@0: f@0: class Config; f@0: f@0: f@0: namespace collidoscope { f@0: f@16: // Exception thrown by MIDI system f@0: class MIDIException : public std::exception f@0: { f@0: public: f@0: f@0: MIDIException( std::string message ) : mMessage( message ) {} f@0: f@0: virtual const std::string& getMessage( void ) const { return mMessage; } f@0: f@0: #ifdef _WINDOWS f@0: const char* what() const override { return mMessage.c_str(); } f@0: #else f@0: const char* what() const noexcept override { return mMessage.c_str(); } f@0: #endif f@0: f@0: protected: f@0: std::string mMessage; f@0: }; f@0: f@3: /** f@3: * A MIDI message f@3: */ f@0: class MIDIMessage f@0: { f@0: friend class MIDI; f@0: public: f@0: f@0: enum class Voice { eNoteOn, eNoteOff, ePitchBend, eControlChange, eIgnore }; f@0: f@0: Voice getVoice() { return mVoice; } f@0: f@0: unsigned char getChannel() { return mChannel; } f@0: f@3: /** f@3: * First byte of MIDI data f@3: */ f@0: unsigned char getData_1() { return mData1; } f@0: f@3: /** f@3: * Second byte of MIDI data f@3: */ f@0: unsigned char getData_2() { return mData2; } f@0: f@0: private: f@0: f@0: Voice mVoice = Voice::eIgnore; f@0: unsigned char mChannel; f@0: unsigned char mData1; f@0: unsigned char mData2; f@0: f@0: f@0: }; f@0: f@3: /** f@3: * Handles MIDI messages from the keyboards and Teensy. It uses RtMidi library. f@3: * f@3: */ f@0: class MIDI f@0: { f@0: f@0: public: f@0: f@0: MIDI(); f@0: ~MIDI(); f@0: f@0: void setup( const Config& ); f@0: f@3: /** f@3: * Check new incoming messages and stores them into the vector passed as argument by reference. f@3: */ f@0: void checkMessages( std::vector< MIDIMessage >& ); f@0: f@0: private: f@0: f@3: // callback passed to RtMidi library f@0: static void RtMidiInCallback( double deltatime, std::vector *message, void *userData ); f@0: f@3: // parse RtMidi messages and turns them into more readable collidoscope::MIDIMessages f@0: MIDIMessage parseRtMidiMessage( std::vector *message ); f@0: f@3: // messages to pass to checkMessages caller f@0: std::vector< MIDIMessage > mMIDIMessages; f@3: // use specific variables for pitch bend messages. Pitch bend messages are coming f@3: // from the strip sensors that are very jerky and send a lot of values. So instead f@3: // of saving all the messages in mMIDIMessages just save the last received in mPitchBendMessages f@3: // and optimize away redundant messages. f@0: std::array< MIDIMessage, NUM_WAVES > mPitchBendMessages; f@16: // Same principle as mPitchBendMessages f@0: std::array< MIDIMessage, NUM_WAVES > mFilterMessages; f@0: f@16: // vector containing all the MIDI input devices detected. f@0: std::vector< std::unique_ptr > mInputs; f@3: // Used for mutual access to the MIDI messages by the MIDI thread and the graphic thread. f@0: std::mutex mMutex; f@0: }; f@0: f@0: f@0: f@0: } // collidsocope }