3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005 - 2012 Christian Schoenebeck * |
* Copyright (C) 2005 - 2013 Christian Schoenebeck * |
7 |
* * |
* * |
8 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
9 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
82 |
{ |
{ |
83 |
this->pDevice = pDevice; |
this->pDevice = pDevice; |
84 |
this->portNumber = portNumber; |
this->portNumber = portNumber; |
85 |
|
runningStatusBuf[0] = 0; |
86 |
Parameters["NAME"] = new ParameterName(this); |
Parameters["NAME"] = new ParameterName(this); |
87 |
} |
} |
88 |
|
|
378 |
} |
} |
379 |
MidiChannelMapReader.Unlock(); |
MidiChannelMapReader.Unlock(); |
380 |
} |
} |
381 |
|
|
382 |
|
/** |
383 |
|
* Handles the so called MIDI "running status" mode, which allows devices |
384 |
|
* to reduce bandwidth (data reduction). |
385 |
|
* |
386 |
|
* If the passed in MIDI data is regular MIDI data, this method will simply |
387 |
|
* return the original data pointer and just stores the status byte for |
388 |
|
* potential "running status" event eventually coming next. |
389 |
|
* |
390 |
|
* If the passed in MIDI data however seems to be in "running status" mode, |
391 |
|
* this method will return another buffer, which allows the MIDI parser |
392 |
|
* to handle the MIDI data as usually with "normal" MIDI data. |
393 |
|
*/ |
394 |
|
uint8_t* MidiInputPort::handleRunningStatus(uint8_t* pData) { |
395 |
|
if ((pData[0] & 0x80) || !runningStatusBuf[0]) { |
396 |
|
// store status byte for eventual "running status" in next event |
397 |
|
if (pData[0] & 0x80) { |
398 |
|
if (pData[0] < 0xf0) { |
399 |
|
// "running status" is only allowed for channel messages |
400 |
|
runningStatusBuf[0] = pData[0]; |
401 |
|
} else if (pData[0] < 0xf8) { |
402 |
|
// "system common" messages (0xf0..0xf7) shall reset any running |
403 |
|
// status, however "realtime" messages (0xf8..0xff) shall be |
404 |
|
// ignored here |
405 |
|
runningStatusBuf[0] = 0; |
406 |
|
} |
407 |
|
} |
408 |
|
// it's either a regular status byte, or some invalid "running status" |
409 |
|
return pData; |
410 |
|
} else { // "running status" mode ... |
411 |
|
const uint8_t type = runningStatusBuf[0] & 0xf0; |
412 |
|
const int size = (type == 0xc0 || type == 0xd0) ? 1 : 2; // only program change & channel pressure have 1 data bytes |
413 |
|
memcpy(&runningStatusBuf[1], pData, size); |
414 |
|
return runningStatusBuf; |
415 |
|
} |
416 |
|
} |
417 |
|
|
418 |
void MidiInputPort::DispatchRaw(uint8_t* pData) { |
void MidiInputPort::DispatchRaw(uint8_t* pData) { |
419 |
|
pData = handleRunningStatus(pData); |
420 |
|
|
421 |
uint8_t channel = pData[0] & 0x0f; |
uint8_t channel = pData[0] & 0x0f; |
422 |
switch (pData[0] & 0xf0) { |
switch (pData[0] & 0xf0) { |
423 |
case 0x80: |
case 0x80: |
451 |
} |
} |
452 |
|
|
453 |
void MidiInputPort::DispatchRaw(uint8_t* pData, int32_t FragmentPos) { |
void MidiInputPort::DispatchRaw(uint8_t* pData, int32_t FragmentPos) { |
454 |
|
pData = handleRunningStatus(pData); |
455 |
|
|
456 |
uint8_t channel = pData[0] & 0x0f; |
uint8_t channel = pData[0] & 0x0f; |
457 |
switch (pData[0] & 0xf0) { |
switch (pData[0] & 0xf0) { |
458 |
case 0x80: |
case 0x80: |