CSL  5.2
MIDIIOJ.h
Go to the documentation of this file.
1 ///
2 /// MIDIIOJ.h -- MIDI IO using JUCE
3 ///
4 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
5 ///
6 
7 #ifndef CSL_MIDIIO_H
8 #define CSL_MIDIIO_H
9 
10 #include "CSL_Types.h"
11 #include "CGestalt.h"
12 #include "ThreadUtilities.h"
13 #include "Instrument.h"
14 #include "../JuceLibraryCode/JuceHeader.h"
15 //#include "src/juce_appframework/audio/midi/juce_MidiBuffer.h"
16 //#include "src/juce_appframework/audio/midi/juce_MidiFile.h"
17 //#include "src/juce_appframework/audio/midi/juce_MidiMessage.h"
18 //#include "src/juce_appframework/audio/midi/juce_MidiMessageSequence.h"
19 //#include "src/juce_appframework/audio/devices/juce_MidiInput.h"
20 //#include "src/juce_appframework/audio/devices/juce_MidiOutput.h"
21 
22 namespace csl {
23 
24 /// CMIDIMessageType enum of midi msg categories
25 
26 typedef enum {
27  kNone = 0,
28  kNoteOff = 8,
29  kNoteOn = 9,
30  kPolyTouch = 10,
35  kSysEX = 15
37 
38 /// Message_ChannelToStatus -- converts from message and channel to status byte
39 
40 #define MessageChannelToStatus(message, channel) ((unsigned) message << 4) + channel)
41 
42 ///
43 /// CMIDIMessage class (mapped to juce::MidiMessage)
44 ///
45 
46 class CMIDIMessage {
47 public:
48  CMIDIMessage();
49  CMIDIMessage(CMIDIMessageType t, unsigned ch, unsigned d1, unsigned d2);
50 
51  bool isNoteOn(); ///< bool flags for events
52  bool isNoteOff();
53  bool isNoteOnOff();
54  bool isPolyTouch();
55  bool isControlChange();
56  bool isProgramChange();
57  bool isAftertouch();
58  bool isPitchWheel();
59  bool isSysEX();
60 
61  unsigned getCommand(); ///< note accessors
62  unsigned getNote();
63  unsigned getVelocity();
64  unsigned getPolyAftertouch();
65  unsigned getControlFunction();
66  unsigned getControlValue();
67  unsigned getProgramNumber();
68  unsigned getAftertouch();
69  unsigned getPitchWheel();
70  float getFrequency();
71  float getVelocityFloat(); ///< has range of [0.0 1.0] mapped to [0 127]
72  /// Data fields
73  CMIDIMessageType message; ///< event type
74  unsigned command;
75  unsigned channel; ///< 0-indexed, so from 0 to 15
76  unsigned data1;
77  unsigned data2;
78  float time; ///< timestamp in sec
79 };
80 
81 
82 /// MIDIIO class: superclass of in and out; has a message buffer and current messages
83 /// It's a model so you can observe it.
84 /// Uses mMsg.CMIDIMessageType as a status flag.
85 
86 class MIDIIO: public Model { ///< It's a model & sends itself "changed"
87 public:
88  MIDIIO();
89  virtual ~MIDIIO();
90 
91  static int countDevices();
92  static void dumpDevices(); ///< printing device info for all devices.
93 
94  void open(); ///< open the abstract
95  virtual void open(int devID) = 0; ///< open a device
96  bool isOpen(); ///< true if MIDI stream is opened.
97  virtual void close(); ///< closing MIDI stream
98  virtual void start() { }; ///< start MIDI stream
99  virtual void stop() { }; ///< stop MIDI stream
100  virtual void clear(); ///< clear MIDI stream
101  void dumpBuffer();
102 
103  int mDeviceID; ///< device ID which will/is opened.
104  CMIDIMessage mMsg; ///< current message (its flags determine the port state)
106  MidiBuffer mBuffer; ///< I/O buffer
107 
108 protected: ///< static flags to keep track of driver state
109  static bool mIsInitialized;
110 
111  MidiMessage * mJMsg; ///< JUCE-format message
112 
113  bool mIsOpen; ///< instance status indicators
116  /// error handler
117  void handleError(CException * err);
118 
119  /// copy csl::CMIDIMessage <--> juce::MidiMessage
120  void copyMessage(CMIDIMessage& source, CMIDIMessage& dest);
121  void copyMessage(CMIDIMessage& source, MidiMessage* dest);
122  void copyMessage(const MidiMessage& source, CMIDIMessage& dest);
123 };
124 
125 
126 ///
127 /// MIDIIn class is-a MidiInputCallback too, and an "input-ready" flag
128 ///
129 
130 class MIDIIn : public MIDIIO, public MidiInputCallback {
131 public:
132  MIDIIn();
133 
134  unsigned bufferSize();
135  void setBufferSize(unsigned bufferSize );
136  virtual void open(int deviceID); ///< open a device
137  bool poll(); ///< poll returns a bool (really quickly)
138  void nextEvent(); ///< step to next event or reset flag
139  void dumpMessage(); ///< print current msg
140  virtual void start(); ///< start MIDI stream
141  virtual void stop(); ///< stop MIDI stream
142  int evaluate(void * arg); ///< evaluate answers the message command
143 
144  /// implement inherited MidiInputCallback
145  void handleIncomingMidiMessage(MidiInput * source, const MidiMessage & message);
146 
147  MidiInput * mDevice; ///< my device ptr
148  double mStartTime; ///< the time I was started
149 };
150 
151 
152 ///
153 /// MIDIOut class write msgs out to a device (or file)
154 ///
155 
156 class MIDIOut : public MIDIIO {
157 public:
158  MIDIOut();
159  ~MIDIOut();
160 
161  MidiOutput * mOut; ///< the juce midi output is public
162 
163  virtual void open(int deviceID );
164  void write(CMIDIMessage & msg);
165  void writeNoteOn(unsigned channel, unsigned pitch, unsigned velocity ); ///< MIDINote#, [0, 127]
166  void writeNoteOn(unsigned channel, float frequency, float amplitude ); ///< [Hz], [0.0 1.0];
167  void writeNoteOff(unsigned channel, unsigned pitch, unsigned velocity ); ///< MIDINote#, [0, 127]
168  void writeNoteOff(unsigned channel, float frequency, float amplitude ); ///< [Hz], [0.0 1.0];
169  void writePolyTouch(unsigned channel, unsigned pitch, unsigned amount );
170  void writeControlChange(unsigned channel, unsigned function, unsigned value );
171  void writeProgramChange(unsigned channel, unsigned programNum );
172  void writeAftertouch(unsigned channel, unsigned amount ); ///< [0, 127]
173  void writePitchWheel(unsigned channel, unsigned amount ); ///< [0, 16384]
174  void writeSysEX(long when, unsigned char *msg );
175 
176 protected:
178  long mLatency;
179 
180 };
181 
182 
183 ///
184 /// MIDI stream/file player
185 ///
186 
187 class MIDIPlayer: public MIDIIO {
188 public:
189  MIDIPlayer(string nam, InstrumentLibrary * lib);
190  MIDIPlayer(string folder, string nam, InstrumentLibrary * lib);
192 
193  void open(int devID) { }; ///< open a device (empty method)
194  void start(int index); ///< play a track; merges tracks if index< 0
195  void stop(); ///< stop playing
196 
197  MidiFile mFile; ///< JUCE MIDI file
198  int mNumTrax; ///< num tracks
199  MidiMessageSequence * mTrak; ///< track ptr
200  bool mIsOn; ///< Active flag
201 
202  InstrumentLibrary * mLibrary; ///< instrument library
203  float mTempoScale; ///< tempo scale (secs/beat / ticks/beat)
204 
205 protected:
206  void init(String namS);
207  MidiMessageSequence * mergeTrax();
208 
209 };
210 
211 } // csl namespace
212 
213 #endif