f@5
|
1 /*
|
f@5
|
2
|
f@5
|
3 Copyright (C) 2016 Queen Mary University of London
|
f@5
|
4 Author: Fiore Martin
|
f@5
|
5
|
f@5
|
6 This file is part of Collidoscope.
|
f@5
|
7
|
f@5
|
8 Collidoscope is free software: you can redistribute it and/or modify
|
f@5
|
9 it under the terms of the GNU General Public License as published by
|
f@5
|
10 the Free Software Foundation, either version 3 of the License, or
|
f@5
|
11 (at your option) any later version.
|
f@5
|
12
|
f@5
|
13 This program is distributed in the hope that it will be useful,
|
f@5
|
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
f@5
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
f@5
|
16 GNU General Public License for more details.
|
f@5
|
17
|
f@5
|
18 You should have received a copy of the GNU General Public License
|
f@5
|
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
f@5
|
20 */
|
f@5
|
21
|
f@0
|
22 #pragma once
|
f@0
|
23
|
f@0
|
24 #include "RtMidi.h"
|
f@0
|
25 #include <memory>
|
f@0
|
26 #include <mutex>
|
f@0
|
27 #include <array>
|
f@0
|
28
|
f@0
|
29 class Config;
|
f@0
|
30
|
f@0
|
31
|
f@0
|
32 namespace collidoscope {
|
f@0
|
33
|
f@16
|
34 // Exception thrown by MIDI system
|
f@0
|
35 class MIDIException : public std::exception
|
f@0
|
36 {
|
f@0
|
37 public:
|
f@0
|
38
|
f@0
|
39 MIDIException( std::string message ) : mMessage( message ) {}
|
f@0
|
40
|
f@0
|
41 virtual const std::string& getMessage( void ) const { return mMessage; }
|
f@0
|
42
|
f@0
|
43 #ifdef _WINDOWS
|
f@0
|
44 const char* what() const override { return mMessage.c_str(); }
|
f@0
|
45 #else
|
f@0
|
46 const char* what() const noexcept override { return mMessage.c_str(); }
|
f@0
|
47 #endif
|
f@0
|
48
|
f@0
|
49 protected:
|
f@0
|
50 std::string mMessage;
|
f@0
|
51 };
|
f@0
|
52
|
f@3
|
53 /**
|
f@3
|
54 * A MIDI message
|
f@3
|
55 */
|
f@0
|
56 class MIDIMessage
|
f@0
|
57 {
|
f@0
|
58 friend class MIDI;
|
f@0
|
59 public:
|
f@0
|
60
|
f@0
|
61 enum class Voice { eNoteOn, eNoteOff, ePitchBend, eControlChange, eIgnore };
|
f@0
|
62
|
f@0
|
63 Voice getVoice() { return mVoice; }
|
f@0
|
64
|
f@0
|
65 unsigned char getChannel() { return mChannel; }
|
f@0
|
66
|
f@3
|
67 /**
|
f@3
|
68 * First byte of MIDI data
|
f@3
|
69 */
|
f@0
|
70 unsigned char getData_1() { return mData1; }
|
f@0
|
71
|
f@3
|
72 /**
|
f@3
|
73 * Second byte of MIDI data
|
f@3
|
74 */
|
f@0
|
75 unsigned char getData_2() { return mData2; }
|
f@0
|
76
|
f@0
|
77 private:
|
f@0
|
78
|
f@0
|
79 Voice mVoice = Voice::eIgnore;
|
f@0
|
80 unsigned char mChannel;
|
f@0
|
81 unsigned char mData1;
|
f@0
|
82 unsigned char mData2;
|
f@0
|
83
|
f@0
|
84
|
f@0
|
85 };
|
f@0
|
86
|
f@3
|
87 /**
|
f@3
|
88 * Handles MIDI messages from the keyboards and Teensy. It uses RtMidi library.
|
f@3
|
89 *
|
f@3
|
90 */
|
f@0
|
91 class MIDI
|
f@0
|
92 {
|
f@0
|
93
|
f@0
|
94 public:
|
f@0
|
95
|
f@0
|
96 MIDI();
|
f@0
|
97 ~MIDI();
|
f@0
|
98
|
f@0
|
99 void setup( const Config& );
|
f@0
|
100
|
f@3
|
101 /**
|
f@3
|
102 * Check new incoming messages and stores them into the vector passed as argument by reference.
|
f@3
|
103 */
|
f@0
|
104 void checkMessages( std::vector< MIDIMessage >& );
|
f@0
|
105
|
f@0
|
106 private:
|
f@0
|
107
|
f@3
|
108 // callback passed to RtMidi library
|
f@0
|
109 static void RtMidiInCallback( double deltatime, std::vector<unsigned char> *message, void *userData );
|
f@0
|
110
|
f@3
|
111 // parse RtMidi messages and turns them into more readable collidoscope::MIDIMessages
|
f@0
|
112 MIDIMessage parseRtMidiMessage( std::vector<unsigned char> *message );
|
f@0
|
113
|
f@3
|
114 // messages to pass to checkMessages caller
|
f@0
|
115 std::vector< MIDIMessage > mMIDIMessages;
|
f@3
|
116 // use specific variables for pitch bend messages. Pitch bend messages are coming
|
f@3
|
117 // from the strip sensors that are very jerky and send a lot of values. So instead
|
f@3
|
118 // of saving all the messages in mMIDIMessages just save the last received in mPitchBendMessages
|
f@3
|
119 // and optimize away redundant messages.
|
f@0
|
120 std::array< MIDIMessage, NUM_WAVES > mPitchBendMessages;
|
f@16
|
121 // Same principle as mPitchBendMessages
|
f@0
|
122 std::array< MIDIMessage, NUM_WAVES > mFilterMessages;
|
f@0
|
123
|
f@16
|
124 // vector containing all the MIDI input devices detected.
|
f@0
|
125 std::vector< std::unique_ptr <RtMidiIn> > mInputs;
|
f@3
|
126 // Used for mutual access to the MIDI messages by the MIDI thread and the graphic thread.
|
f@0
|
127 std::mutex mMutex;
|
f@0
|
128 };
|
f@0
|
129
|
f@0
|
130
|
f@0
|
131
|
f@0
|
132 } // collidsocope }
|