annotate core/Midi.cpp @ 191:b3a306da03e0

Implemented Midi output
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 03 Feb 2016 01:18:30 +0000
parents 9108a0a34cb8
children 265a527f8be8
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@191 12 #define kMidiInput 0
giuliomoro@191 13 #define kMidiOutput 1
giuliomoro@191 14
giuliomoro@181 15 bool Midi::staticConstructed;
giuliomoro@181 16 AuxiliaryTask Midi::midiInputTask;
giuliomoro@181 17 AuxiliaryTask Midi::midiOutputTask;
giuliomoro@191 18 std::vector<Midi *> Midi::objAddrs[2];
giuliomoro@181 19
giuliomoro@181 20 Midi::Midi(){
giuliomoro@181 21 outputPort = -1;
giuliomoro@181 22 inputPort = -1;
giuliomoro@181 23 size_t inputBytesInitialSize = 1000;
giuliomoro@181 24 inputBytes.resize(inputBytesInitialSize);
giuliomoro@191 25 outputBytes.resize(inputBytesInitialSize);
giuliomoro@181 26 inputBytesWritePointer = 0;
giuliomoro@181 27 inputBytesReadPointer = inputBytes.size() - 1;
giuliomoro@181 28 if(!staticConstructed){
giuliomoro@181 29 staticConstructor();
giuliomoro@181 30 }
giuliomoro@181 31 }
giuliomoro@181 32
giuliomoro@181 33 void Midi::staticConstructor(){
giuliomoro@181 34 staticConstructed = true;
giuliomoro@181 35 midiInputTask = BeagleRT_createAuxiliaryTask(Midi::midiInputLoop, 50, "MidiInput");
giuliomoro@191 36 midiOutputTask = BeagleRT_createAuxiliaryTask(Midi::midiOutputLoop, 50, "MidiOutupt");
giuliomoro@181 37 }
giuliomoro@181 38
giuliomoro@181 39 Midi::~Midi(){}
giuliomoro@191 40 void Midi::midiInputLoop(){
giuliomoro@191 41 printf("Midi input loop %d\n", objAddrs[kMidiInput].size());
giuliomoro@191 42 for(unsigned int n = 0; n < objAddrs[kMidiInput].size(); n++){
giuliomoro@191 43 objAddrs[kMidiInput][n] -> readInputLoop();
giuliomoro@191 44 }
giuliomoro@191 45 }
giuliomoro@181 46
giuliomoro@191 47 void Midi::midiOutputLoop(){
giuliomoro@191 48 printf("Midi output loop %d\n", objAddrs[kMidiOutput].size());
giuliomoro@191 49 for(unsigned int n = 0; n < objAddrs[kMidiOutput].size(); n++){
giuliomoro@191 50 objAddrs[kMidiOutput][n] -> writeOutputLoop();
giuliomoro@181 51 }
giuliomoro@181 52 }
giuliomoro@181 53
giuliomoro@181 54 void Midi::readInputLoop(){
giuliomoro@181 55 while(!gShouldStop){
giuliomoro@181 56 int maxBytesToRead = inputBytes.size() - inputBytesWritePointer;
giuliomoro@181 57 int ret = read(inputPort, &inputBytes[inputBytesWritePointer], sizeof(midi_byte_t)*maxBytesToRead);
giuliomoro@181 58 if(ret < 0){
giuliomoro@181 59 if(errno != EAGAIN){ // read() would return EAGAIN when no data are available to read just now
giuliomoro@181 60 rt_printf("Error while reading midi %d\n", errno);
giuliomoro@181 61 }
giuliomoro@181 62 usleep(1000);
giuliomoro@181 63 continue;
giuliomoro@181 64 }
giuliomoro@181 65 inputBytesWritePointer += ret;
giuliomoro@181 66 if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around
giuliomoro@181 67 inputBytesWritePointer = 0;
giuliomoro@181 68 }
giuliomoro@181 69 if(ret < maxBytesToRead){ //no more data to retrieve at the moment
giuliomoro@181 70 usleep(1000);
giuliomoro@181 71 } // otherwise there might be more data ready to be read, so don't sleep
giuliomoro@181 72 }
giuliomoro@181 73 }
giuliomoro@181 74
giuliomoro@191 75 void Midi::writeOutputLoop(){
giuliomoro@191 76 while(!gShouldStop){
giuliomoro@191 77 usleep(1000);
giuliomoro@191 78 int length = outputBytesWritePointer - outputBytesReadPointer;
giuliomoro@191 79 if(length < 0){
giuliomoro@191 80 length = outputBytes.size() - outputBytesReadPointer;
giuliomoro@191 81 }
giuliomoro@191 82 if(length == 0){ //nothing to be written
giuliomoro@191 83 continue;
giuliomoro@191 84 }
giuliomoro@191 85 int ret;
giuliomoro@191 86 ret = write(outputPort, &outputBytes[outputBytesReadPointer], sizeof(midi_byte_t)*length);
giuliomoro@191 87 if(ret < 0){ //error occurred
giuliomoro@191 88 // if(errno != EAGAIN){ // () would return EAGAIN when no data are available to read just now
giuliomoro@191 89 // rt_printf("Error while writing midi %d\n", errno);
giuliomoro@191 90 // }
giuliomoro@191 91 rt_printf("error occurred while writing: %d\n", errno);
giuliomoro@191 92 usleep(10000); //wait before retrying
giuliomoro@191 93 continue;
giuliomoro@191 94 }
giuliomoro@191 95
giuliomoro@191 96 // inputBytesWritePointer += ret;
giuliomoro@191 97 // if(inputBytesWritePointer == inputBytes.size()){ //wrap pointer around
giuliomoro@191 98 // inputBytesWritePointer = 0;
giuliomoro@191 99 // }
giuliomoro@191 100 // if(ret < maxBytesToRead){ //no more data to retrieve at the moment
giuliomoro@191 101 // usleep(1000);
giuliomoro@191 102 // } // otherwise there might be more data ready to be read, so don't sleep
giuliomoro@191 103 }
giuliomoro@191 104 }
giuliomoro@181 105 int Midi::readFrom(int port){
giuliomoro@191 106 objAddrs[kMidiInput].push_back(this);
giuliomoro@181 107 inputPort = open("/dev/midi1", O_RDONLY | O_NONBLOCK | O_NOCTTY);
giuliomoro@181 108 if(inputPort < 0){
giuliomoro@191 109 printf("Error occurred while opening midi input port %d: %d", port, inputPort);
giuliomoro@181 110 return -1;
giuliomoro@181 111 } else {
giuliomoro@191 112 printf("Reading from port %d\n", port);
giuliomoro@181 113 BeagleRT_scheduleAuxiliaryTask(midiInputTask);
giuliomoro@181 114 return 1;
giuliomoro@181 115 }
giuliomoro@181 116 }
giuliomoro@181 117
giuliomoro@191 118 int Midi::writeTo(int port){
giuliomoro@191 119 objAddrs[kMidiOutput].push_back(this);
giuliomoro@191 120 outputPort = open("/dev/midi1", O_WRONLY, 0);
giuliomoro@191 121 if(outputPort < 0){
giuliomoro@191 122 printf("Error occurred while opening midi output port %d: %d", port, outputPort);
giuliomoro@191 123 return -1;
giuliomoro@191 124 } else {
giuliomoro@191 125 printf("Writing to Midi port %d\n", port);
giuliomoro@191 126 BeagleRT_scheduleAuxiliaryTask(midiOutputTask);
giuliomoro@191 127 return 1;
giuliomoro@191 128 }
giuliomoro@191 129 }
giuliomoro@191 130
giuliomoro@191 131 int Midi::getInput(){
giuliomoro@181 132 if(inputPort < 0)
giuliomoro@181 133 return -2;
giuliomoro@181 134 if(inputBytesReadPointer == inputBytesWritePointer){
giuliomoro@181 135 return -1; // no bytes to read
giuliomoro@181 136 }
giuliomoro@181 137 midi_byte_t inputMessage = inputBytes[inputBytesReadPointer++];
giuliomoro@181 138 if(inputBytesReadPointer == inputBytes.size()){ // wrap pointer
giuliomoro@181 139 inputBytesReadPointer = 0;
giuliomoro@181 140 }
giuliomoro@181 141 return inputMessage;
giuliomoro@181 142 }
giuliomoro@191 143
giuliomoro@191 144 int Midi::writeOutput(midi_byte_t byte){
giuliomoro@191 145 return writeOutput(&byte, 1);
giuliomoro@191 146 }
giuliomoro@191 147
giuliomoro@191 148 int Midi::writeOutput(midi_byte_t* bytes, unsigned int length){
giuliomoro@191 149 int ret = write(outputPort, bytes, length);
giuliomoro@191 150 if(ret < 0)
giuliomoro@191 151 return -1;
giuliomoro@191 152 else
giuliomoro@191 153 return 1;
giuliomoro@191 154 }