trunk/src/osd/portmedia/pmmidi.c
| r20706 | r20707 | |
| 12 | 12 | |
| 13 | 13 | static const int RX_EVENT_BUF_SIZE = 512; |
| 14 | 14 | |
| 15 | #define MIDI_SYSEX 0xf0 |
| 16 | #define MIDI_EOX 0xf7 |
| 17 | |
| 15 | 18 | struct osd_midi_device |
| 16 | 19 | { |
| 17 | 20 | #ifndef DISABLE_MIDI |
| r20706 | r20707 | |
| 242 | 245 | { |
| 243 | 246 | #ifndef DISABLE_MIDI |
| 244 | 247 | int bytes_needed = 0; |
| 248 | PmEvent ev; |
| 249 | ev.timestamp = 0; // use the current time |
| 245 | 250 | |
| 246 | | // skip sysex data |
| 247 | | if (dev->last_status == 0xf0) |
| 251 | // handle sysex |
| 252 | if (dev->last_status == MIDI_SYSEX) |
| 248 | 253 | { |
| 249 | | if (data != 0xf7) |
| 254 | // printf("sysex: %02x (%d)\n", data, dev->xmit_cnt); |
| 255 | |
| 256 | // if we get a status that isn't sysex, assume it's system common |
| 257 | if ((data & 0x80) && (data != MIDI_EOX)) |
| 250 | 258 | { |
| 259 | // printf("common during sysex!\n"); |
| 260 | ev.message = Pm_Message(data, 0, 0); |
| 261 | Pm_Write(dev->pmStream, &ev, 1); |
| 251 | 262 | return; |
| 252 | 263 | } |
| 253 | | else |
| 264 | |
| 265 | dev->xmit_in[dev->xmit_cnt++] = data; |
| 266 | |
| 267 | // if EOX or 4 bytes filled, transmit 4 bytes |
| 268 | if ((dev->xmit_cnt == 4) || (data == MIDI_EOX)) |
| 254 | 269 | { |
| 255 | | dev->last_status = 0xf7; |
| 256 | | return; |
| 270 | ev.message = dev->xmit_in[0] | (dev->xmit_in[1]<<8) | (dev->xmit_in[2]<<16) | (dev->xmit_in[3]<<24); |
| 271 | Pm_Write(dev->pmStream, &ev, 1); |
| 272 | dev->xmit_in[0] = dev->xmit_in[1] = dev->xmit_in[2] = dev->xmit_in[3] = 0; |
| 273 | dev->xmit_cnt = 0; |
| 274 | |
| 275 | // printf("SysEx packet: %08x\n", ev.message); |
| 276 | |
| 277 | // if this is EOX, kill the running status |
| 278 | if (data == MIDI_EOX) |
| 279 | { |
| 280 | dev->last_status = 0; |
| 281 | } |
| 257 | 282 | } |
| 283 | |
| 284 | return; |
| 258 | 285 | } |
| 259 | 286 | |
| 287 | // handle running status |
| 260 | 288 | if ((dev->xmit_cnt == 0) && (data & 0x80)) |
| 261 | 289 | { |
| 262 | 290 | dev->last_status = data; |
| r20706 | r20707 | |
| 272 | 300 | dev->xmit_in[dev->xmit_cnt++] = data; |
| 273 | 301 | } |
| 274 | 302 | |
| 275 | | if ((dev->xmit_cnt == 1) && (dev->xmit_in[0] == 0xf0)) |
| 303 | if ((dev->xmit_cnt == 1) && (dev->xmit_in[0] == MIDI_SYSEX)) |
| 276 | 304 | { |
| 277 | | dev->xmit_cnt = 0; |
| 278 | | dev->last_status = 0xf0; |
| 305 | // printf("Start SysEx!\n"); |
| 306 | dev->last_status = MIDI_SYSEX; |
| 279 | 307 | return; |
| 280 | 308 | } |
| 281 | 309 | |
| r20706 | r20707 | |
| 290 | 318 | case 0xf: // system common |
| 291 | 319 | switch (dev->xmit_in[0] & 0xf) |
| 292 | 320 | { |
| 293 | | case 0: // System Exclusive |
| 294 | | printf("No SEx please!\n"); |
| 321 | case 0: // System Exclusive is handled above |
| 295 | 322 | break; |
| 296 | 323 | |
| 297 | 324 | case 7: // End of System Exclusive |
| r20706 | r20707 | |
| 316 | 343 | |
| 317 | 344 | if (dev->xmit_cnt == bytes_needed) |
| 318 | 345 | { |
| 319 | | PmEvent ev; |
| 320 | 346 | ev.message = Pm_Message(dev->xmit_in[0], dev->xmit_in[1], dev->xmit_in[2]); |
| 321 | | ev.timestamp = 0; // use the current time |
| 322 | 347 | Pm_Write(dev->pmStream, &ev, 1); |
| 323 | 348 | dev->xmit_cnt = 0; |
| 324 | 349 | } |