Browse Source

Make sure midi channel is always set on output

tags/v1.9.9
falkTX 7 years ago
parent
commit
52f56ad468
9 changed files with 122 additions and 91 deletions
  1. +3
    -2
      source/backend/CarlaEngine.hpp
  2. +10
    -5
      source/backend/engine/CarlaEngineBridge.cpp
  3. +16
    -24
      source/backend/engine/CarlaEngineData.cpp
  4. +26
    -14
      source/backend/engine/CarlaEngineJack.cpp
  5. +7
    -6
      source/backend/engine/CarlaEngineNative.cpp
  6. +26
    -13
      source/backend/engine/CarlaEngineRtAudio.cpp
  7. +29
    -21
      source/bridges-plugin/CarlaBridgeSingleLV2.cpp
  8. +0
    -2
      source/utils/CarlaBinaryUtils.hpp
  9. +5
    -4
      source/utils/CarlaEngineUtils.hpp

+ 3
- 2
source/backend/CarlaEngine.hpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -169,8 +169,9 @@ struct CARLA_API EngineControlEvent {

/*!
* Convert this control event into MIDI data.
* Returns size.
*/
void convertToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept;
uint8_t convertToMidiData(const uint8_t channel, uint8_t data[3]) const noexcept;
};

/*!


+ 10
- 5
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -1251,9 +1251,8 @@ protected:

if (event.type == kEngineEventTypeControl)
{
uint8_t size;
uint8_t data[3];
event.ctrl.convertToMidiData(event.channel, size, data);
const uint8_t size = event.ctrl.convertToMidiData(event.channel, data);
CARLA_SAFE_ASSERT_CONTINUE(size > 0 && size <= 3);

if (curMidiDataPos + kBridgeBaseMidiOutHeaderSize + size >= kBridgeRtClientDataMidiOutSize)
@@ -1262,18 +1261,21 @@ protected:
// set time
*(uint32_t*)midiData = event.time;
midiData = midiData + 4;
curMidiDataPos += 4;

// set port
*midiData++ = 0;
++curMidiDataPos;

// set size
*midiData++ = size;
++curMidiDataPos;

// set data
for (uint8_t j=0; j<size; ++j)
*midiData++ = data[j];

curMidiDataPos += kBridgeBaseMidiOutHeaderSize + size;
curMidiDataPos += size;
}
else if (event.type == kEngineEventTypeMidi)
{
@@ -1287,12 +1289,15 @@ protected:
// set time
*(uint32_t*)midiData = event.time;
midiData += 4;
curMidiDataPos += 4;

// set port
*midiData++ = _midiEvent.port;
++curMidiDataPos;

// set size
*midiData++ = _midiEvent.size;
++curMidiDataPos;

// set data
*midiData++ = uint8_t(_midiData[0] | (event.channel & MIDI_CHANNEL_BIT));
@@ -1300,7 +1305,7 @@ protected:
for (uint8_t j=1; j<_midiEvent.size; ++j)
*midiData++ = _midiData[j];

curMidiDataPos += kBridgeBaseMidiOutHeaderSize + _midiEvent.size;
curMidiDataPos += _midiEvent.size;
}
}



+ 16
- 24
source/backend/engine/CarlaEngineData.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -24,61 +24,53 @@ CARLA_BACKEND_START_NAMESPACE
// -----------------------------------------------------------------------
// EngineControlEvent

void EngineControlEvent::convertToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept
uint8_t EngineControlEvent::convertToMidiData(const uint8_t channel, uint8_t data[3]) const noexcept
{
size = 0;

switch (type)
{
case kEngineControlEventTypeNull:
break;

case kEngineControlEventTypeParameter:
if (param >= MAX_MIDI_VALUE)
{
// out of bounds. do nothing
}
else if (MIDI_IS_CONTROL_BANK_SELECT(param))
CARLA_SAFE_ASSERT_RETURN(param >= MAX_MIDI_VALUE, 0);
data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
if (MIDI_IS_CONTROL_BANK_SELECT(param))
{
size = 3;
data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
data[1] = MIDI_CONTROL_BANK_SELECT;
data[2] = uint8_t(carla_fixedValue<float>(0.0f, float(MAX_MIDI_VALUE-1), value));
data[2] = uint8_t(carla_fixedValue<float>(0.0f, static_cast<float>(MAX_MIDI_VALUE-1), value));
}
else
{
size = 3;
data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
data[1] = static_cast<uint8_t>(param);
data[2] = uint8_t(carla_fixedValue<float>(0.0f, 1.0f, value) * float(MAX_MIDI_VALUE-1));
data[2] = uint8_t(carla_fixedValue<float>(0.0f, 1.0f, value) * static_cast<float>(MAX_MIDI_VALUE-1));
}
break;
return 3;

case kEngineControlEventTypeMidiBank:
size = 3;
data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
data[1] = MIDI_CONTROL_BANK_SELECT;
data[2] = uint8_t(carla_fixedValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
break;
return 3;

case kEngineControlEventTypeMidiProgram:
size = 2;
data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_BIT));
data[1] = uint8_t(carla_fixedValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
break;
return 2;

case kEngineControlEventTypeAllSoundOff:
size = 2;
data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
break;
return 2;

case kEngineControlEventTypeAllNotesOff:
size = 2;
data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
break;
return 2;
}

return 0;
}

// -----------------------------------------------------------------------


+ 26
- 14
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -380,11 +380,10 @@ public:
CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
}

uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };

EngineControlEvent ctrlEvent = { type, param, value };
ctrlEvent.convertToMidiData(channel, size, data);
const uint8_t size = ctrlEvent.convertToMidiData(channel, data);

if (size == 0)
return false;
@@ -1725,22 +1724,25 @@ protected:
{
jackbridge_midi_clear_buffer(eventOut);

uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };
const uint8_t* dataPtr = data;
uint8_t size = 0;
uint8_t mdata[3] = { 0, 0, 0 };
const uint8_t* mdataPtr = mdata;
uint8_t mdataTmp[EngineMidiEvent::kDataSize];

for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
{
const EngineEvent& engineEvent(pData->events.out[i]);

if (engineEvent.type == kEngineEventTypeNull)
/**/ if (engineEvent.type == kEngineEventTypeNull)
{
break;
}
else if (engineEvent.type == kEngineEventTypeControl)
{
const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
ctrlEvent.convertToMidiData(engineEvent.channel, size, data);
dataPtr = data;

size = ctrlEvent.convertToMidiData(engineEvent.channel, mdata);
mdataPtr = mdata;
}
else if (engineEvent.type == kEngineEventTypeMidi)
{
@@ -1748,10 +1750,20 @@ protected:

size = midiEvent.size;

if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
dataPtr = midiEvent.dataExt;
if (size > EngineMidiEvent::kDataSize)
{
CARLA_SAFE_ASSERT_CONTINUE(midiEvent.dataExt != nullptr);
mdataPtr = midiEvent.dataExt;
}
else
dataPtr = midiEvent.data;
{
// copy
carla_copy<uint8_t>(mdataTmp, midiEvent.data, size);
// add channel
mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
// done
mdataPtr = mdataTmp;
}
}
else
{
@@ -1759,7 +1771,7 @@ protected:
}

if (size > 0)
jackbridge_midi_event_write(eventOut, engineEvent.time, dataPtr, size);
jackbridge_midi_event_write(eventOut, engineEvent.time, mdataPtr, size);
}
}
}


+ 7
- 6
source/backend/engine/CarlaEngineNative.cpp View File

@@ -1571,33 +1571,34 @@ protected:
if (engineEvent.type == kEngineEventTypeNull)
break;

carla_zeroStruct(midiEvent);
midiEvent.time = engineEvent.time;

if (engineEvent.type == CarlaBackend::kEngineEventTypeControl)
/**/ if (engineEvent.type == kEngineEventTypeControl)
{
midiEvent.port = 0;
engineEvent.ctrl.convertToMidiData(engineEvent.channel, midiEvent.size, midiEvent.data);
midiEvent.size = engineEvent.ctrl.convertToMidiData(engineEvent.channel, midiEvent.data);
}
else if (engineEvent.type == kEngineEventTypeMidi)
{
if (engineEvent.midi.size > 4 || engineEvent.midi.dataExt != nullptr)
if (engineEvent.midi.size > 4)
continue;

midiEvent.port = engineEvent.midi.port;
midiEvent.size = engineEvent.midi.size;

midiEvent.data[0] = static_cast<uint8_t>(engineEvent.midi.data[0] + engineEvent.channel);
midiEvent.data[0] = static_cast<uint8_t>(engineEvent.midi.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));

for (uint8_t j=1; j < midiEvent.size; ++j)
midiEvent.data[j] = engineEvent.midi.data[j];
}
else
{
carla_stderr("Unknown event type...");
continue;
}

pHost->write_midi_event(pHost->handle, &midiEvent);
if (midiEvent.size > 0)
pHost->write_midi_event(pHost->handle, &midiEvent);
}
}
}


+ 26
- 13
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -173,7 +173,7 @@ public:
fMidiInEvents(),
fMidiOuts(),
fMidiOutMutex(),
fMidiOutVector(3)
fMidiOutVector(EngineMidiEvent::kDataSize)
{
carla_debug("CarlaEngineRtAudio::CarlaEngineRtAudio(%i)", api);

@@ -674,22 +674,25 @@ protected:

if (fMidiOuts.count() > 0)
{
uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };
const uint8_t* dataPtr = data;
uint8_t size = 0;
uint8_t mdata[3] = { 0, 0, 0 };
const uint8_t* mdataPtr = mdata;
uint8_t mdataTmp[EngineMidiEvent::kDataSize];

for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
{
const EngineEvent& engineEvent(pData->events.out[i]);

if (engineEvent.type == kEngineEventTypeNull)
/**/ if (engineEvent.type == kEngineEventTypeNull)
{
break;
}
else if (engineEvent.type == kEngineEventTypeControl)
{
const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
ctrlEvent.convertToMidiData(engineEvent.channel, size, data);
dataPtr = data;

size = ctrlEvent.convertToMidiData(engineEvent.channel, mdata);
mdataPtr = mdata;
}
else if (engineEvent.type == kEngineEventTypeMidi)
{
@@ -697,10 +700,20 @@ protected:

size = midiEvent.size;

if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
dataPtr = midiEvent.dataExt;
if (size > EngineMidiEvent::kDataSize)
{
CARLA_SAFE_ASSERT_CONTINUE(midiEvent.dataExt != nullptr);
mdataPtr = midiEvent.dataExt;
}
else
dataPtr = midiEvent.data;
{
// copy
carla_copy<uint8_t>(mdataTmp, midiEvent.data, size);
// add channel
mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
// done
mdataPtr = mdataTmp;
}
}
else
{
@@ -709,7 +722,7 @@ protected:

if (size > 0)
{
fMidiOutVector.assign(dataPtr, dataPtr + size);
fMidiOutVector.assign(mdataPtr, mdataPtr + size);

for (LinkedList<MidiOutPort>::Itenerator it=fMidiOuts.begin2(); it.valid(); it.next())
{


+ 29
- 21
source/bridges-plugin/CarlaBridgeSingleLV2.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla LV2 Single Plugin
* Copyright (C) 2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2017-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -197,43 +197,51 @@ public:

if (fPorts.numMidiOuts > 0)
{
uint8_t port = 0;
uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };
const uint8_t* dataPtr = data;
uint8_t port = 0;
uint8_t size = 0;
uint8_t mdata[3] = { 0, 0, 0 };
const uint8_t* mdataPtr = mdata;
uint8_t mdataTmp[EngineMidiEvent::kDataSize];

for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
{
const EngineEvent& engineEvent(pData->events.out[i]);

switch (engineEvent.type)
/**/ if (engineEvent.type == kEngineEventTypeNull)
{
case kEngineEventTypeNull:
break;

case kEngineEventTypeControl: {
const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
ctrlEvent.convertToMidiData(engineEvent.channel, size, data);
dataPtr = data;
break;
}
else if (engineEvent.type == kEngineEventTypeControl)
{
const EngineControlEvent& ctrlEvent(engineEvent.ctrl);

case kEngineEventTypeMidi: {
size = ctrlEvent.convertToMidiData(engineEvent.channel, mdata);
mdataPtr = mdata;
}
else if (engineEvent.type == kEngineEventTypeMidi)
{
const EngineMidiEvent& midiEvent(engineEvent.midi);

port = midiEvent.port;
size = midiEvent.size;

if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
dataPtr = midiEvent.dataExt;
if (size > EngineMidiEvent::kDataSize)
{
CARLA_SAFE_ASSERT_CONTINUE(midiEvent.dataExt != nullptr);
mdataPtr = midiEvent.dataExt;
}
else
dataPtr = midiEvent.data;

break;
}
{
// copy
carla_copy<uint8_t>(mdataTmp, midiEvent.data, size);
// add channel
mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
// done
mdataPtr = mdataTmp;
}
}

if (size > 0 && ! writeMidiEvent(port, engineEvent.time, size, dataPtr))
if (size > 0 && ! writeMidiEvent(port, engineEvent.time, size, mdataPtr))
break;
}
}


+ 0
- 2
source/utils/CarlaBinaryUtils.hpp View File

@@ -142,8 +142,6 @@ BinaryType getBinaryTypeFromFile(const char* const filename)
default:
return BINARY_NATIVE;
}

return BINARY_NATIVE;
}

// --------------------------------------------------------------------------------------------------------------------


+ 5
- 4
source/utils/CarlaEngineUtils.hpp View File

@@ -1,6 +1,6 @@
/*
* Carla Engine utils
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -160,7 +160,7 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En
{
const EngineEvent& engineEvent(engineEvents[i]);

if (engineEvent.type == kEngineEventTypeNull)
/**/ if (engineEvent.type == kEngineEventTypeNull)
{
break;
}
@@ -168,7 +168,7 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En
{
const EngineControlEvent& ctrlEvent(engineEvent.ctrl);

ctrlEvent.convertToMidiData(engineEvent.channel, size, mdata);
size = ctrlEvent.convertToMidiData(engineEvent.channel, mdata);
mdataPtr = mdata;
}
else if (engineEvent.type == kEngineEventTypeMidi)
@@ -177,8 +177,9 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En

size = midiEvent.size;

if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
if (size > EngineMidiEvent::kDataSize)
{
CARLA_SAFE_ASSERT_CONTINUE(midiEvent.dataExt != nullptr);
mdataPtr = midiEvent.dataExt;
}
else


Loading…
Cancel
Save