@@ -1136,20 +1136,6 @@ typedef struct { | |||
*/ | |||
uint8_t midiChannel; | |||
#ifdef __cplusplus | |||
/*! | |||
* Clear data. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
type = PARAMETER_UNKNOWN; | |||
hints = 0x0; | |||
index = PARAMETER_NULL; | |||
rindex = -1; | |||
midiCC =-1; | |||
midiChannel = 0; | |||
} | |||
#endif | |||
} ParameterData; | |||
/*! | |||
@@ -1187,19 +1173,6 @@ typedef struct { | |||
float stepLarge; | |||
#ifdef __cplusplus | |||
/*! | |||
* Clear data. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
def = 0.0f; | |||
min = 0.0f; | |||
max = 1.0f; | |||
step = 0.01f; | |||
stepSmall = 0.0001f; | |||
stepLarge = 0.1f; | |||
} | |||
/*! | |||
* Fix default value within range. | |||
*/ | |||
@@ -1294,17 +1267,6 @@ typedef struct { | |||
*/ | |||
const char* name; | |||
#ifdef __cplusplus | |||
/*! | |||
* Clear data. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
bank = 0; | |||
program = 0; | |||
name = nullptr; | |||
} | |||
#endif | |||
} MidiProgramData; | |||
/*! | |||
@@ -1328,17 +1290,6 @@ typedef struct { | |||
*/ | |||
const char* value; | |||
#ifdef __cplusplus | |||
/*! | |||
* Clear data. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
type = nullptr; | |||
key = nullptr; | |||
value = nullptr; | |||
} | |||
#endif | |||
} CustomData; | |||
/*! | |||
@@ -167,39 +167,25 @@ struct EngineControlEvent { | |||
EngineControlEventType type; //!< Control-Event type. | |||
uint16_t param; //!< Parameter Id, midi bank or midi program. | |||
float value; //!< Parameter value, normalized to 0.0f<->1.0f. | |||
/*! | |||
* Clear data. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
type = kEngineControlEventTypeNull; | |||
param = 0; | |||
value = 0.0f; | |||
} | |||
}; | |||
/*! | |||
* Engine MIDI event. | |||
*/ | |||
struct EngineMidiEvent { | |||
static const uint8_t kDataSize = 4; //!< Size of data | |||
static const uint8_t kDataSize = 4; //!< Size of internal data | |||
uint8_t port; //!< Port offset (usually 0) | |||
uint8_t size; //!< Number of bytes used | |||
uint8_t data[kDataSize]; //!< MIDI data, without channel bit | |||
uint8_t port; //!< Port offset (usually 0) | |||
uint8_t size; //!< Number of bytes used | |||
/*! | |||
* Clear data. | |||
* MIDI data, without channel bit. | |||
* If size > kDataSize, dataExt is used. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
port = 0; | |||
size = 0; | |||
for (uint8_t i=0; i < kDataSize; ++i) | |||
data[i] = 0; | |||
} | |||
union { | |||
uint8_t data[kDataSize]; | |||
uint8_t* dataExt; | |||
}; | |||
}; | |||
/*! | |||
@@ -218,15 +204,7 @@ struct EngineEvent { | |||
EngineMidiEvent midi; | |||
}; | |||
/*! | |||
* Clear data. | |||
*/ | |||
void clear() noexcept | |||
{ | |||
type = kEngineEventTypeNull; | |||
time = 0; | |||
channel = 0; | |||
} | |||
void fillFromMidiData(const uint8_t size, uint8_t* const data); | |||
}; | |||
/*! | |||
@@ -313,14 +313,6 @@ typedef struct _CarlaPortCountInfo { | |||
*/ | |||
uint32_t outs; | |||
#ifdef __cplusplus | |||
/*! | |||
* C++ constructor. | |||
*/ | |||
_CarlaPortCountInfo() noexcept | |||
: ins(0), | |||
outs(0) {} | |||
#endif | |||
} CarlaPortCountInfo; | |||
/*! | |||
@@ -50,7 +50,102 @@ CARLA_BACKEND_START_NAMESPACE | |||
// ----------------------------------------------------------------------- | |||
// Fallback data | |||
static EngineEvent kFallbackEngineEvent; | |||
static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } }; | |||
// ----------------------------------------------------------------------- | |||
void EngineEvent::fillFromMidiData(const uint8_t size, uint8_t* const data) | |||
{ | |||
// get channel | |||
channel = MIDI_GET_CHANNEL_FROM_DATA(data); | |||
// get status | |||
const uint8_t midiStatus(MIDI_GET_STATUS_FROM_DATA(data)); | |||
// remove channel bit from data | |||
data[0] = midiStatus; | |||
if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||
{ | |||
type = kEngineEventTypeControl; | |||
const uint8_t midiControl(data[1]); | |||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||
{ | |||
CARLA_SAFE_ASSERT_INT(size == 3, size); | |||
const uint8_t midiBank(data[2]); | |||
ctrl.type = kEngineControlEventTypeMidiBank; | |||
ctrl.param = midiBank; | |||
ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||
{ | |||
CARLA_SAFE_ASSERT_INT(size == 2, size); | |||
ctrl.type = kEngineControlEventTypeAllSoundOff; | |||
ctrl.param = 0; | |||
ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
CARLA_SAFE_ASSERT_INT(size == 2, size); | |||
ctrl.type = kEngineControlEventTypeAllNotesOff; | |||
ctrl.param = 0; | |||
ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl); | |||
const uint8_t midiValue(data[2]); | |||
ctrl.type = kEngineControlEventTypeParameter; | |||
ctrl.param = midiControl; | |||
ctrl.value = float(midiValue)/127.0f; | |||
} | |||
} | |||
else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||
{ | |||
CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]); | |||
type = kEngineEventTypeControl; | |||
const uint8_t midiProgram(data[1]); | |||
ctrl.type = kEngineControlEventTypeMidiProgram; | |||
ctrl.param = midiProgram; | |||
ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
type = kEngineEventTypeMidi; | |||
midi.port = 0; | |||
midi.size = size; | |||
if (size > EngineMidiEvent::kDataSize) | |||
{ | |||
midi.dataExt = data; | |||
std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize); | |||
} | |||
else | |||
{ | |||
midi.data[0] = midiStatus; | |||
uint8_t i=1; | |||
for (; i < midi.size; ++i) | |||
midi.data[i] = data[i]; | |||
for (; i < EngineMidiEvent::kDataSize; ++i) | |||
midi.data[i] = 0; | |||
midi.dataExt = nullptr; | |||
} | |||
} | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Carla Engine port (Abstract) | |||
@@ -144,14 +239,6 @@ CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool | |||
{ | |||
carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); | |||
static bool sFallbackEngineEventNeedsInit = true; | |||
if (sFallbackEngineEventNeedsInit) | |||
{ | |||
kFallbackEngineEvent.clear(); | |||
sFallbackEngineEventNeedsInit = false; | |||
} | |||
if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
fBuffer = new EngineEvent[kEngineMaxInternalEventCount]; | |||
} | |||
@@ -272,8 +359,11 @@ bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||
event.midi.data[0] = MIDI_GET_STATUS_FROM_DATA(data); | |||
for (uint8_t j=1; j < size; ++j) | |||
uint8_t j=1; | |||
for (; j < size; ++j) | |||
event.midi.data[j] = data[j]; | |||
for (; j < EngineMidiEvent::kDataSize; ++j) | |||
event.midi.data[j] = 0; | |||
return true; | |||
} | |||
@@ -43,7 +43,7 @@ class CarlaEngineJack; | |||
// ----------------------------------------------------------------------- | |||
// Fallback data | |||
static EngineEvent kFallbackJackEngineEvent; | |||
static const EngineEvent kFallbackJackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } }; | |||
// ----------------------------------------------------------------------- | |||
// Carla Engine JACK-Audio port | |||
@@ -185,14 +185,6 @@ public: | |||
{ | |||
carla_debug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %p, %p)", bool2str(isInput), client, port); | |||
static bool sFallbackJackEngineEventNeedsInit = true; | |||
if (sFallbackJackEngineEventNeedsInit) | |||
{ | |||
kFallbackJackEngineEvent.clear(); | |||
sFallbackJackEngineEventNeedsInit = false; | |||
} | |||
if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) | |||
{ | |||
CARLA_ASSERT(client != nullptr && port != nullptr); | |||
@@ -256,86 +248,8 @@ public: | |||
if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) | |||
return kFallbackJackEngineEvent; | |||
CARLA_SAFE_ASSERT_RETURN(jackEvent.size > 0 && jackEvent.size <= EngineMidiEvent::kDataSize, kFallbackJackEngineEvent); | |||
//if (jackEvent.size == 0 || jackEvent.size > EngineMidiEvent::kDataSize) | |||
// return kFallbackJackEngineEvent; | |||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer); | |||
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer); | |||
fRetEvent.time = jackEvent.time; | |||
fRetEvent.channel = midiChannel; | |||
if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||
{ | |||
fRetEvent.type = kEngineEventTypeControl; | |||
const uint8_t midiControl = jackEvent.buffer[1]; | |||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||
{ | |||
CARLA_SAFE_ASSERT_INT(jackEvent.size == 3, jackEvent.size); | |||
const uint8_t midiBank = jackEvent.buffer[2]; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank; | |||
fRetEvent.ctrl.param = midiBank; | |||
fRetEvent.ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||
{ | |||
CARLA_SAFE_ASSERT_INT(jackEvent.size == 2, jackEvent.size); | |||
fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | |||
fRetEvent.ctrl.param = 0; | |||
fRetEvent.ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
CARLA_SAFE_ASSERT_INT(jackEvent.size == 2, jackEvent.size); | |||
fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | |||
fRetEvent.ctrl.param = 0; | |||
fRetEvent.ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
CARLA_SAFE_ASSERT_INT2(jackEvent.size == 3, jackEvent.size, midiControl); | |||
const uint8_t midiValue = jackEvent.buffer[2]; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeParameter; | |||
fRetEvent.ctrl.param = midiControl; | |||
fRetEvent.ctrl.value = float(midiValue)/127.0f; | |||
} | |||
} | |||
else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||
{ | |||
CARLA_SAFE_ASSERT_INT2(jackEvent.size == 2, jackEvent.size, jackEvent.buffer[1]); | |||
fRetEvent.type = kEngineEventTypeControl; | |||
const uint8_t midiProgram = jackEvent.buffer[1]; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | |||
fRetEvent.ctrl.param = midiProgram; | |||
fRetEvent.ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
fRetEvent.type = kEngineEventTypeMidi; | |||
fRetEvent.midi.port = 0; | |||
fRetEvent.midi.size = static_cast<uint8_t>(jackEvent.size); | |||
fRetEvent.midi.data[0] = midiStatus; | |||
uint8_t i=1; | |||
for (; i < fRetEvent.midi.size; ++i) | |||
fRetEvent.midi.data[i] = jackEvent.buffer[i]; | |||
for (; i < EngineMidiEvent::kDataSize; ++i) | |||
fRetEvent.midi.data[i] = 0; | |||
} | |||
fRetEvent.time = jackEvent.time; | |||
fRetEvent.fillFromMidiData(jackEvent.size, jackEvent.buffer); | |||
return fRetEvent; | |||
} | |||
@@ -415,7 +329,6 @@ public: | |||
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | |||
jack_midi_data_t jdata[size]; | |||
std::memset(jdata, 0, sizeof(jack_midi_data_t)*size); | |||
jdata[0] = MIDI_GET_STATUS_FROM_DATA(data); | |||
jdata[0] += channel; | |||
@@ -1259,74 +1172,10 @@ protected: | |||
if (! jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex)) | |||
continue; | |||
EngineEvent* const engineEvent(&pData->bufEvents.in[engineEventIndex++]); | |||
engineEvent->clear(); | |||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer); | |||
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer); | |||
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]); | |||
engineEvent->time = jackEvent.time; | |||
engineEvent->channel = midiChannel; | |||
if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) | |||
{ | |||
CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | |||
const uint8_t midiControl = jackEvent.buffer[1]; | |||
engineEvent->type = kEngineEventTypeControl; | |||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||
{ | |||
const uint8_t midiBank = jackEvent.buffer[2]; | |||
engineEvent->ctrl.type = kEngineControlEventTypeMidiBank; | |||
engineEvent->ctrl.param = midiBank; | |||
engineEvent->ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||
{ | |||
engineEvent->ctrl.type = kEngineControlEventTypeAllSoundOff; | |||
engineEvent->ctrl.param = 0; | |||
engineEvent->ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
engineEvent->ctrl.type = kEngineControlEventTypeAllNotesOff; | |||
engineEvent->ctrl.param = 0; | |||
engineEvent->ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
CARLA_ASSERT(jackEvent.size == 3); | |||
const uint8_t midiValue = jackEvent.buffer[2]; | |||
engineEvent->ctrl.type = kEngineControlEventTypeParameter; | |||
engineEvent->ctrl.param = midiControl; | |||
engineEvent->ctrl.value = float(midiValue)/127.0f; | |||
} | |||
} | |||
else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) | |||
{ | |||
CARLA_ASSERT(jackEvent.size == 2); | |||
const uint8_t midiProgram = jackEvent.buffer[1]; | |||
engineEvent->type = kEngineEventTypeControl; | |||
engineEvent->ctrl.type = kEngineControlEventTypeMidiProgram; | |||
engineEvent->ctrl.param = midiProgram; | |||
engineEvent->ctrl.value = 0.0f; | |||
} | |||
else if (jackEvent.size <= 4) | |||
{ | |||
engineEvent->type = kEngineEventTypeMidi; | |||
engineEvent->midi.data[0] = midiStatus; | |||
engineEvent->midi.size = static_cast<uint8_t>(jackEvent.size); | |||
if (jackEvent.size > 1) | |||
carla_copy<uint8_t>(engineEvent->midi.data+1, jackEvent.buffer+1, jackEvent.size-1); | |||
} | |||
engineEvent.time = jackEvent.time; | |||
engineEvent.fillFromMidiData(jackEvent.size, jackEvent.buffer); | |||
if (engineEventIndex >= kEngineMaxInternalEventCount) | |||
break; | |||
@@ -1342,58 +1191,61 @@ protected: | |||
for (unsigned short i=0; i < kEngineMaxInternalEventCount; ++i) | |||
{ | |||
EngineEvent* const engineEvent = &pData->bufEvents.out[i]; | |||
const EngineEvent& engineEvent(pData->bufEvents.out[i]); | |||
uint8_t data[3] = { 0 }; | |||
uint8_t size = 0; | |||
uint8_t size = 0; | |||
uint8_t data[3] = { 0, 0, 0 }; | |||
uint8_t* dataPtr = data; | |||
switch (engineEvent->type) | |||
switch (engineEvent.type) | |||
{ | |||
case kEngineEventTypeNull: | |||
break; | |||
case kEngineEventTypeControl: | |||
{ | |||
EngineControlEvent* const ctrlEvent = &engineEvent->ctrl; | |||
const EngineControlEvent& ctrlEvent(engineEvent.ctrl); | |||
if (ctrlEvent->type == kEngineControlEventTypeParameter && MIDI_IS_CONTROL_BANK_SELECT(ctrlEvent->param)) | |||
{ | |||
// FIXME? | |||
ctrlEvent->type = kEngineControlEventTypeMidiBank; | |||
ctrlEvent->param = ctrlEvent->value; | |||
ctrlEvent->value = 0.0f; | |||
} | |||
switch (ctrlEvent->type) | |||
switch (ctrlEvent.type) | |||
{ | |||
case kEngineControlEventTypeNull: | |||
break; | |||
case kEngineControlEventTypeParameter: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||
data[1] = static_cast<uint8_t>(ctrlEvent->param); | |||
data[2] = uint8_t(ctrlEvent->value * 127.0f); | |||
size = 3; | |||
if (MIDI_IS_CONTROL_BANK_SELECT(ctrlEvent.param)) | |||
{ | |||
size = 3; | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||
data[2] = static_cast<uint8_t>(ctrlEvent.value); | |||
} | |||
else | |||
{ | |||
size = 3; | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||
data[1] = static_cast<uint8_t>(ctrlEvent.param); | |||
data[2] = uint8_t(ctrlEvent.value * 127.0f); | |||
} | |||
break; | |||
case kEngineControlEventTypeMidiBank: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||
data[2] = static_cast<uint8_t>(ctrlEvent->param); | |||
size = 3; | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||
data[2] = static_cast<uint8_t>(ctrlEvent.param); | |||
break; | |||
case kEngineControlEventTypeMidiProgram: | |||
data[0] = MIDI_STATUS_PROGRAM_CHANGE + engineEvent->channel; | |||
data[1] = static_cast<uint8_t>(ctrlEvent->param); | |||
size = 2; | |||
data[0] = MIDI_STATUS_PROGRAM_CHANGE + engineEvent.channel; | |||
data[1] = static_cast<uint8_t>(ctrlEvent.param); | |||
break; | |||
case kEngineControlEventTypeAllSoundOff: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||
data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
size = 2; | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||
data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
break; | |||
case kEngineControlEventTypeAllNotesOff: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel; | |||
data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
size = 2; | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent.channel; | |||
data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
break; | |||
} | |||
break; | |||
@@ -1401,18 +1253,21 @@ protected: | |||
case kEngineEventTypeMidi: | |||
{ | |||
EngineMidiEvent* const midiEvent = &engineEvent->midi; | |||
const EngineMidiEvent& midiEvent(engineEvent.midi); | |||
size = midiEvent.size; | |||
if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr) | |||
dataPtr = midiEvent.dataExt; | |||
else | |||
dataPtr = midiEvent.dataExt; | |||
data[0] = midiEvent->data[0]; | |||
data[1] = midiEvent->data[1]; | |||
data[2] = midiEvent->data[2]; | |||
size = midiEvent->size; | |||
break; | |||
} | |||
} | |||
if (size > 0) | |||
jackbridge_midi_event_write(eventOut, engineEvent->time, data, size); | |||
jackbridge_midi_event_write(eventOut, engineEvent.time, dataPtr, size); | |||
} | |||
} | |||
@@ -887,15 +887,8 @@ protected: | |||
while (! fMidiInEvents.data.isEmpty()) | |||
{ | |||
const RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true)); | |||
RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true)); | |||
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(midiEvent.data); | |||
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(midiEvent.data); | |||
engineEvent.channel = midiChannel; | |||
if (midiEvent.time < pData->timeInfo.frame) | |||
{ | |||
@@ -909,59 +902,7 @@ protected: | |||
else | |||
engineEvent.time = midiEvent.time - pData->timeInfo.frame; | |||
if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) | |||
{ | |||
const uint8_t midiControl = midiEvent.data[1]; | |||
engineEvent.type = kEngineEventTypeControl; | |||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||
{ | |||
const uint8_t midiBank = midiEvent.data[2]; | |||
engineEvent.ctrl.type = kEngineControlEventTypeMidiBank; | |||
engineEvent.ctrl.param = midiBank; | |||
engineEvent.ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||
{ | |||
engineEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | |||
engineEvent.ctrl.param = 0; | |||
engineEvent.ctrl.value = 0.0f; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
engineEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | |||
engineEvent.ctrl.param = 0; | |||
engineEvent.ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
const uint8_t midiValue = midiEvent.data[2]; | |||
engineEvent.ctrl.type = kEngineControlEventTypeParameter; | |||
engineEvent.ctrl.param = midiControl; | |||
engineEvent.ctrl.value = float(midiValue)/127.0f; | |||
} | |||
} | |||
else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus)) | |||
{ | |||
const uint8_t midiProgram = midiEvent.data[1]; | |||
engineEvent.type = kEngineEventTypeControl; | |||
engineEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | |||
engineEvent.ctrl.param = midiProgram; | |||
engineEvent.ctrl.value = 0.0f; | |||
} | |||
else | |||
{ | |||
engineEvent.type = kEngineEventTypeMidi; | |||
engineEvent.midi.data[0] = midiStatus; | |||
engineEvent.midi.data[1] = midiEvent.data[1]; | |||
engineEvent.midi.data[2] = midiEvent.data[2]; | |||
engineEvent.midi.data[3] = midiEvent.data[3]; | |||
engineEvent.midi.size = midiEvent.size; | |||
} | |||
engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data); | |||
if (engineEventIndex >= kEngineMaxInternalEventCount) | |||
break; | |||
@@ -1124,7 +1065,7 @@ protected: | |||
const size_t messageSize = message->size(); | |||
static uint32_t lastTime = 0; | |||
if (messageSize == 0 || messageSize > 4) | |||
if (messageSize == 0 || messageSize > EngineMidiEvent::kDataSize) | |||
return; | |||
timeStamp /= 2; | |||
@@ -1142,38 +1083,13 @@ protected: | |||
else | |||
lastTime = midiEvent.time; | |||
if (messageSize == 1) | |||
{ | |||
midiEvent.data[0] = message->at(0); | |||
midiEvent.data[1] = 0; | |||
midiEvent.data[2] = 0; | |||
midiEvent.data[3] = 0; | |||
midiEvent.size = 1; | |||
} | |||
else if (messageSize == 2) | |||
{ | |||
midiEvent.data[0] = message->at(0); | |||
midiEvent.data[1] = message->at(1); | |||
midiEvent.data[2] = 0; | |||
midiEvent.data[3] = 0; | |||
midiEvent.size = 2; | |||
} | |||
else if (messageSize == 3) | |||
{ | |||
midiEvent.data[0] = message->at(0); | |||
midiEvent.data[1] = message->at(1); | |||
midiEvent.data[2] = message->at(2); | |||
midiEvent.data[3] = 0; | |||
midiEvent.size = 3; | |||
} | |||
else | |||
{ | |||
midiEvent.data[0] = message->at(0); | |||
midiEvent.data[1] = message->at(1); | |||
midiEvent.data[2] = message->at(2); | |||
midiEvent.data[3] = message->at(3); | |||
midiEvent.size = 4; | |||
} | |||
midiEvent.size = messageSize; | |||
size_t i=0; | |||
for (; i < messageSize; ++i) | |||
midiEvent.data[i] = message->at(i); | |||
for (; i < EngineMidiEvent::kDataSize; ++i) | |||
midiEvent.data[i] = 0; | |||
fMidiInEvents.append(midiEvent); | |||
} | |||
@@ -1337,8 +1253,8 @@ private: | |||
struct RtMidiEvent { | |||
uint32_t time; | |||
unsigned char data[4]; | |||
unsigned char size; | |||
uint8_t size; | |||
uint8_t data[EngineMidiEvent::kDataSize]; | |||
}; | |||
struct RtMidiEvents { | |||
@@ -29,10 +29,10 @@ CARLA_BACKEND_START_NAMESPACE | |||
// ------------------------------------------------------------------- | |||
// Fallback data | |||
static ParameterData kParameterDataNull; | |||
static ParameterRanges kParameterRangesNull; | |||
static MidiProgramData kMidiProgramDataNull; | |||
static CustomData kCustomDataNull; | |||
static const ParameterData kParameterDataNull = { PARAMETER_UNKNOWN, 0x0, PARAMETER_NULL, -1, -1, 0 }; | |||
static const ParameterRanges kParameterRangesNull = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f }; | |||
static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr }; | |||
static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr }; | |||
static bool gIsLoadingProject = false; | |||
@@ -229,17 +229,6 @@ CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id) | |||
CARLA_ASSERT(id == engine->getCurrentPluginCount()); | |||
carla_debug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id); | |||
static bool sFallbackDataNeedsInit = true; | |||
if (sFallbackDataNeedsInit) | |||
{ | |||
kParameterDataNull.clear(); | |||
kParameterRangesNull.clear(); | |||
kMidiProgramDataNull.clear(); | |||
kCustomDataNull.clear(); | |||
sFallbackDataNeedsInit = false; | |||
} | |||
switch (engine->getProccessMode()) | |||
{ | |||
case ENGINE_PROCESS_MODE_SINGLE_CLIENT: | |||
@@ -1240,9 +1240,9 @@ const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterI | |||
{ | |||
carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId); | |||
static ParameterData fallbackParamData; | |||
static const ParameterData fallbackParameterData = { CB::PARAMETER_UNKNOWN, 0x0, CB::PARAMETER_NULL, -1, -1, 0 }; | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamData); | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParameterData); | |||
if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId)) | |||
{ | |||
@@ -1250,18 +1250,18 @@ const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterI | |||
return &plugin->getParameterData(parameterId); | |||
carla_stderr2("carla_get_parameter_data(%i, %i) - parameterId out of bounds", pluginId, parameterId); | |||
return &fallbackParamData; | |||
return &fallbackParameterData; | |||
} | |||
carla_stderr2("carla_get_parameter_data(%i, %i) - could not find plugin", pluginId, parameterId); | |||
return &fallbackParamData; | |||
return &fallbackParameterData; | |||
} | |||
const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId) | |||
{ | |||
carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId); | |||
static ParameterRanges fallbackParamRanges; | |||
static const ParameterRanges fallbackParamRanges = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f }; | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamRanges); | |||
@@ -1282,7 +1282,7 @@ const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiP | |||
{ | |||
carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId); | |||
static MidiProgramData fallbackMidiProgData; | |||
static const MidiProgramData fallbackMidiProgData = { 0, 0, nullptr }; | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackMidiProgData); | |||
@@ -1303,7 +1303,7 @@ const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId) | |||
{ | |||
carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId); | |||
static CustomData fallbackCustomData; | |||
static const CustomData fallbackCustomData = { nullptr, nullptr, nullptr }; | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackCustomData); | |||