17 channel(0), data1(0), data2(0), time(0) { }
52 juce::StringArray midiDevs = juce::MidiInput::getDevices();
53 return (
int) midiDevs.size();
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());
88 open(juce::MidiInput::getDefaultDeviceIndex());
123 #define CCOPY_MSG dest.channel = source.getChannel(); \
124 dest.data1 = source.getNoteNumber(); \
125 dest.data2 = source.getVelocity()
128 const unsigned char * data = (
unsigned char *) source.getRawData();
129 unsigned char cmd = (data[0] & 0xf0) >> 4;
133 if (source.getVelocity() > 0) {
147 dest.
channel = source.getChannel();
148 dest.
data1 = source.getControllerNumber();
149 dest.
data2 = source.getControllerValue();
172 logMsg(
kLogError,
"Unknown MIDI input: stat=%d chan=%d value1=%d value2=%d",
173 cmd, source.getChannel(), source.getNoteNumber(), source.getVelocity());
180 unsigned cmd, voice, pitch = 0, vel;
234 mStartTime = juce::Time::getMillisecondCounter() / 1000.0;
273 int t0 =
mBuffer.getFirstEventTime();
274 juce::MidiBuffer::Iterator it(
mBuffer);
275 it.getNextEvent(*
mJMsg, t0);
294 printf(
"kPolyTouch");
297 printf(
"ControlChange");
300 printf(
"kProgramChange");
303 printf(
"kAftertouch");
306 printf(
"kPitchWheel");
330 juce::MidiOutput::getDevices();
331 juce::StringArray midiDevs = juce::MidiInput::getDevices();
341 mOut = (juce::MidiOutput::openDevice(deviceID)).
get();
384 juce::File fil(namS);
385 mFile.readFrom(*(fil.createInputStream()));
387 mTrak = (juce::MidiMessageSequence *)
mFile.getTrack(0);
391 for (
int i = 0; i <
mNumTrax; i++) {
392 mTrak = (juce::MidiMessageSequence *)
mFile.getTrack(i);
393 logMsg(
" track %d : %d evts", i,
mTrak->getNumEvents());
395 int tix =
mFile.getTimeFormat();
396 juce::MidiMessageSequence tempi;
397 mFile.findAllTempoEvents(tempi);
398 if (tempi.getNumEvents() == 0) {
401 juce::MidiMessageSequence::MidiEventHolder * t1 = tempi.getEventPointer(0);
402 juce::MidiMessage msg = t1->message;
403 double sex = msg.getTempoSecondsPerQuarterNote();
411 juce::String namS(nam.c_str());
421 juce::String namS(abs.c_str());
432 mTrak = (juce::MidiMessageSequence *)
mFile.getTrack(index);
433 mTrak->deleteSysExMessages();
434 mTrak->updateMatchedPairs();
439 unsigned numEvts =
mTrak->getNumEvents();
442 float * pPtr = & pos;
443 logMsg(
"MIDIPlayer playing %d evts %5.2f sec.", numEvts, timX - tim0);
445 while (
mIsOn && (timN < timX)) {
448 juce::MidiMessageSequence::MidiEventHolder * evt
449 =
mTrak->getEventPointer(ind);
450 if ( ! evt)
continue;
451 juce::MidiMessage msg = evt->message;
456 float timD =
mTrak->getTimeOfMatchingKeyUp(ind);
467 logMsg(
"MIDIPlayer empty iv");
471 logMsg(
"MIDIPlayer empty in");
475 if (which == iv.size()) {
508 juce::MidiMessageSequence * tr =
new juce::MidiMessageSequence;
510 tr->addSequence(*
mFile.getTrack(i), 0, 0,
mFile.getLastTimestamp());
static void dumpDevices()
printing device info for all devices.
void logMsg(const char *format,...)
These are the public logging messages.
float mTempoScale
tempo scale (secs/beat / ticks/beat)
MIDIIO class: superclass of in and out; has a message buffer and current messages It's a model so you...
juce::MidiMessageSequence * mTrak
track ptr
virtual void clear()
stop MIDI stream
void open()
open the abstract
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
float getVelocityFloat()
has range of [0.0 1.0] mapped to [0 127] Data fields
void writeControlChange(unsigned channel, unsigned function, unsigned value)
void open()
method for opening the default stream.
long mBufferSize
fundamental members
juce::MidiMessage * mJMsg
JUCE-format message.
virtual void playMIDI(float dur, int chan, int key, int vel)
unsigned getProgramNumber()
juce::MidiInput * mDevice
my device ptr
void writeAftertouch(unsigned channel, unsigned amount)
[0, 127]
unsigned channel
0-indexed, so from 0 to 15
unsigned long Timestamp
Timestamp type: we assume that we can get the host's best guess at the IO word clock (normally passed...
double mStartTime
the time I was started
void writePolyTouch(unsigned channel, unsigned pitch, unsigned amount)
void writeNoteOff(unsigned channel, unsigned pitch, unsigned velocity)
MIDINote#, [0, 127].
bool mIsOpen
instance status indicators
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
float keyToFreq(unsigned midiKey)
MIDI Conversions.
int mDeviceID
device ID which will/is opened.
MIDIIO()
< It's a model & sends itself "changed"
void nextEvent()
step to next event or reset flag
int evaluate(void *arg)
evaluate answers the message command
virtual void stop()
stop MIDI stream
unsigned getCommand()
note accessors
unsigned getControlFunction()
void writeProgramChange(unsigned channel, unsigned programNum)
void dumpMessage()
print current msg
unsigned getControlValue()
void setBufferSize(unsigned bufferSize)
InstrumentLibrary * mLibrary
instrument library
bool isNoteOn()
bool flags for events
void handleIncomingMidiMessage(juce::MidiInput *source, const juce::MidiMessage &message)
implement inherited MidiInputCallback
static int countDevices()
bool isOpen()
true if MIDI stream is opened.
juce::AudioDeviceManager * gAudioDeviceManager
MIDIPlayer(string nam, InstrumentLibrary *lib)
void handleError(CException *err)
error handler
juce::MidiFile mFile
JUCE MIDI file.
void writeNoteOn(unsigned channel, unsigned pitch, unsigned velocity)
MIDINote#, [0, 127].
Instrument class (abstract)
juce::MidiMessageSequence * mergeTrax()
void writePitchWheel(unsigned channel, unsigned amount)
[0, 16384]
virtual bool isActive()
Envelope query and re-trigger.
std::vector< Instrument * > InstrumentVector
Players hold onto Instrument vectors/maps.
bool poll()
poll returns a bool (really quickly)
PmEvent mBuffer[1]
buffer which gets filled by read()
CMIDIMessage mMsg
current message (its flags determine the port state)
float time
timestamp in sec
CSL_MIDIMessageType message
virtual void setParameter(unsigned selector, int argc, void **argv, const char *types)
answer the number of accessors
void writeSysEX(long when, unsigned char *msg)
juce::MidiBuffer mBuffer
I/O buffer.
float fTimeNow()
system or IO time in seconds
CMIDIMessage class (mapped to juce::MidiMessage)
CMIDIMessageType message
event type
void copyMessage(CMIDIMessage &source, CMIDIMessage &dest)
copy csl::CMIDIMessage <–> juce::MidiMessage
juce::MidiOutput * mOut
the juce midi output is public
unsigned getPolyAftertouch()
virtual void close()
closing MIDI stream
static bool mIsInitialized
< static flags to keep track of driver state
float fRand1(void)
-1 - 1 (one)
virtual void start()
start MIDI stream
Timestamp timeNow()
high-accuracy system or IO time in ticks
std::map< int, InstrumentVector > InstrumentLibrary
void init(juce::String namS)
Base class of CSL exceptions (written upper-case). Has a string message.