giuliomoro@181: /* giuliomoro@181: * Midi.cpp giuliomoro@181: * giuliomoro@181: * Created on: 15 Jan 2016 giuliomoro@181: * Author: giulio giuliomoro@181: */ giuliomoro@181: giuliomoro@181: #include "Midi.h" giuliomoro@181: #include giuliomoro@181: #include giuliomoro@181: giuliomoro@191: #define kMidiInput 0 giuliomoro@191: #define kMidiOutput 1 giuliomoro@191: giuliomoro@181: bool Midi::staticConstructed; giuliomoro@181: AuxiliaryTask Midi::midiInputTask; giuliomoro@181: AuxiliaryTask Midi::midiOutputTask; giuliomoro@191: std::vector Midi::objAddrs[2]; giuliomoro@181: giuliomoro@181: Midi::Midi(){ giuliomoro@181: outputPort = -1; giuliomoro@181: inputPort = -1; giuliomoro@181: size_t inputBytesInitialSize = 1000; giuliomoro@181: inputBytes.resize(inputBytesInitialSize); giuliomoro@191: outputBytes.resize(inputBytesInitialSize); giuliomoro@181: inputBytesWritePointer = 0; giuliomoro@181: inputBytesReadPointer = inputBytes.size() - 1; giuliomoro@181: if(!staticConstructed){ giuliomoro@181: staticConstructor(); giuliomoro@181: } giuliomoro@181: } giuliomoro@181: giuliomoro@181: void Midi::staticConstructor(){ giuliomoro@181: staticConstructed = true; giuliomoro@181: midiInputTask = BeagleRT_createAuxiliaryTask(Midi::midiInputLoop, 50, "MidiInput"); giuliomoro@191: midiOutputTask = BeagleRT_createAuxiliaryTask(Midi::midiOutputLoop, 50, "MidiOutupt"); giuliomoro@181: } giuliomoro@181: giuliomoro@181: Midi::~Midi(){} giuliomoro@191: void Midi::midiInputLoop(){ giuliomoro@191: printf("Midi input loop %d\n", objAddrs[kMidiInput].size()); giuliomoro@191: for(unsigned int n = 0; n < objAddrs[kMidiInput].size(); n++){ giuliomoro@191: objAddrs[kMidiInput][n] -> readInputLoop(); giuliomoro@191: } giuliomoro@191: } giuliomoro@181: giuliomoro@191: void Midi::midiOutputLoop(){ giuliomoro@191: printf("Midi output loop %d\n", objAddrs[kMidiOutput].size()); giuliomoro@191: for(unsigned int n = 0; n < objAddrs[kMidiOutput].size(); n++){ giuliomoro@191: objAddrs[kMidiOutput][n] -> writeOutputLoop(); giuliomoro@181: } giuliomoro@181: } giuliomoro@181: giuliomoro@181: void Midi::readInputLoop(){ giuliomoro@181: while(!gShouldStop){ giuliomoro@181: int maxBytesToRead = inputBytes.size() - inputBytesWritePointer; giuliomoro@181: int ret = read(inputPort, &inputBytes[inputBytesWritePointer], sizeof(midi_byte_t)*maxBytesToRead); giuliomoro@181: if(ret < 0){ giuliomoro@181: if(errno != EAGAIN){ // read() would return EAGAIN when no data are available to read just now giuliomoro@181: rt_printf("Error while reading midi %d\n", errno); giuliomoro@181: } giuliomoro@181: usleep(1000); giuliomoro@181: continue; giuliomoro@181: } giuliomoro@181: inputBytesWritePointer += ret; giuliomoro@181: if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around giuliomoro@181: inputBytesWritePointer = 0; giuliomoro@181: } giuliomoro@181: if(ret < maxBytesToRead){ //no more data to retrieve at the moment giuliomoro@181: usleep(1000); giuliomoro@181: } // otherwise there might be more data ready to be read, so don't sleep giuliomoro@181: } giuliomoro@181: } giuliomoro@181: giuliomoro@191: void Midi::writeOutputLoop(){ giuliomoro@191: while(!gShouldStop){ giuliomoro@191: usleep(1000); giuliomoro@191: int length = outputBytesWritePointer - outputBytesReadPointer; giuliomoro@191: if(length < 0){ giuliomoro@191: length = outputBytes.size() - outputBytesReadPointer; giuliomoro@191: } giuliomoro@191: if(length == 0){ //nothing to be written giuliomoro@191: continue; giuliomoro@191: } giuliomoro@191: int ret; giuliomoro@191: ret = write(outputPort, &outputBytes[outputBytesReadPointer], sizeof(midi_byte_t)*length); giuliomoro@191: if(ret < 0){ //error occurred giuliomoro@191: // if(errno != EAGAIN){ // () would return EAGAIN when no data are available to read just now giuliomoro@191: // rt_printf("Error while writing midi %d\n", errno); giuliomoro@191: // } giuliomoro@191: rt_printf("error occurred while writing: %d\n", errno); giuliomoro@191: usleep(10000); //wait before retrying giuliomoro@191: continue; giuliomoro@191: } giuliomoro@191: giuliomoro@191: // inputBytesWritePointer += ret; giuliomoro@191: // if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around giuliomoro@191: // inputBytesWritePointer = 0; giuliomoro@191: // } giuliomoro@191: // if(ret < maxBytesToRead){ //no more data to retrieve at the moment giuliomoro@191: // usleep(1000); giuliomoro@191: // } // otherwise there might be more data ready to be read, so don't sleep giuliomoro@191: } giuliomoro@191: } giuliomoro@181: int Midi::readFrom(int port){ giuliomoro@191: objAddrs[kMidiInput].push_back(this); giuliomoro@181: inputPort = open("/dev/midi1", O_RDONLY | O_NONBLOCK | O_NOCTTY); giuliomoro@181: if(inputPort < 0){ giuliomoro@191: printf("Error occurred while opening midi input port %d: %d", port, inputPort); giuliomoro@181: return -1; giuliomoro@181: } else { giuliomoro@191: printf("Reading from port %d\n", port); giuliomoro@181: BeagleRT_scheduleAuxiliaryTask(midiInputTask); giuliomoro@181: return 1; giuliomoro@181: } giuliomoro@181: } giuliomoro@181: giuliomoro@191: int Midi::writeTo(int port){ giuliomoro@191: objAddrs[kMidiOutput].push_back(this); giuliomoro@191: outputPort = open("/dev/midi1", O_WRONLY, 0); giuliomoro@191: if(outputPort < 0){ giuliomoro@191: printf("Error occurred while opening midi output port %d: %d", port, outputPort); giuliomoro@191: return -1; giuliomoro@191: } else { giuliomoro@191: printf("Writing to Midi port %d\n", port); giuliomoro@191: BeagleRT_scheduleAuxiliaryTask(midiOutputTask); giuliomoro@191: return 1; giuliomoro@191: } giuliomoro@191: } giuliomoro@191: giuliomoro@191: int Midi::getInput(){ giuliomoro@181: if(inputPort < 0) giuliomoro@181: return -2; giuliomoro@181: if(inputBytesReadPointer == inputBytesWritePointer){ giuliomoro@181: return -1; // no bytes to read giuliomoro@181: } giuliomoro@181: midi_byte_t inputMessage = inputBytes[inputBytesReadPointer++]; giuliomoro@181: if(inputBytesReadPointer == inputBytes.size()){ // wrap pointer giuliomoro@181: inputBytesReadPointer = 0; giuliomoro@181: } giuliomoro@181: return inputMessage; giuliomoro@181: } giuliomoro@191: giuliomoro@191: int Midi::writeOutput(midi_byte_t byte){ giuliomoro@191: return writeOutput(&byte, 1); giuliomoro@191: } giuliomoro@191: giuliomoro@191: int Midi::writeOutput(midi_byte_t* bytes, unsigned int length){ giuliomoro@191: int ret = write(outputPort, bytes, length); giuliomoro@191: if(ret < 0) giuliomoro@191: return -1; giuliomoro@191: else giuliomoro@191: return 1; giuliomoro@191: }