annotate core/Midi.cpp @ 184:9108a0a34cb8

Better(non ideal) monophonic behaviour of the basic midi implementation. Would require to remember what notes are being held down and release either the most recent or low/high priority.
author Giulio Moro <giuliomoro@yahoo.it>
date Sun, 17 Jan 2016 21:56:13 +0000
parents 391ad036557d
children b3a306da03e0
rev   line source
giuliomoro@181 1 /*
giuliomoro@181 2 * Midi.cpp
giuliomoro@181 3 *
giuliomoro@181 4 * Created on: 15 Jan 2016
giuliomoro@181 5 * Author: giulio
giuliomoro@181 6 */
giuliomoro@181 7
giuliomoro@181 8 #include "Midi.h"
giuliomoro@181 9 #include <fcntl.h>
giuliomoro@181 10 #include <errno.h>
giuliomoro@181 11
giuliomoro@181 12 bool Midi::staticConstructed;
giuliomoro@181 13 AuxiliaryTask Midi::midiInputTask;
giuliomoro@181 14 AuxiliaryTask Midi::midiOutputTask;
giuliomoro@181 15 std::vector<Midi *> Midi::objAddrs(0);
giuliomoro@181 16
giuliomoro@181 17 Midi::Midi(){
giuliomoro@181 18 outputPort = -1;
giuliomoro@181 19 inputPort = -1;
giuliomoro@181 20 size_t inputBytesInitialSize = 1000;
giuliomoro@181 21 inputBytes.resize(inputBytesInitialSize);
giuliomoro@181 22 inputBytesWritePointer = 0;
giuliomoro@181 23 inputBytesReadPointer = inputBytes.size() - 1;
giuliomoro@181 24 if(!staticConstructed){
giuliomoro@181 25 staticConstructor();
giuliomoro@181 26 }
giuliomoro@181 27 }
giuliomoro@181 28
giuliomoro@181 29 void Midi::staticConstructor(){
giuliomoro@181 30 staticConstructed = true;
giuliomoro@181 31 midiInputTask = BeagleRT_createAuxiliaryTask(Midi::midiInputLoop, 50, "MidiInput");
giuliomoro@181 32 midiOutputTask = BeagleRT_createAuxiliaryTask(Midi::midiInputLoop, 50, "MidiOutupt");
giuliomoro@181 33 }
giuliomoro@181 34
giuliomoro@181 35 Midi::~Midi(){}
giuliomoro@181 36
giuliomoro@181 37 void Midi::midiInputLoop(){
giuliomoro@181 38 printf("Midi input loop %d\n", objAddrs.size());
giuliomoro@181 39 for(unsigned int n = 0; n < objAddrs.size(); n++){
giuliomoro@181 40 objAddrs[n] -> readInputLoop();
giuliomoro@181 41 }
giuliomoro@181 42 }
giuliomoro@181 43
giuliomoro@181 44 void Midi::readInputLoop(){
giuliomoro@181 45 while(!gShouldStop){
giuliomoro@181 46 int maxBytesToRead = inputBytes.size() - inputBytesWritePointer;
giuliomoro@181 47 int ret = read(inputPort, &inputBytes[inputBytesWritePointer], sizeof(midi_byte_t)*maxBytesToRead);
giuliomoro@181 48 static int count = 0;
giuliomoro@181 49 count++;
giuliomoro@181 50 if(ret < 0){
giuliomoro@181 51 if(errno != EAGAIN){ // read() would return EAGAIN when no data are available to read just now
giuliomoro@181 52 rt_printf("Error while reading midi %d\n", errno);
giuliomoro@181 53 }
giuliomoro@181 54 usleep(1000);
giuliomoro@181 55 continue;
giuliomoro@181 56 }
giuliomoro@181 57 inputBytesWritePointer += ret;
giuliomoro@181 58 if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around
giuliomoro@181 59 inputBytesWritePointer = 0;
giuliomoro@181 60 }
giuliomoro@181 61 if(ret < maxBytesToRead){ //no more data to retrieve at the moment
giuliomoro@181 62 usleep(1000);
giuliomoro@181 63 } // otherwise there might be more data ready to be read, so don't sleep
giuliomoro@181 64 }
giuliomoro@181 65 }
giuliomoro@181 66
giuliomoro@181 67 int Midi::readFrom(int port){
giuliomoro@181 68 objAddrs.push_back(this);
giuliomoro@181 69 inputPort = open("/dev/midi1", O_RDONLY | O_NONBLOCK | O_NOCTTY);
giuliomoro@181 70 if(inputPort < 0){
giuliomoro@181 71 printf("Error occurred while opening midi port %d: %d", port, inputPort);
giuliomoro@181 72 return -1;
giuliomoro@181 73 } else {
giuliomoro@181 74 printf("Reading from port %d\n", inputPort);
giuliomoro@181 75 BeagleRT_scheduleAuxiliaryTask(midiInputTask);
giuliomoro@181 76 return 1;
giuliomoro@181 77 }
giuliomoro@181 78 }
giuliomoro@181 79
giuliomoro@181 80 int Midi::getInput(){
giuliomoro@181 81 if(inputPort < 0)
giuliomoro@181 82 return -2;
giuliomoro@181 83 if(inputBytesReadPointer == inputBytesWritePointer){
giuliomoro@181 84 return -1; // no bytes to read
giuliomoro@181 85 }
giuliomoro@181 86 midi_byte_t inputMessage = inputBytes[inputBytesReadPointer++];
giuliomoro@181 87 if(inputBytesReadPointer == inputBytes.size()){ // wrap pointer
giuliomoro@181 88 inputBytesReadPointer = 0;
giuliomoro@181 89 }
giuliomoro@181 90 return inputMessage;
giuliomoro@181 91 }