1 /* 2 * Copyright (c) 2003-2004 Matthijs Hollemans 3 * Copyright (c) 2004 Christian Packmann 4 * Copyright (c) 2003 Jerome Leveque 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 29 #include "PortDrivers.h" 30 31 //------------------------------------------------------------------------------ 32 33 MidiPortConsumer::MidiPortConsumer(int fd_, const char* name = NULL) 34 : BMidiLocalConsumer(name) 35 { 36 fd = fd_; 37 } 38 39 //------------------------------------------------------------------------------ 40 41 void MidiPortConsumer::Data( 42 uchar* data, size_t length, bool atomic, bigtime_t time) 43 { 44 snooze_until(time - Latency(), B_SYSTEM_TIMEBASE); 45 46 if (write(fd, data, length) == -1) 47 { 48 perror("Error sending data to driver"); 49 } 50 } 51 52 //------------------------------------------------------------------------------ 53 54 MidiPortProducer::MidiPortProducer(int fd_, const char *name = NULL) 55 : BMidiLocalProducer(name) 56 { 57 fd = fd_; 58 keepRunning = true; 59 60 thread_id thread = spawn_thread( 61 SpawnThread, "MidiPortProducer", B_URGENT_PRIORITY, this); 62 63 resume_thread(thread); 64 } 65 66 //------------------------------------------------------------------------------ 67 68 MidiPortProducer::~MidiPortProducer() 69 { 70 keepRunning = false; 71 } 72 73 //------------------------------------------------------------------------------ 74 75 int32 MidiPortProducer::SpawnThread(void* data) 76 { 77 return ((MidiPortProducer*) data)->GetData(); 78 } 79 80 //------------------------------------------------------------------------------ 81 82 int32 MidiPortProducer::GetData() 83 { 84 uint8 msgBuf[3]; 85 uint8* sysexBuf; 86 87 uint8* msgPtr; 88 size_t msgSize; 89 size_t needed = 0; 90 uint8 runningStatus = 0; 91 92 bool haveSysEx = false; 93 size_t sysexAlloc; 94 size_t sysexSize; 95 96 uint8 next; 97 98 while (keepRunning) 99 { 100 if (read(fd, &next, 1) != 1) 101 { 102 perror("Error reading data from driver"); 103 return B_ERROR; 104 } 105 106 if (haveSysEx) // System Exclusive 107 { 108 if (next < 0x80) // data byte 109 { 110 sysexBuf[sysexSize++] = next; 111 if (sysexSize == sysexAlloc) 112 { 113 sysexAlloc *= 2; 114 sysexBuf = (uint8*) realloc(sysexBuf, sysexAlloc); 115 } 116 continue; 117 } 118 else if (next < 0xF8) // end of sysex 119 { 120 SpraySystemExclusive(sysexBuf, sysexSize); 121 haveSysEx = false; 122 } 123 } 124 125 if ((next & 0xF8) == 0xF8) // System Realtime 126 { 127 SpraySystemRealTime(next); 128 } 129 else if ((next & 0xF0) == 0xF0) // System Common 130 { 131 runningStatus = 0; 132 msgBuf[0] = next; 133 msgPtr = msgBuf + 1; 134 switch (next) 135 { 136 case B_SYS_EX_START: 137 sysexAlloc = 4096; 138 sysexBuf = (uint8*) malloc(sysexAlloc); 139 sysexBuf[0] = next; 140 sysexSize = 1; 141 haveSysEx = true; 142 break; 143 144 case B_SONG_POSITION: 145 needed = 2; 146 msgSize = 3; 147 break; 148 149 case B_MIDI_TIME_CODE: 150 case B_SONG_SELECT: 151 case B_CABLE_MESSAGE: 152 needed = 1; 153 msgSize = 2; 154 break; 155 156 case B_TUNE_REQUEST: 157 case B_SYS_EX_END: 158 SpraySystemCommon(next, 0, 0); 159 break; 160 } 161 } 162 else if ((next & 0x80) == 0x80) // Voice message 163 { 164 runningStatus = next; 165 msgBuf[0] = next; 166 msgPtr = msgBuf + 1; 167 switch (next & 0xF0) 168 { 169 case B_NOTE_OFF: 170 case B_NOTE_ON: 171 case B_KEY_PRESSURE: 172 case B_CONTROL_CHANGE: 173 case B_PITCH_BEND: 174 needed = 2; 175 msgSize = 3; 176 break; 177 178 case B_PROGRAM_CHANGE: 179 case B_CHANNEL_PRESSURE: 180 needed = 1; 181 msgSize = 2; 182 break; 183 } 184 } 185 else if (needed > 0) // Data bytes to complete message 186 { 187 *msgPtr++ = next; 188 if (--needed == 0) 189 { 190 switch (msgBuf[0] & 0xF0) 191 { 192 case B_NOTE_OFF: 193 SprayNoteOff(msgBuf[0] & 0x0F, msgBuf[1], msgBuf[2]); 194 break; 195 196 case B_NOTE_ON: 197 SprayNoteOn(msgBuf[0] & 0x0F, msgBuf[1], msgBuf[2]); 198 break; 199 200 case B_KEY_PRESSURE: 201 SprayKeyPressure(msgBuf[0] & 0x0F, msgBuf[1], msgBuf[2]); 202 break; 203 204 case B_CONTROL_CHANGE: 205 SprayControlChange(msgBuf[0] & 0x0F, msgBuf[1], msgBuf[2]); 206 break; 207 208 case B_PROGRAM_CHANGE: 209 SprayProgramChange(msgBuf[0] & 0x0F, msgBuf[1]); 210 break; 211 212 case B_CHANNEL_PRESSURE: 213 SprayChannelPressure(msgBuf[0] & 0x0F, msgBuf[1]); 214 break; 215 216 case B_PITCH_BEND: 217 SprayPitchBend(msgBuf[0] & 0x0F, msgBuf[1], msgBuf[2]); 218 break; 219 } 220 221 switch (msgBuf[0]) 222 { 223 case B_SONG_POSITION: 224 SpraySystemCommon(msgBuf[0], msgBuf[1], msgBuf[2]); 225 break; 226 227 case B_MIDI_TIME_CODE: 228 case B_SONG_SELECT: 229 case B_CABLE_MESSAGE: 230 SpraySystemCommon(msgBuf[0], msgBuf[1], 0); 231 break; 232 } 233 } 234 } 235 else if (runningStatus != 0) // Repeated voice command 236 { 237 msgBuf[0] = runningStatus; 238 msgBuf[1] = next; 239 msgPtr = msgBuf + 2; 240 needed = msgSize - 2; 241 } 242 } 243 244 if (haveSysEx) 245 { 246 free(sysexBuf); 247 } 248 249 return B_OK; 250 } 251 252 //------------------------------------------------------------------------------ 253