Mercurial > hg > beaglert
changeset 191:b3a306da03e0
Implemented Midi output
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Wed, 03 Feb 2016 01:18:30 +0000 |
parents | 7144c5594d16 |
children | 1402f22fc99a |
files | core/Midi.cpp include/Midi.h projects/basic_midi/render.cpp |
diffstat | 3 files changed, 97 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/core/Midi.cpp Tue Jan 26 00:02:15 2016 +0000 +++ b/core/Midi.cpp Wed Feb 03 01:18:30 2016 +0000 @@ -9,16 +9,20 @@ #include <fcntl.h> #include <errno.h> +#define kMidiInput 0 +#define kMidiOutput 1 + bool Midi::staticConstructed; AuxiliaryTask Midi::midiInputTask; AuxiliaryTask Midi::midiOutputTask; -std::vector<Midi *> Midi::objAddrs(0); +std::vector<Midi *> 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; +}
--- a/include/Midi.h Tue Jan 26 00:02:15 2016 +0000 +++ b/include/Midi.h Wed Feb 03 01:18:30 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<midi_byte_t> inputBytes; unsigned int inputBytesWritePointer; unsigned int inputBytesReadPointer; std::vector<midi_byte_t> outputBytes; - static std::vector<Midi*> objAddrs; + unsigned int outputBytesWritePointer; + unsigned int outputBytesReadPointer; + static std::vector<Midi*> objAddrs[2]; static AuxiliaryTask midiInputTask; static AuxiliaryTask midiOutputTask; };
--- a/projects/basic_midi/render.cpp Tue Jan 26 00:02:15 2016 +0000 +++ b/projects/basic_midi/render.cpp Wed Feb 03 01:18:30 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++; } }