f@0
|
1 #pragma once
|
f@0
|
2
|
f@0
|
3 #include "RtMidi.h"
|
f@0
|
4 #include <memory>
|
f@0
|
5 #include <mutex>
|
f@0
|
6 #include <array>
|
f@0
|
7
|
f@0
|
8 class Config;
|
f@0
|
9
|
f@0
|
10
|
f@0
|
11 namespace collidoscope {
|
f@0
|
12
|
f@0
|
13
|
f@0
|
14 class MIDIException : public std::exception
|
f@0
|
15 {
|
f@0
|
16 public:
|
f@0
|
17
|
f@0
|
18 MIDIException( std::string message ) : mMessage( message ) {}
|
f@0
|
19
|
f@0
|
20 virtual const std::string& getMessage( void ) const { return mMessage; }
|
f@0
|
21
|
f@0
|
22 #ifdef _WINDOWS
|
f@0
|
23 const char* what() const override { return mMessage.c_str(); }
|
f@0
|
24 #else
|
f@0
|
25 const char* what() const noexcept override { return mMessage.c_str(); }
|
f@0
|
26 #endif
|
f@0
|
27
|
f@0
|
28 protected:
|
f@0
|
29 std::string mMessage;
|
f@0
|
30 };
|
f@0
|
31
|
f@3
|
32 /**
|
f@3
|
33 * A MIDI message
|
f@3
|
34 */
|
f@0
|
35 class MIDIMessage
|
f@0
|
36 {
|
f@0
|
37 friend class MIDI;
|
f@0
|
38 public:
|
f@0
|
39
|
f@0
|
40 enum class Voice { eNoteOn, eNoteOff, ePitchBend, eControlChange, eIgnore };
|
f@0
|
41
|
f@0
|
42 Voice getVoice() { return mVoice; }
|
f@0
|
43
|
f@0
|
44 unsigned char getChannel() { return mChannel; }
|
f@0
|
45
|
f@3
|
46 /**
|
f@3
|
47 * First byte of MIDI data
|
f@3
|
48 */
|
f@0
|
49 unsigned char getData_1() { return mData1; }
|
f@0
|
50
|
f@3
|
51 /**
|
f@3
|
52 * Second byte of MIDI data
|
f@3
|
53 */
|
f@0
|
54 unsigned char getData_2() { return mData2; }
|
f@0
|
55
|
f@0
|
56 private:
|
f@0
|
57
|
f@0
|
58 Voice mVoice = Voice::eIgnore;
|
f@0
|
59 unsigned char mChannel;
|
f@0
|
60 unsigned char mData1;
|
f@0
|
61 unsigned char mData2;
|
f@0
|
62
|
f@0
|
63
|
f@0
|
64 };
|
f@0
|
65
|
f@3
|
66 /**
|
f@3
|
67 * Handles MIDI messages from the keyboards and Teensy. It uses RtMidi library.
|
f@3
|
68 *
|
f@3
|
69 */
|
f@0
|
70 class MIDI
|
f@0
|
71 {
|
f@0
|
72
|
f@0
|
73 public:
|
f@0
|
74
|
f@0
|
75 MIDI();
|
f@0
|
76 ~MIDI();
|
f@0
|
77
|
f@0
|
78 void setup( const Config& );
|
f@0
|
79
|
f@3
|
80 /**
|
f@3
|
81 * Check new incoming messages and stores them into the vector passed as argument by reference.
|
f@3
|
82 */
|
f@0
|
83 void checkMessages( std::vector< MIDIMessage >& );
|
f@0
|
84
|
f@0
|
85 private:
|
f@0
|
86
|
f@3
|
87 // callback passed to RtMidi library
|
f@0
|
88 static void RtMidiInCallback( double deltatime, std::vector<unsigned char> *message, void *userData );
|
f@0
|
89
|
f@3
|
90 // parse RtMidi messages and turns them into more readable collidoscope::MIDIMessages
|
f@0
|
91 MIDIMessage parseRtMidiMessage( std::vector<unsigned char> *message );
|
f@0
|
92
|
f@3
|
93 // messages to pass to checkMessages caller
|
f@0
|
94 std::vector< MIDIMessage > mMIDIMessages;
|
f@3
|
95 // use specific variables for pitch bend messages. Pitch bend messages are coming
|
f@3
|
96 // from the strip sensors that are very jerky and send a lot of values. So instead
|
f@3
|
97 // of saving all the messages in mMIDIMessages just save the last received in mPitchBendMessages
|
f@3
|
98 // and optimize away redundant messages.
|
f@0
|
99 std::array< MIDIMessage, NUM_WAVES > mPitchBendMessages;
|
f@3
|
100 // Same principle of pitch bend messages
|
f@0
|
101 std::array< MIDIMessage, NUM_WAVES > mFilterMessages;
|
f@0
|
102
|
f@3
|
103 // vecotr containing all the MIDI input devices detected.
|
f@0
|
104 std::vector< std::unique_ptr <RtMidiIn> > mInputs;
|
f@3
|
105 // Used for mutual access to the MIDI messages by the MIDI thread and the graphic thread.
|
f@0
|
106 std::mutex mMutex;
|
f@0
|
107 };
|
f@0
|
108
|
f@0
|
109
|
f@0
|
110
|
f@0
|
111 } // collidsocope }
|