33 uint8_t mStatus, mData1, mData2;
44 kChannelAftertouch = 13,
53 kBreathController = 2,
61 kExpressionController = 11,
66 kGeneralPurposeController1 = 16,
67 kGeneralPurposeController2 = 17,
68 kGeneralPurposeController3 = 18,
69 kGeneralPurposeController4 = 19,
83 kPortamentoOnOff = 65,
92 kCutoffFrequency = 74,
97 kSoundControllerUndefined = 79,
133 IMidiMsg(
int offset = 0, uint8_t status = 0, uint8_t data1 = 0, uint8_t data2 = 0)
145 void MakeNoteOnMsg(
int noteNumber,
int velocity,
int offset,
int channel = 0)
148 mStatus = channel | (kNoteOn << 4) ;
161 mStatus = channel | (kNoteOff << 4);
173 mStatus = channel | (kPitchWheel << 4);
174 int i = 8192 + (int) (value * 8192.0);
175 i = std::min(std::max(i, 0), 16383);
189 mStatus = channel | (kControlChange << 4);
191 mData2 = (int) (value * 127.0);
202 mStatus = channel | (kProgramChange << 4);
214 mStatus = channel | (kChannelAftertouch << 4);
228 mStatus = channel | (kPolyAftertouch << 4);
238 return mStatus & 0x0F;
245 unsigned int e = mStatus >> 4;
246 if (e < kNoteOff || e > kPitchWheel)
261 case kPolyAftertouch:
288 case kPolyAftertouch:
301 case kChannelAftertouch:
325 int iVal = (mData2 << 7) + mData1;
326 return static_cast<double>(iVal - 8192) / 8192.0;
344 return (
double) mData2 / 127.0;
354 return (msgValue >= 0.5);
361 mStatus = mData1 = mData2 = 0;
371 case kNone:
return "none";
372 case kNoteOff:
return "noteoff";
373 case kNoteOn:
return "noteon";
374 case kPolyAftertouch:
return "aftertouch";
375 case kControlChange:
return "controlchange";
376 case kProgramChange:
return "programchange";
377 case kChannelAftertouch:
return "channelaftertouch";
378 case kPitchWheel:
return "pitchwheel";
379 default:
return "unknown";
388 static const char* ccNameStrs[128] =
520 return ccNameStrs[idx];
541 const uint8_t* mData;
547 ISysEx(
int offset = 0,
const uint8_t* pData =
nullptr,
int size = 0)
566 char*
SysExStr(
char* str,
int maxLen,
const uint8_t* pData,
int size)
568 assert(str != NULL && maxLen >= 3);
570 if (!pData || !size) {
577 if (n > size) n = size;
578 for (
int i = 0; i < n; ++i, ++pData) {
579 snprintf(pStr, maxLen,
"%02X", (
int)*pData);
592 Trace(TRACELOC,
"sysex:(%d:%s)", mSize,
SysExStr(str,
sizeof(str), mData, mSize));
674#ifndef DEFAULT_BLOCK_SIZE
675 #define DEFAULT_BLOCK_SIZE 512
685 : mBuf(NULL), mSize(0), mGrow(Granulize(size)), mFront(0), mBack(0)
697 void Add(
const T& msg)
703 else if (!Expand())
return;
706#ifndef DONT_SORT_IMIDIQUEUE
708 if (mBack > mFront && msg.mOffset < mBuf[mBack - 1].mOffset)
711 while (i >= mFront && msg.mOffset < mBuf[i].mOffset) --i;
713 memmove(&mBuf[i + 1], &mBuf[i], (mBack - i) *
sizeof(T));
724 inline void Remove() { ++mFront; }
727 inline bool Empty()
const {
return mFront == mBack; }
730 inline int ToDo()
const {
return mBack - mFront; }
734 inline int GetSize()
const {
return mSize; }
738 inline T& Peek()
const {
return mBuf[mFront]; }
743 inline void Flush(
int nFrames)
746 if (mFront > 0) Compact();
749 for (
int i = 0; i < mBack; ++i) mBuf[i].mOffset -= nFrames;
753 inline void Clear() { mFront = mBack = 0; }
758 if (mFront > 0) Compact();
759 mGrow = size = Granulize(size);
761 if (size < mBack) size = Granulize(mBack);
762 if (size == mSize)
return mSize;
764 void* buf = realloc(mBuf, size *
sizeof(T));
765 if (!buf)
return mSize;
776 if (!mGrow)
return false;
777 int size = (mSize / mGrow + 1) * mGrow;
779 void* buf = realloc(mBuf, size *
sizeof(T));
780 if (!buf)
return false;
788 inline void Compact()
791 if (mBack > 0) memmove(&mBuf[0], &mBuf[mFront], mBack *
sizeof(T));
796 inline int Granulize(
int size)
const
798 int bytes = size *
sizeof(T);
799 int rest = bytes % 4096;
800 if (rest) size = (bytes - rest + 4096) /
sizeof(T);
IPlug logging a.k.a tracing functionality.
A class to help with queuing timestamped MIDI messages.
Encapsulates a MIDI message and provides helper functions.
void MakeNoteOnMsg(int noteNumber, int velocity, int offset, int channel=0)
Make a Note On message.
static const char * StatusMsgStr(EStatusMsg msg)
Get the Status Message as a CString.
double ControlChange(EControlChangeMsg idx) const
Get the value of a CC message.
int Channel() const
Gets the channel of a MIDI message.
IMidiMsg(int offset=0, uint8_t status=0, uint8_t data1=0, uint8_t data2=0)
Create an IMidiMsg, an abstraction for a MIDI message.
void MakeNoteOffMsg(int noteNumber, int offset, int channel=0)
Make a Note Off message.
void MakePitchWheelMsg(double value, int channel=0, int offset=0)
Create a pitch wheel/bend message.
int Velocity() const
Get the velocity value of a NoteOn/NoteOff message.
void LogMsg()
Log a message (TRACER BUILDS)
void MakeControlChangeMsg(EControlChangeMsg idx, double value, int channel=0, int offset=0)
Create a CC message.
int Program() const
Get the program index from a Program Change message.
EControlChangeMsg
Constants for MIDI CC messages.
static const char * CCNameStr(int idx)
Get the CC name as a CString.
void MakeProgramChange(int program, int channel=0, int offset=0)
Create a Program Change message.
void Clear()
Clear the message.
EStatusMsg
Constants for the status byte of a MIDI message.
void MakeChannelATMsg(int pressure, int offset, int channel)
Create a Channel AfterTouch message.
void MakePolyATMsg(int noteNumber, int pressure, int offset, int channel)
Create a Poly AfterTouch message.
int ChannelAfterTouch() const
Get the Pressure value from an AfterTouch message.
EControlChangeMsg ControlChangeIdx() const
Gets the controller index of a CC message.
int PolyAfterTouch() const
Get the Pressure value from a PolyAfterTouch message.
double PitchWheel() const
Get the value from a Pitchwheel message.
void PrintMsg() const
Print a message (DEBUG BUILDS)
int NoteNumber() const
Gets the MIDI note number.
static bool ControlChangeOnOff(double msgValue)
Helper to get a boolean value from a CC messages.
EStatusMsg StatusMsg() const
Gets the MIDI Status message.
A struct for dealing with SysEx messages.
ISysEx(int offset=0, const uint8_t *pData=nullptr, int size=0)
Create an ISysex.
void Clear()
Clear the data pointer and size (does not modify the external data!)
char * SysExStr(char *str, int maxLen, const uint8_t *pData, int size)
Get the bytes of a sysex message as a CString.
void LogMsg()
Log a message (TRACER BUILDS)