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 }