5 #ifdef XENOMAI_SKIN_native
6 #include <native/pipe.h>
9 typedef unsigned char midi_byte_t;
11 typedef enum midiMessageType{
14 kmmPolyphonicKeyPressure,
23 #define midiMessageStatusBytesLength 8+2 //2 being kmmNone and kmmAny
25 extern midi_byte_t midiMessageStatusBytes[midiMessageStatusBytesLength];
26 extern unsigned int midiMessageNumDataBytes[midiMessageStatusBytesLength];
32 midi_byte_t getStatusByte()
const {
36 MidiMessageType getType()
const;
37 int getChannel()
const;
38 const char* getTypeText()
const {
39 return getTypeText(getType());
41 static const char* getTypeText(MidiMessageType type){
47 case kmmPolyphonicKeyPressure:
48 return "polyphonic aftertouch";
49 case kmmControlChange:
50 return "control change";
51 case kmmProgramChange:
52 return "program change";
53 case kmmChannelPressure:
54 return "channel aftertouch";
67 unsigned int getNumDataBytes()
const {
68 return midiMessageNumDataBytes[(
unsigned int)_type];
70 void setDataByte(
unsigned int dataByteIndex, midi_byte_t input){
71 _dataBytes[dataByteIndex] = input;
73 void setType(MidiMessageType type){
75 _statusByte = midiMessageStatusBytes[_type];
77 void setChannel(midi_byte_t channel){
80 midi_byte_t getDataByte(
unsigned int index)
const {
81 return _dataBytes[index];
84 for(
int n = 0; n<maxDataBytes; n++){
90 void prettyPrint()
const {
91 rt_printf(
"type: %s, ", this->getTypeText());
92 rt_printf(
"channel: %u, ", this->getChannel());
93 for(
unsigned int n = 0; n < this->getNumDataBytes(); n++){
94 rt_printf(
"data%d: %d, ", n + 1, this->getDataByte(n));
99 const static int maxDataBytes = 2;
101 midi_byte_t _statusByte;
102 midi_byte_t _dataBytes[maxDataBytes];
103 MidiMessageType _type;
104 midi_byte_t _channel;
139 std::vector<MidiChannelMessage> messages;
140 unsigned int writePointer;
141 unsigned int readPointer;
142 unsigned int elapsedDataBytes;
143 bool waitingForStatus;
147 void (*sysexCallback)(midi_byte_t,
void*);
148 void* sysexCallbackArg;
151 waitingForStatus =
true;
152 receivingSysex =
false;
154 messages.resize(100);
157 messageReadyCallback =
nullptr;
158 callbackArg =
nullptr;
159 sysexCallback =
nullptr;
160 sysexCallbackArg =
nullptr;
171 int parse(midi_byte_t* input,
unsigned int length);
192 messageReadyCallback = newCallback;
201 return messageReadyCallback !=
nullptr;
221 sysexCallbackArg = arg;
222 sysexCallback = newCallback;
231 return sysexCallback !=
nullptr;
240 int num = (writePointer - readPointer + messages.size() ) % messages.size();
254 message = messages[readPointer];
255 if(message.getType() == kmmNone){
258 messages[readPointer].setType(kmmNone);
260 if(readPointer == messages.size()){
281 typedef struct _snd_rawmidi snd_rawmidi_t;
353 int writeOutput(midi_byte_t* bytes,
unsigned int length);
356 static midi_byte_t makeStatusByte(midi_byte_t statusCode, midi_byte_t dataByte);
357 int writeMessage(midi_byte_t statusCode, midi_byte_t channel, midi_byte_t dataByte);
358 int writeMessage(midi_byte_t statusCode, midi_byte_t channel, midi_byte_t dataByte1, midi_byte_t dataByte2);
360 int writeNoteOff(midi_byte_t channel, midi_byte_t pitch, midi_byte_t velocity);
361 int writeNoteOn(midi_byte_t channel, midi_byte_t pitch, midi_byte_t velocity);
362 int writePolyphonicKeyPressure(midi_byte_t channel, midi_byte_t pitch, midi_byte_t pressure);
363 int writeControlChange(midi_byte_t channel, midi_byte_t controller, midi_byte_t value);
364 int writeProgramChange(midi_byte_t channel, midi_byte_t program);
365 int writeChannelPressure(midi_byte_t channel, midi_byte_t pressure);
366 int writePitchBend(midi_byte_t channel, uint16_t bend);
376 bool isInputEnabled();
378 bool isOutputEnabled();
384 static void createAllPorts(std::vector<Midi*>& ports,
bool useParser =
false);
395 int attemptRecoveryRead();
396 static void readInputLoop(
void* obj);
397 int attemptRecoveryWrite();
398 static void writeOutputLoop(
void* obj);
399 snd_rawmidi_t *alsaIn,*alsaOut;
400 std::vector<midi_byte_t> inputBytes;
401 unsigned int inputBytesWritePointer;
402 unsigned int inputBytesReadPointer;
403 std::vector<midi_byte_t> outputBytes;
413 #ifdef XENOMAI_SKIN_native
416 #ifdef XENOMAI_SKIN_posix
static void createAllPorts(std::vector< Midi * > &ports, bool useParser=false)
Definition: Midi.cpp:366
MidiParser * getMidiParser()
int numAvailableMessages()
Definition: Midi.h:239
void setSysexCallback(void(*newCallback)(midi_byte_t, void *), void *arg=nullptr)
Definition: Midi.h:220
void enableParser(bool enable)
Definition: Midi.cpp:148
bool isCallbackEnabled()
Definition: Midi.h:200
MidiParser * getParser()
Definition: Midi.cpp:469
int writeTo(const char *port)
Definition: Midi.cpp:322
int parse(midi_byte_t *input, unsigned int length)
Definition: Midi.cpp:39
int writeOutput(midi_byte_t byte)
Definition: Midi.cpp:476
bool isSysexCallbackEnabled()
Definition: Midi.h:230
MidiChannelMessage getNextChannelMessage()
Definition: Midi.h:252
void setParserCallback(void(*callback)(MidiChannelMessage, void *), void *arg=NULL)
Definition: Midi.h:313
static void destroyPorts(std::vector< Midi * > &ports)
int readFrom(const char *port)
Definition: Midi.cpp:303
int getInput()
Definition: Midi.cpp:462
void * AuxiliaryTask
Definition: Bela.h:561
void setCallback(void(*newCallback)(MidiChannelMessage, void *), void *arg=NULL)
Definition: Midi.h:190