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 }
|