CSL  5.2
MIDIIOP.h
Go to the documentation of this file.
1 ///
2 /// MIDIIO.h -- MIDI IO using PortMIDI
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 
13 #include "math.h"
14 #include "portmidi.h"
15 #include "porttime.h"
16 
17 // copied from 240_test.c. need to sort out where it belongs.
18 
19 #define OUTPUT_BUFFER_SIZE 0
20 #define DRIVER_INFO NULL
21 #define TIME_PROC Pt_Time
22 #define TIME_INFO NULL
23 #define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
24 #define MIDI_THRU NULL
25 
26 // PmDeviceInfo data structure taken from portmidi.h
27 //
28 // typedef struct {
29 // int structVersion;
30 // const char *interf; /* underlying MIDI API, e.g. MMSystem or DirectX */
31 // const char *name; /* device name, e.g. USB MidiSport 1x1 */
32 // int input; /* true iff input is available */
33 // int output; /* true iff output is available */
34 // int opened; /* used by generic PortMidi code to do error checking on arguments */
35 // } PmDeviceInfo;
36 
37 // PmEvent data structure taken from portmidi.h
38 // typedef long PmMessage;
39 // typedef struct {
40 // PmMessage message;
41 // PmTimestamp timestamp;
42 // } PmEvent;
43 
44 namespace csl {
45 
46 /// CSL_MIDIMessageType
47 
48 typedef enum {
49  kNone = 0,
50  kNoteOff = 8,
51  kNoteOn = 9,
52  kPolyTouch = 10,
53  kControlChange = 11,
54  kProgramChange = 12,
55  kAftertouch = 13,
56  kPitchWheel = 14,
57  kSysEX = 15
59 
60 /// CSL_MIDIMessage
61 
63 
64 public:
66  unsigned channel; // 0-indexed, so from 0 to 15
67  unsigned data1;
68  unsigned data2;
69  long time;
70 
72 // CSL_MIDIMessage(CSL_MIDIMessageType, ch, d1, d2 );
73 };
74 
75 /// copy_CSL_MIDIMessage -- copies CSL_MIDIMessage
76 
78 
79 /// CSL_MIDIMessageToPmEvent -- converts CSL_MIDIMessage to PmEvent
80 
81 void CSL_MIDIMessageToPmEvent(CSL_MIDIMessage* cslMIDI, PmEvent* event );
82 
83 /// PmEventToCSL_MIDIMessage -- converts PmEvent to CSL_MIDIMessage
84 
85 void PmEventToCSL_MIDIMessage( PmEvent* event, CSL_MIDIMessage* cslMIDI );
86 
87 /// Message_ChannelToStatus -- converts from message and channel to status byte
88 
89 unsigned Message_ChannelToStatus(CSL_MIDIMessageType message, unsigned channel );
90 
91 ///
92 /// MIDIIO class
93 ///
94 
95 class MIDIIO {
96 public:
97  MIDIIO();
98  virtual ~MIDIIO();
99 
100  virtual void open() { }; ///< can't open the abstract class
101  bool is_open(); ///< true if MIDI stream is opened.
102  void close(); ///< closing MIDI stream
103  void dump_device_info(); ///< printing device info for all devices.
104  void dump_count_devices(); ///< printing total number of devices available
105 
106  ///< thin wrapper for PortMidi functions. made available for flexibility.
107  int count_devices();
108  int get_default_input_id();
109  int get_default_output_id();
110  const PmDeviceInfo* get_device_info(int deviceID );
111 
112 protected:
113  PmStream * mMIDIStream; ///< opened stream
114  PmDeviceID mDeviceID; ///< device ID which will/is opened.
115 
116  ///< static to keep track of Pm_Initialize() / Pm_Terminate()
117  static bool mIsInitialized;
118  static unsigned mNumInstantiated;
119  static bool mIsPortTimeStarted;
120 
121  ///< status indicators
122  bool mIsInput;
123  bool mIsOutput;
124  bool mIsOpen;
125 
126  void handle_error(PmError err);
127 };
128 
129 ///
130 /// MIDIIn class
131 ///
132 
133 class MIDIIn : public MIDIIO {
134 public:
135  MIDIIn();
136 
137  unsigned buffer_size();
138  void set_buffer_size(unsigned bufferSize );
139  void open(); ///< method for opening the default stream.
140  void open(int deviceID);
141  bool poll();
142  void read(); ///< generic read method. gets MIDI message and store it in mBuffer
143  void read_interpret(); ///< read method and sets internal flag for which message was received
144 
145  PmEvent buffer() { return mBuffer[0]; }
146  void dump_buffer();
147 
149  void dump_CSL_MIDIMessage();
150 
151  bool is_NoteOn_received();
152  bool is_NoteOff_received();
153  bool is_PolyTouch_received();
156  bool is_Aftertouch_received();
157  bool is_PitchWheel_received();
158  bool is_SysEX_received();
159 
160  unsigned get_note();
161  unsigned get_velocity();
162  unsigned get_PolyAftertouch();
163  unsigned get_ControlChange_function();
164  unsigned get_ControlChange_value();
165  unsigned get_ProgramNumber();
166  unsigned get_Aftertouch();
167  unsigned get_PitchWheel();
168  float get_frequency();
169  float get_velocity_float(); ///< has range of [0.0 1.0] mapped to [0 127]
170 
171  void setFilter();
172  void filter_active_sensing(bool flag );
173  void filter_sysex(bool flag );
174  void filter_clock_msg(bool flag );
175 
176 
177 protected:
178  /// fundamental members
181 
183 
184  PmEvent mBuffer[1]; ///< buffer which gets filled by read()
185  PmError mLength; ///< length
186 
187 };
188 
189 ///
190 /// MIDIOut class
191 ///
192 
193 class MIDIOut : public MIDIIO {
194 public:
195  MIDIOut();
196  ~MIDIOut();
197 
198  unsigned buffer_size();
199  void set_buffer_size(unsigned bufferSize ); // TODO: should not be called after opening.
200  long latency();
201  void set_latency(long latency ); // TODO: should not be called after opening.
202 
203  void open();
204  void open(int deviceID );
205  void set_message(CSL_MIDIMessage msg, long when );
206  void write();
207  void write(CSL_MIDIMessage* msg, long length ); ///< thin wrapper for Pm_Write
208  void write_short(CSL_MIDIMessage msg );
209  void write_SysEX(long when, unsigned char *msg );
210 
211  /// convenience method for each MIDI messages
212  /// writes directly and doesn't use member mMsg for temporal storage.
213  void write_NoteOn(unsigned channel, unsigned pitch, unsigned velocity ); ///< MIDINote#, [0, 127]
214  void write_NoteOn(unsigned channel, float frequency, float amplitude ); ///< [Hz], [0.0 1.0];
215  void write_NoteOff(unsigned channel, unsigned pitch, unsigned velocity ); ///< MIDINote#, [0, 127]
216  void write_NoteOff(unsigned channel, float frequency, float amplitude ); ///< [Hz], [0.0 1.0];
217  void write_PolyTouch(unsigned channel, unsigned pitch, unsigned amount );
218  void write_ControlChange(unsigned channel, unsigned function, unsigned value );
219  void write_ProgramChange(unsigned channel, unsigned programNum );
220  void write_Aftertouch(unsigned channel, unsigned amount ); ///< [0, 127]
221  void write_PitchWheel(unsigned channel, unsigned amount ); ///< [0, 16384]
222 
223 protected:
224  long mBufferSize;
225  long mLatency;
226 
228 };
229 
230 } // csl namespace
231 
232 #endif