Mercurial > hg > beaglert
diff core/Midi.cpp @ 197:265a527f8be8
Added MidiParser for channel messages
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Fri, 05 Feb 2016 06:16:35 +0000 |
parents | b3a306da03e0 |
children | b128e3ea84ff |
line wrap: on
line diff
--- a/core/Midi.cpp Thu Feb 04 18:41:30 2016 +0000 +++ b/core/Midi.cpp Fri Feb 05 06:16:35 2016 +0000 @@ -12,14 +12,68 @@ #define kMidiInput 0 #define kMidiOutput 1 + +midi_byte_t midiMessageStatusBytes[midiMessageStatusBytesLength]= +{ + 0x80, + 0x90, + 0xA0, + 0xB0, + 0xC0, + 0xD0, + 0xE0, + 0 +}; + +unsigned int midiMessageNumDataBytes[midiMessageStatusBytesLength]={2, 2, 2, 2, 1, 1, 2, 0}; + bool Midi::staticConstructed; AuxiliaryTask Midi::midiInputTask; AuxiliaryTask Midi::midiOutputTask; std::vector<Midi *> Midi::objAddrs[2]; +int MidiParser::parse(midi_byte_t* input, unsigned int length){ + unsigned int consumedBytes = 0; + for(unsigned int n = 0; n < length; n++){ + consumedBytes++; + if(waitingForStatus == true){ + int statusByte = input[n]; + MidiMessageType newType = kmmNone; + if (statusByte >= 0x80){//it actually is a status byte + for(int n = 0; n < midiMessageStatusBytesLength; n++){ //find the statusByte in the array + if(midiMessageStatusBytes[n] == (statusByte&0xf0)){ + newType = (MidiMessageType)n; + break; + } + } + elapsedDataBytes = 0; + waitingForStatus = false; + messages[writePointer].setType(newType); + messages[writePointer].setChannel((midi_byte_t)(statusByte&0xf)); + consumedBytes++; + } else { // either something went wrong or it's a system message + continue; + } + } else { + messages[writePointer].setDataByte(elapsedDataBytes, input[n]); + elapsedDataBytes++; + if(elapsedDataBytes == messages[writePointer].getNumDataBytes()){ + waitingForStatus = true; + writePointer++; + if(writePointer == messages.size()){ + writePointer = 0; + } + } + } + } + return consumedBytes; +}; + + Midi::Midi(){ outputPort = -1; inputPort = -1; + inputParser = 0; size_t inputBytesInitialSize = 1000; inputBytes.resize(inputBytesInitialSize); outputBytes.resize(inputBytesInitialSize); @@ -37,6 +91,18 @@ } Midi::~Midi(){} + +void Midi::enableParser(bool enable){ + if(enable == true){ + delete inputParser; + inputParser = new MidiParser(); + parserEnabled = true; + } else { + delete inputParser; + parserEnabled = false; + } +} + void Midi::midiInputLoop(){ printf("Midi input loop %d\n", objAddrs[kMidiInput].size()); for(unsigned int n = 0; n < objAddrs[kMidiInput].size(); n++){ @@ -66,9 +132,32 @@ if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around inputBytesWritePointer = 0; } + if(parserEnabled == true && ret > 0){ // if the parser is enabled and there is new data, send the data to it + int input; + while((input=getInput()) >= 0){ + midi_byte_t inputByte = (midi_byte_t)(input); +// printf("__0x%x\n", input); + inputParser->parse(&inputByte, 1); + } +// if(inputBytesReadPointer == inputBytesWritePointer){ + // this should never be the case, it should only happen when ret == 0 +// } else { + +// unsigned int length = (inputBytesWritePointer - inputBytesReadPointer + inputBytes.size()) +// % inputBytes.size(); +// rt_printf("inputBytes: 0x%x 0x%x 0x%x", inputBytes[inputBytesReadPointer], +// inputBytes[inputBytesReadPointer+1], inputBytes[inputBytesReadPointer+2]); +// length = inputParser->parse(&inputBytes[inputBytesReadPointer], length); +// inputBytesReadPointer += length; //if parserEnabled, the readPointer is incremented here, +// //so calls to getInput() should be avoided +// if(inputBytesReadPointer == inputBytes.size()){ +// inputBytesReadPointer = 0; +// } +// } + } if(ret < maxBytesToRead){ //no more data to retrieve at the moment usleep(1000); - } // otherwise there might be more data ready to be read, so don't sleep + } // otherwise there might be more data ready to be read (we were at the end of the buffer), so don't sleep } } @@ -85,21 +174,10 @@ int ret; ret = write(outputPort, &outputBytes[outputBytesReadPointer], sizeof(midi_byte_t)*length); if(ret < 0){ //error occurred -// if(errno != EAGAIN){ // () would return EAGAIN when no data are available to read just now -// rt_printf("Error while writing midi %d\n", errno); -// } rt_printf("error occurred while writing: %d\n", errno); usleep(10000); //wait before retrying continue; } - -// inputBytesWritePointer += ret; -// if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around -// inputBytesWritePointer = 0; -// } -// if(ret < maxBytesToRead){ //no more data to retrieve at the moment -// usleep(1000); -// } // otherwise there might be more data ready to be read, so don't sleep } } int Midi::readFrom(int port){ @@ -129,6 +207,9 @@ } int Midi::getInput(){ +// if(parserEnabled == true) { +// return -3; +// } if(inputPort < 0) return -2; if(inputBytesReadPointer == inputBytesWritePointer){ @@ -141,6 +222,13 @@ return inputMessage; } +MidiParser* Midi::getParser(){ + if(parserEnabled == false){ + return 0; + } + return inputParser; +}; + int Midi::writeOutput(midi_byte_t byte){ return writeOutput(&byte, 1); } @@ -152,3 +240,29 @@ else return 1; } + +MidiChannelMessage::MidiChannelMessage(){}; +MidiChannelMessage::MidiChannelMessage(MidiMessageType type){ + setType(type); +}; +MidiChannelMessage::~MidiChannelMessage(){}; +MidiMessageType MidiChannelMessage::getType(){ + return _type; +}; +int MidiChannelMessage::getChannel(){ + return _channel; +}; +//int MidiChannelMessage::set(midi_byte_t* input); +// +//int MidiControlChangeMessage ::getValue(); +//int MidiControlChangeMessage::set(midi_byte_t* input){ +// channel = input[0]; +// number = input[1]; +// value = input[2]; +// return 3; +//} + +//int MidiNoteMessage::getNote(); +//int MidiNoteMessage::getVelocity(); + +//midi_byte_t MidiProgramChangeMessage::getProgram();