# HG changeset patch # User Giulio Moro # Date 1454462501 0 # Node ID 1402f22fc99a04faac1581749f824f50cce3423e # Parent b3a306da03e0864882aad0a7bed71777e3e8a71c# Parent 3b8a28edae41178256b05c328a35a824e79d90ce merge diff -r 3b8a28edae41 -r 1402f22fc99a core/Midi.cpp --- a/core/Midi.cpp Wed Jan 27 19:13:57 2016 +0000 +++ b/core/Midi.cpp Wed Feb 03 01:21:41 2016 +0000 @@ -9,16 +9,20 @@ #include #include +#define kMidiInput 0 +#define kMidiOutput 1 + bool Midi::staticConstructed; AuxiliaryTask Midi::midiInputTask; AuxiliaryTask Midi::midiOutputTask; -std::vector Midi::objAddrs(0); +std::vector Midi::objAddrs[2]; Midi::Midi(){ outputPort = -1; inputPort = -1; size_t inputBytesInitialSize = 1000; inputBytes.resize(inputBytesInitialSize); + outputBytes.resize(inputBytesInitialSize); inputBytesWritePointer = 0; inputBytesReadPointer = inputBytes.size() - 1; if(!staticConstructed){ @@ -29,15 +33,21 @@ void Midi::staticConstructor(){ staticConstructed = true; midiInputTask = BeagleRT_createAuxiliaryTask(Midi::midiInputLoop, 50, "MidiInput"); - midiOutputTask = BeagleRT_createAuxiliaryTask(Midi::midiInputLoop, 50, "MidiOutupt"); + midiOutputTask = BeagleRT_createAuxiliaryTask(Midi::midiOutputLoop, 50, "MidiOutupt"); } Midi::~Midi(){} +void Midi::midiInputLoop(){ + printf("Midi input loop %d\n", objAddrs[kMidiInput].size()); + for(unsigned int n = 0; n < objAddrs[kMidiInput].size(); n++){ + objAddrs[kMidiInput][n] -> readInputLoop(); + } +} -void Midi::midiInputLoop(){ - printf("Midi input loop %d\n", objAddrs.size()); - for(unsigned int n = 0; n < objAddrs.size(); n++){ - objAddrs[n] -> readInputLoop(); +void Midi::midiOutputLoop(){ + printf("Midi output loop %d\n", objAddrs[kMidiOutput].size()); + for(unsigned int n = 0; n < objAddrs[kMidiOutput].size(); n++){ + objAddrs[kMidiOutput][n] -> writeOutputLoop(); } } @@ -45,8 +55,6 @@ while(!gShouldStop){ int maxBytesToRead = inputBytes.size() - inputBytesWritePointer; int ret = read(inputPort, &inputBytes[inputBytesWritePointer], sizeof(midi_byte_t)*maxBytesToRead); - static int count = 0; - count++; if(ret < 0){ if(errno != EAGAIN){ // read() would return EAGAIN when no data are available to read just now rt_printf("Error while reading midi %d\n", errno); @@ -64,20 +72,63 @@ } } +void Midi::writeOutputLoop(){ + while(!gShouldStop){ + usleep(1000); + int length = outputBytesWritePointer - outputBytesReadPointer; + if(length < 0){ + length = outputBytes.size() - outputBytesReadPointer; + } + if(length == 0){ //nothing to be written + continue; + } + 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){ - objAddrs.push_back(this); + objAddrs[kMidiInput].push_back(this); inputPort = open("/dev/midi1", O_RDONLY | O_NONBLOCK | O_NOCTTY); if(inputPort < 0){ - printf("Error occurred while opening midi port %d: %d", port, inputPort); + printf("Error occurred while opening midi input port %d: %d", port, inputPort); return -1; } else { - printf("Reading from port %d\n", inputPort); + printf("Reading from port %d\n", port); BeagleRT_scheduleAuxiliaryTask(midiInputTask); return 1; } } -int Midi::getInput(){ +int Midi::writeTo(int port){ + objAddrs[kMidiOutput].push_back(this); + outputPort = open("/dev/midi1", O_WRONLY, 0); + if(outputPort < 0){ + printf("Error occurred while opening midi output port %d: %d", port, outputPort); + return -1; + } else { + printf("Writing to Midi port %d\n", port); + BeagleRT_scheduleAuxiliaryTask(midiOutputTask); + return 1; + } +} + +int Midi::getInput(){ if(inputPort < 0) return -2; if(inputBytesReadPointer == inputBytesWritePointer){ @@ -89,3 +140,15 @@ } return inputMessage; } + +int Midi::writeOutput(midi_byte_t byte){ + return writeOutput(&byte, 1); +} + +int Midi::writeOutput(midi_byte_t* bytes, unsigned int length){ + int ret = write(outputPort, bytes, length); + if(ret < 0) + return -1; + else + return 1; +} diff -r 3b8a28edae41 -r 1402f22fc99a include/Midi.h --- a/include/Midi.h Wed Jan 27 19:13:57 2016 +0000 +++ b/include/Midi.h Wed Feb 03 01:21:41 2016 +0000 @@ -30,7 +30,7 @@ int writeTo(int port); /** - * Get received midi byte, one at a time. + * Get received midi bytes, one at a time. * @return -1 if no new byte is available, -2 on error, * the oldest not yet retrieved midi byte otherwise */ @@ -49,21 +49,25 @@ * @param length number of bytes to write * @return 1 on success, -1 on error */ - int writeMidiOut(short unsigned int* bytes, unsigned int length); + int writeOutput(midi_byte_t* bytes, unsigned int length); virtual ~Midi(); static void midiInputLoop(); + static void midiOutputLoop(); static bool staticConstructed; static void staticConstructor(); private: void readInputLoop(); + void writeOutputLoop(); int outputPort; int inputPort; std::vector inputBytes; unsigned int inputBytesWritePointer; unsigned int inputBytesReadPointer; std::vector outputBytes; - static std::vector objAddrs; + unsigned int outputBytesWritePointer; + unsigned int outputBytesReadPointer; + static std::vector objAddrs[2]; static AuxiliaryTask midiInputTask; static AuxiliaryTask midiOutputTask; }; diff -r 3b8a28edae41 -r 1402f22fc99a projects/basic_midi/render.cpp --- a/projects/basic_midi/render.cpp Wed Jan 27 19:13:57 2016 +0000 +++ b/projects/basic_midi/render.cpp Wed Feb 03 01:21:41 2016 +0000 @@ -24,6 +24,7 @@ bool setup(BeagleRTContext *context, void *userData) { midi.readFrom(0); + midi.writeTo(0); if(context->analogFrames == 0) { rt_printf("Error: this example needs the matrix enabled\n"); return false; @@ -36,7 +37,7 @@ // ADCs and DACs (if available). If only audio is available, numMatrixFrames // will be 0. -static midi_byte_t noteOnStatus =0x90; //on channel 1 +static midi_byte_t noteOnStatus = 0x90; //on channel 1 enum {kVelocity, kNoteOn, kNoteNumber}; void render(BeagleRTContext *context, void *userData) @@ -50,6 +51,7 @@ static int waitingFor = kNoteOn; static int playingNote = -1; while ((message = midi.getInput()) >= 0){ + rt_printf("%d\n", message); switch(waitingFor){ case kNoteOn: if(message == noteOnStatus){ @@ -86,7 +88,17 @@ break; } } - for(unsigned int n = 0; n < context->audioFrames; n++){ + + for(unsigned int n = 0; n < context->analogFrames; n++){ + static int count = 0; + static bool state = 0; + analogWriteFrameOnce(context, n, 1, state); + if(count % 40000 == 0){ + state = !state; + midi_byte_t bytes[6] = {176, 30, state*127, 176, 67, 30}; // toggle the OWL led and ask for the led status + midi.writeOutput(bytes, 6); + } + if(noteOn == 1){ static float phase = 0; phase += phaseIncrement; @@ -99,6 +111,7 @@ audioWriteFrame(context, n, 0, 0); audioWriteFrame(context, n, 1, 0); } + count++; } }