CSL  6.0
MIDIIOJ.cpp
Go to the documentation of this file.
1 //
2 // MIDIIOJ.cpp -- MIDI IO using JUCE
3 //
4 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
5 //
6 
7 #include "MIDIIOJ.h"
8 
9 extern juce::AudioDeviceManager * gAudioDeviceManager; // global JUCE audio device mgr
10 
11 using namespace csl;
12 
13 // CSL_MIDIMessage
14 
16  : message(kNone), // init to no event
17  channel(0), data1(0), data2(0), time(0) { }
18 
19 bool CMIDIMessage::isNoteOn() { return (command == kNoteOn); }
20 bool CMIDIMessage::isNoteOff() { return (command == kNoteOff); }
21 bool CMIDIMessage::isNoteOnOff() { return ((command == kNoteOff) || (command == kNoteOn)); }
22 
28 bool CMIDIMessage::isSysEX() { return (command == kSysEX); }
29 
30 unsigned CMIDIMessage::getCommand() { return (unsigned) command; }
31 unsigned CMIDIMessage::getNote() { return (unsigned) data1; }
32 unsigned CMIDIMessage::getVelocity() { return (unsigned) data2; }
33 unsigned CMIDIMessage::getPolyAftertouch() { return (unsigned) data2; }
34 unsigned CMIDIMessage::getControlFunction() { return (unsigned) data1; }
35 unsigned CMIDIMessage::getControlValue() { return (unsigned) data2; }
36 unsigned CMIDIMessage::getProgramNumber() { return (unsigned) data1; }
37 unsigned CMIDIMessage::getAftertouch() { return (unsigned) data1; }
38 unsigned CMIDIMessage::getPitchWheel() { return ((unsigned) (data2 << 7) + (unsigned) data1 ); }
40 float CMIDIMessage::getVelocityFloat() { return ((float) data2 / 127.0f); }
41 
42 
43 // MIDIIO
44 
45 // static var. definition
46 
47 bool MIDIIO::mIsInitialized = false;
48 
49 // Made available for flexibility
50 
52  juce::StringArray midiDevs = juce::MidiInput::getDevices();
53  return (int) midiDevs.size();
54 }
55 
56 // Made available for flexibility
57 
59  juce::StringArray midiDevs = juce::MidiInput::getDevices();
60  unsigned len = midiDevs.size();
61  logMsg("\n\tMIDI in devices");
62  for (unsigned i = 0; i < len; i++)
63  logMsg(" %d = %s", i, midiDevs[i].toUTF8());
64  logMsg(" Def: %d", juce::MidiInput::getDefaultDeviceIndex());
65  midiDevs = juce::MidiOutput::getDevices();
66  len = midiDevs.size();
67  logMsg("\n\tMIDI out devices");
68  for (unsigned i = 0; i < len; i++)
69  logMsg(" %d = %s", i, midiDevs[i].toUTF8());
70  logMsg(" Def: %d", juce::MidiOutput::getDefaultDeviceIndex());
71 }
72 
73 // Constructors
74 
76  if( ! mIsInitialized ) {
77  mIsInitialized = true;
78  }
79  mIsOpen = false;
80  mMsg.message = kNone;
81 }
82 
84  mIsInitialized = false;
85 }
86 
87 void MIDIIO::open() {
88  open(juce::MidiInput::getDefaultDeviceIndex());
89 }
90 
92  return mIsOpen;
93 }
94 
95 void MIDIIO::close() {
96  mIsOpen = false;
97  this->clear();
98 }
99 
100 // clear MIDI stream
101 
103  mMsg.message = kNone;
104  mBuffer.clear();
105 }
106 
107 // copy_MIDIMessage -- copies csl::CMIDIMessage <--> juce::MidiMessage
108 
110  dest.message = source.message;
111  dest.command = source.command;
112  dest.channel = source.channel;
113  dest.data1 = source.data1;
114  dest.data2 = source.data2;
115  dest.time = source.time;
116 }
117 
118 void MIDIIO::copyMessage(CMIDIMessage& source, juce::MidiMessage* dest) {
119  dest = new juce::MidiMessage((source.command | source.channel),
120  source.data1, source.data2, source.time);
121 }
122 
123 #define CCOPY_MSG dest.channel = source.getChannel(); \
124  dest.data1 = source.getNoteNumber(); \
125  dest.data2 = source.getVelocity()
126 
127 void MIDIIO::copyMessage(const juce::MidiMessage& source, CMIDIMessage& dest) {
128  const unsigned char * data = (unsigned char *) source.getRawData();
129  unsigned char cmd = (data[0] & 0xf0) >> 4;
130  dest.command = cmd;
131  switch(cmd) {
132  case kNoteOn:
133  if (source.getVelocity() > 0) {
134  dest.message = kNoteOn;
135  CCOPY_MSG;
136  break;
137  }
138  case kNoteOff:
139  dest.message = kNoteOff;
140  CCOPY_MSG;
141  break;
142  case kPolyTouch:
143  dest.message = kPolyTouch;
144  CCOPY_MSG;
145  case kControlChange:
146  dest.message = kControlChange;
147  dest.channel = source.getChannel();
148  dest.data1 = source.getControllerNumber();
149  dest.data2 = source.getControllerValue();
150  break;
151  case kProgramChange:
152  dest.message = kProgramChange;
153  CCOPY_MSG;
154  mMsg.data2 = 0;
155  break;
156  case kAftertouch:
157  dest.message = kAftertouch;
158  CCOPY_MSG;
159  break;
160  case kPitchWheel:
161  dest.message = kPitchWheel;
162  CCOPY_MSG;
163  dest.data2 = 0;
164  break;
165  case kSysEX:
166  dest.message = kSysEX;
167  dest.channel = 0;
168  dest.data1 = 0;
169  dest.data2 = 0;
170  break;
171  default:
172  logMsg(kLogError, "Unknown MIDI input: stat=%d chan=%d value1=%d value2=%d",
173  cmd, source.getChannel(), source.getNoteNumber(), source.getVelocity());
174  break;
175  }
176  dest.time = (Timestamp) source.getTimeStamp();
177 }
178 
180  unsigned cmd, voice, pitch = 0, vel;
181 // PmMessage msg;
182 // msg = mBuffer[0].message;
183 // cmd = Pm_MessageStatus(msg) & 0xF0;
184 // voice = Pm_MessageStatus(msg) & 0x0F;
185 // pitch = Pm_MessageData1(msg);
186 // vel = Pm_MessageData2(msg);
187 // printf("\tGot message: time %.3f, cmd: %x midich: %d data1: %d data2: %d\n",
188 // (float) mBuffer[0].timestamp / 1000.0f, cmd, voice, pitch, vel);
189 
190 }
191 
192 // MIDIIO error handler
193 
195 // Pm_Terminate();
196  logMsg(kLogError, "An error occured in MIDIIO: %s", err->what());
197 }
198 
199 
200 // MIDIIn
201 
203  mFilterFlag = 0;
204  mDeviceID = 0;
205  mDevice = 0;
206  mBufferSize = 100;
207 }
208 
209 unsigned MIDIIn::bufferSize() {
210  return mBufferSize;
211 }
212 
213 void MIDIIn::setBufferSize(unsigned bufferSize) {
215 }
216 
217 // open and register me as the MidiInputCallback
218 void MIDIIn::open(int deviceID) {
219  mDeviceID = deviceID;
220  mDevice = (juce::MidiInput::openDevice(mDeviceID, this)).get();
221  if ( ! mDevice) {
222  logMsg(kLogError, "Cannot open midi in %d", mDeviceID);
223  return;
224  }
225  logMsg("Open midi input %s", mDevice->getName().toUTF8());
227  gAudioDeviceManager->setMidiInputEnabled(mDevice->getName(), true);
228  mIsOpen = true;
229 }
230 
231 ///< start MIDI stream
232 
234  mStartTime = juce::Time::getMillisecondCounter() / 1000.0;
235  if (mDevice)
236  mDevice->start();
237 }
238 
239 ///< stop MIDI stream
240 
241 void MIDIIn::stop() {
242  if (mDevice)
243  mDevice->stop();
244 }
245 
246 /// implement inherited MidiInputCallback
247 
248 void MIDIIn::handleIncomingMidiMessage(juce::MidiInput * source, const juce::MidiMessage & message) {
249  if (mMsg.message == kNone) {
250  copyMessage(message, mMsg); // copy the message
251  mMsg.time = message.getTimeStamp() - mStartTime;
252  this->changed((void *) &mMsg); // FLAG CHANGE TO OBSERVERS
253  } else { // paste msg to buffer
254  mBuffer.addEvent(message, timeNow());
255  copyMessage(message, mMsg2); // copy the message
256  mMsg2.time = message.getTimeStamp() - mStartTime;
257  this->changed((void *) &mMsg2); // FLAG CHANGE TO OBSERVERS
258  }
259 }
260 
261 // quick poll
262 
263 bool MIDIIn::poll() {
264  return (mMsg.message != kNone);
265 }
266 
267 // step to next event or reset flag
268 
270  if (mBuffer.isEmpty()) { // if empty, clear
271  mMsg.message = kNone;
272  } else { //else take first even from Q
273  int t0 = mBuffer.getFirstEventTime();
274  juce::MidiBuffer::Iterator it(mBuffer);
275  it.getNextEvent(*mJMsg, t0);
276  copyMessage(*mJMsg, mMsg); // copy the message
277  mBuffer.clear(t0, 1); // remove it from the buffer
278  }
279 }
280 
282  printf("\tMIDIIn ");
283  switch(mMsg.message) {
284  case kNone:
285  printf("kNone");
286  break;
287  case kNoteOff:
288  printf("kNoteOff");
289  break;
290  case kNoteOn:
291  printf("kNoteOn");
292  break;
293  case kPolyTouch:
294  printf("kPolyTouch");
295  break;
296  case kControlChange:
297  printf("ControlChange");
298  break;
299  case kProgramChange:
300  printf("kProgramChange");
301  break;
302  case kAftertouch:
303  printf("kAftertouch");
304  break;
305  case kPitchWheel:
306  printf("kPitchWheel");
307  break;
308  case kSysEX:
309  printf("kSysEX");
310  break;
311  default:
312  printf("unknown");
313  }
314  printf(" \tch: %2d d1: %2d d2: %2d t: %5.3f\n", mMsg.channel, mMsg.data1, mMsg.data2, mMsg.time);
315 }
316 
317 // evaluate answers the midi command
318 
319 int MIDIIn::evaluate(void * arg) {
320  CMIDIMessage * msg = (CMIDIMessage *) arg;
321  return msg->message;
322 }
323 
324 // MIDIOut
325 
326 MIDIOut::MIDIOut() : MIDIIO(), mOut(0) {
327  mDeviceID = 0; // Pm_GetDefaultOutputDeviceID();
328  mBufferSize = 0;
329  mLatency = 0; // do I need to set this to > 0 value for synchronization?
330  juce::MidiOutput::getDevices();
331  juce::StringArray midiDevs = juce::MidiInput::getDevices();
332 
333  * mOut;
334 }
335 
337 }
338 
339 void MIDIOut::open(int deviceID) {
340  mDeviceID = deviceID;
341  mOut = (juce::MidiOutput::openDevice(deviceID)).get();
342 }
343 
345  copyMessage(msg, mJMsg);
346  mOut->sendMessageNow (*mJMsg);
347  delete mJMsg;
348 }
349 
350 void MIDIOut::writeSysEX(long when, unsigned char *msg ) {
351 }
352 
353 void MIDIOut::writeNoteOn(unsigned channel, unsigned pitch, unsigned velocity ) {
354 }
355 
356 void MIDIOut::writeNoteOn(unsigned channel, float frequency, float amplitude ) {
357 }
358 
359 void MIDIOut::writeNoteOff(unsigned channel, unsigned pitch, unsigned velocity ) {
360 }
361 
362 void MIDIOut::writeNoteOff(unsigned channel, float frequency, float amplitude ) {
363 }
364 
365 void MIDIOut::writePolyTouch(unsigned channel, unsigned pitch, unsigned amount ) {
366 }
367 
368 void MIDIOut::writeControlChange(unsigned channel, unsigned function, unsigned value ) {
369 }
370 
371 void MIDIOut::writeProgramChange(unsigned channel, unsigned programNum ) {
372 }
373 
374 void MIDIOut::writeAftertouch(unsigned channel, unsigned amount ) {
375 }
376 
377 void MIDIOut::writePitchWheel(unsigned channel, unsigned amount ) {
378 }
379 
380 
381 // init a Midi player from a file name
382 
383 void MIDIPlayer::init(juce::String namS) {
384  juce::File fil(namS);
385  mFile.readFrom(*(fil.createInputStream()));
386  mNumTrax = mFile.getNumTracks();
387  mTrak = (juce::MidiMessageSequence *) mFile.getTrack(0);
388  mIsOn = false;
389  logMsg("MIDIPlayer %d trax", mNumTrax);
390  // dump all track events
391  for (int i = 0; i < mNumTrax; i++) {
392  mTrak = (juce::MidiMessageSequence *) mFile.getTrack(i);
393  logMsg(" track %d : %d evts", i, mTrak->getNumEvents());
394  }
395  int tix = mFile.getTimeFormat();
396  juce::MidiMessageSequence tempi;
397  mFile.findAllTempoEvents(tempi);
398  if (tempi.getNumEvents() == 0) {
399  mTempoScale = 120.0f;
400  } else {
401  juce::MidiMessageSequence::MidiEventHolder * t1 = tempi.getEventPointer(0);
402  juce::MidiMessage msg = t1->message; // and its event
403  double sex = msg.getTempoSecondsPerQuarterNote();
404  mTempoScale = sex / tix;
405  }
406 }
407 
408 // MIDIPlayer constructor loads MIDI file
409 
411  juce::String namS(nam.c_str());
412  init(namS);
413  mLibrary = lib;
414 }
415 
416 // MIDIPlayer constructor loads MIDI file
417 
418 MIDIPlayer::MIDIPlayer(string folder, string nam, InstrumentLibrary * lib) {
419  string abs(folder);
420  abs += nam;
421  juce::String namS(abs.c_str());
422  init(namS);
423  mLibrary = lib;
424 }
425 
426 // start method reads tracks
427 
428 void MIDIPlayer::start(int index) {
429  if (index < 0)
430  mTrak = this->mergeTrax();
431  else
432  mTrak = (juce::MidiMessageSequence *) mFile.getTrack(index); // get track
433  mTrak->deleteSysExMessages(); // clean up
434  mTrak->updateMatchedPairs(); // match note-on-off
435  float tim0 = (float) mTrak->getStartTime() * mTempoScale; // time 0
436  float timX = (float) mTrak->getEndTime() * mTempoScale; // time x
437  float timN = tim0; // time now
438  float startT = fTimeNow();
439  unsigned numEvts = mTrak->getNumEvents(); // # notes
440  mIsOn = true;
441  float pos; // stereo position
442  float * pPtr = & pos;
443  logMsg("MIDIPlayer playing %d evts %5.2f sec.", numEvts, timX - tim0);
444 
445  while (mIsOn && (timN < timX)) { // schedule loop
446  int ind = mTrak->getNextIndexAtTime((double) (timN / mTempoScale)); // get ind of next event
447  float timE = mTrak->getEventTime(ind) * mTempoScale; // time of event
448  juce::MidiMessageSequence::MidiEventHolder * evt // get the event holder
449  = mTrak->getEventPointer(ind);
450  if ( ! evt) continue;
451  juce::MidiMessage msg = evt->message; // and its event
452  copyMessage(msg, mMsg); // make a CMIDIMessage
453  sleepSec(timE - timN); // sleep till then
454 
455  if (mMsg.isNoteOn()) { // handle note-on events
456  float timD = mTrak->getTimeOfMatchingKeyUp(ind);
457  if (timD != 0)
458  timD = (timD * mTempoScale) - timE; // get note duration
459  else {
460 // logMsg(" NoteOff %d not found", ind);
461  timD = timX - timE;
462  }
463  if (mLibrary) { // get the instrument to play on
464  int which = 0;
465  InstrumentVector iv = (* mLibrary)[mMsg.channel];
466  if (iv.empty()) {
467  logMsg("MIDIPlayer empty iv");
468  }
469  Instrument * inst = iv[which]; // get the vector for this channel
470  if ( ! inst) {
471  logMsg("MIDIPlayer empty in");
472  }
473  while (inst->isActive()) { // if we're already playing
474  which++;
475  if (which == iv.size()) { // look for a free instrument
476 // iv.push_back(new Instrument(*inst));
477  logMsg("MIDIPlayer out of voices in instr %d", mMsg.channel);
478  goto next; // goto next note instead of voice-stealing
479  }
480  inst = iv[which];
481  }
482  pos = fRand1(); // pick a random position
483  inst->setParameter(set_position_f, 1, (void **) &pPtr, "f");
484  // play the MIDI note
485 // logMsg("NoteOn %5.2f - %5.2f \t%2d.%2d %2d %2d",
486 // timE, timD, mMsg.command, mMsg.channel, mMsg.data1, mMsg.data2);
487  inst->playMIDI(timD, mMsg.channel, mMsg.data1, mMsg.data2);
488  }
489 // } else if ( ! mMsg.isNoteOff()) {
490 // logMsg("Msg %5.2f %d - %d %d %d", timV * mTempoScale,
491 // mMsg.message, mMsg.channel, mMsg.data1, mMsg.data2);
492  }
493 next:
494  mTrak->deleteEvent(ind, mMsg.isNoteOn()); // delete event from list
495  timN = timE; // update clock
496  }
497 }
498 
499 // set stop flag
500 
502  mIsOn = false;
503 }
504 
505 // merge all the file's tracks into 1
506 
507 juce::MidiMessageSequence * MIDIPlayer::mergeTrax() {
508  juce::MidiMessageSequence * tr = new juce::MidiMessageSequence;
509  for (int i = 0; i < mNumTrax; i++)
510  tr->addSequence(*mFile.getTrack(i), 0, 0, mFile.getLastTimestamp());
511  return tr;
512 }
static void dumpDevices()
printing device info for all devices.
Definition: MIDIIOJ.cpp:58
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
float mTempoScale
tempo scale (secs/beat / ticks/beat)
Definition: MIDIIOJ.h:203
MIDIIO class: superclass of in and out; has a message buffer and current messages It's a model so you...
Definition: MIDIIOJ.h:86
unsigned getAftertouch()
Definition: MIDIIOJ.cpp:37
bool isAftertouch()
Definition: MIDIIOJ.cpp:26
juce::MidiMessageSequence * mTrak
track ptr
Definition: MIDIIOJ.h:199
void write()
Definition: MIDIIOP.cpp:534
virtual void clear()
stop MIDI stream
Definition: MIDIIOJ.cpp:102
unsigned getVelocity()
Definition: MIDIIOJ.cpp:32
void open()
open the abstract
Definition: MIDIIOJ.cpp:87
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
float getVelocityFloat()
has range of [0.0 1.0] mapped to [0 127] Data fields
Definition: MIDIIOJ.cpp:40
void writeControlChange(unsigned channel, unsigned function, unsigned value)
Definition: MIDIIOJ.cpp:368
float getFrequency()
Definition: MIDIIOJ.cpp:39
void open()
method for opening the default stream.
Definition: MIDIIOP.cpp:182
unsigned data1
Definition: MIDIIOP.h:67
long mBufferSize
fundamental members
Definition: MIDIIOP.h:179
juce::MidiMessage * mJMsg
JUCE-format message.
Definition: MIDIIOJ.h:111
virtual void playMIDI(float dur, int chan, int key, int vel)
Definition: Instrument.h:83
unsigned getProgramNumber()
Definition: MIDIIOJ.cpp:36
juce::MidiInput * mDevice
my device ptr
Definition: MIDIIOJ.h:147
void writeAftertouch(unsigned channel, unsigned amount)
[0, 127]
Definition: MIDIIOJ.cpp:374
unsigned channel
Definition: MIDIIOP.h:66
long mBufferSize
Definition: MIDIIOJ.h:177
unsigned channel
0-indexed, so from 0 to 15
Definition: MIDIIOJ.h:75
unsigned long Timestamp
Timestamp type: we assume that we can get the host's best guess at the IO word clock (normally passed...
Definition: CSL_Types.h:261
double mStartTime
the time I was started
Definition: MIDIIOJ.h:148
unsigned getPitchWheel()
Definition: MIDIIOJ.cpp:38
void writePolyTouch(unsigned channel, unsigned pitch, unsigned amount)
Definition: MIDIIOJ.cpp:365
void writeNoteOff(unsigned channel, unsigned pitch, unsigned velocity)
MIDINote#, [0, 127].
Definition: MIDIIOJ.cpp:359
bool mIsOpen
instance status indicators
Definition: MIDIIOJ.h:113
void changed(void *argument)
this is what I send to myself to notify my observers; It's not overridden in general. It results in the observers receiving update() calls < override evaluate to filter updates to the observer map
Definition: CGestalt.cpp:540
unsigned data2
Definition: MIDIIOJ.h:77
float keyToFreq(unsigned midiKey)
MIDI Conversions.
Definition: CGestalt.cpp:483
void open()
Definition: MIDIIOP.cpp:507
int mDeviceID
device ID which will/is opened.
Definition: MIDIIOJ.h:103
MIDIIO()
< It's a model & sends itself "changed"
Definition: MIDIIOJ.cpp:75
void nextEvent()
step to next event or reset flag
Definition: MIDIIOJ.cpp:269
int evaluate(void *arg)
evaluate answers the message command
Definition: MIDIIOJ.cpp:319
CSL_MIDIMessage mMsg
Definition: MIDIIOP.h:182
virtual void stop()
stop MIDI stream
Definition: MIDIIOJ.cpp:241
unsigned getCommand()
note accessors
Definition: MIDIIOJ.cpp:30
unsigned data1
Definition: MIDIIOJ.h:76
unsigned getControlFunction()
Definition: MIDIIOJ.cpp:34
const char * what()
void dumpBuffer()
Definition: MIDIIOJ.cpp:179
void writeProgramChange(unsigned channel, unsigned programNum)
Definition: MIDIIOJ.cpp:371
void dumpMessage()
print current msg
Definition: MIDIIOJ.cpp:281
unsigned getControlValue()
Definition: MIDIIOJ.cpp:35
bool isPitchWheel()
Definition: MIDIIOJ.cpp:27
int mNumTrax
num tracks
Definition: MIDIIOJ.h:198
void setBufferSize(unsigned bufferSize)
Definition: MIDIIOJ.cpp:213
InstrumentLibrary * mLibrary
instrument library
Definition: MIDIIOJ.h:202
bool isNoteOn()
bool flags for events
Definition: MIDIIOJ.cpp:19
void handleIncomingMidiMessage(juce::MidiInput *source, const juce::MidiMessage &message)
implement inherited MidiInputCallback
Definition: MIDIIOJ.cpp:248
virtual ~MIDIIO()
Definition: MIDIIOJ.cpp:83
static int countDevices()
Definition: MIDIIOJ.cpp:51
bool isOpen()
true if MIDI stream is opened.
Definition: MIDIIOJ.cpp:91
juce::AudioDeviceManager * gAudioDeviceManager
MIDIPlayer(string nam, InstrumentLibrary *lib)
Definition: MIDIIOJ.cpp:410
virtual void start()
Definition: MIDIIOJ.h:98
void handleError(CException *err)
error handler
Definition: MIDIIOJ.cpp:194
juce::MidiFile mFile
JUCE MIDI file.
Definition: MIDIIOJ.h:197
unsigned command
Definition: MIDIIOJ.h:74
long mFilterFlag
Definition: MIDIIOP.h:180
void writeNoteOn(unsigned channel, unsigned pitch, unsigned velocity)
MIDINote#, [0, 127].
Definition: MIDIIOJ.cpp:353
Instrument class (abstract)
Definition: Instrument.h:56
bool isProgramChange()
Definition: MIDIIOJ.cpp:25
juce::MidiMessageSequence * mergeTrax()
Definition: MIDIIOJ.cpp:507
bool sleepSec(float dur)
Definition: CGestalt.cpp:379
static unsigned len
Definition: fft_N.c:39
void writePitchWheel(unsigned channel, unsigned amount)
[0, 16384]
Definition: MIDIIOJ.cpp:377
virtual bool isActive()
Envelope query and re-trigger.
Definition: Instrument.cpp:57
bool isNoteOnOff()
Definition: MIDIIOJ.cpp:21
std::vector< Instrument * > InstrumentVector
Players hold onto Instrument vectors/maps.
Definition: CSL_Types.h:251
bool poll()
poll returns a bool (really quickly)
Definition: MIDIIOJ.cpp:263
PmEvent mBuffer[1]
buffer which gets filled by read()
Definition: MIDIIOP.h:184
CMIDIMessage mMsg
current message (its flags determine the port state)
Definition: MIDIIOJ.h:104
float time
timestamp in sec
Definition: MIDIIOJ.h:78
CSL_MIDIMessageType message
Definition: MIDIIOP.h:65
#define CCOPY_MSG
Definition: MIDIIOJ.cpp:123
virtual void setParameter(unsigned selector, int argc, void **argv, const char *types)
answer the number of accessors
Definition: Instrument.h:74
void writeSysEX(long when, unsigned char *msg)
Definition: MIDIIOJ.cpp:350
unsigned getNote()
Definition: MIDIIOJ.cpp:31
juce::MidiBuffer mBuffer
I/O buffer.
Definition: MIDIIOJ.h:106
float fTimeNow()
system or IO time in seconds
Definition: CGestalt.cpp:398
bool isNoteOff()
Definition: MIDIIOJ.cpp:20
CMIDIMessage class (mapped to juce::MidiMessage)
Definition: MIDIIOJ.h:46
CMIDIMessageType message
event type
Definition: MIDIIOJ.h:73
long mLatency
Definition: MIDIIOJ.h:178
void copyMessage(CMIDIMessage &source, CMIDIMessage &dest)
copy csl::CMIDIMessage <–> juce::MidiMessage
Definition: MIDIIOJ.cpp:109
juce::MidiOutput * mOut
the juce midi output is public
Definition: MIDIIOJ.h:161
unsigned getPolyAftertouch()
Definition: MIDIIOJ.cpp:33
virtual void close()
closing MIDI stream
Definition: MIDIIOJ.cpp:95
#define set_position_f
Definition: Instrument.h:22
static bool mIsInitialized
< static flags to keep track of driver state
Definition: MIDIIOJ.h:109
float fRand1(void)
-1 - 1 (one)
Definition: CGestalt.cpp:420
virtual void start()
start MIDI stream
Definition: MIDIIOJ.cpp:233
bool isPolyTouch()
Definition: MIDIIOJ.cpp:23
bool mIsOn
Active flag.
Definition: MIDIIOJ.h:200
Timestamp timeNow()
high-accuracy system or IO time in ticks
Definition: CGestalt.cpp:386
std::map< int, InstrumentVector > InstrumentLibrary
Definition: CSL_Types.h:252
void init(juce::String namS)
Definition: MIDIIOJ.cpp:383
CMIDIMessage mMsg2
Definition: MIDIIOJ.h:105
void stop()
stop playing
Definition: MIDIIOJ.cpp:501
unsigned bufferSize()
Definition: MIDIIOJ.cpp:209
unsigned data2
Definition: MIDIIOP.h:68
bool isControlChange()
Definition: MIDIIOJ.cpp:24
Base class of CSL exceptions (written upper-case). Has a string message.