Browse Source

Make the bridge ringbuffer work atomic; Fix bridge MIDI

tags/1.9.4
falkTX 11 years ago
parent
commit
5d5dd0cd2d
3 changed files with 58 additions and 53 deletions
  1. +1
    -2
      source/backend/engine/CarlaEngineBridge.cpp
  2. +55
    -49
      source/backend/plugin/BridgePlugin.cpp
  3. +2
    -2
      source/utils/CarlaRingBuffer.hpp

+ 1
- 2
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -285,8 +285,7 @@ public:
{ {
const PluginBridgeOpcode opcode(fShmControl.readOpcode()); const PluginBridgeOpcode opcode(fShmControl.readOpcode());


if (opcode != kPluginBridgeOpcodeProcess)
{
if (opcode != kPluginBridgeOpcodeProcess) {
carla_debug("CarlaEngineBridge::run() - got opcode: %s", PluginBridgeOpcode2str(opcode)); carla_debug("CarlaEngineBridge::run() - got opcode: %s", PluginBridgeOpcode2str(opcode));
} }




+ 55
- 49
source/backend/plugin/BridgePlugin.cpp View File

@@ -146,6 +146,7 @@ struct BridgeAudioPool {


struct BridgeControl : public RingBufferControl<StackRingBuffer> { struct BridgeControl : public RingBufferControl<StackRingBuffer> {
CarlaString filename; CarlaString filename;
CarlaCriticalSection lock;
BridgeShmControl* data; BridgeShmControl* data;
shm_t shm; shm_t shm;


@@ -456,20 +457,12 @@ public:
const float fixedValue(pData->param.getFixedValue(parameterId, value)); const float fixedValue(pData->param.getFixedValue(parameterId, value));
fParams[parameterId].value = fixedValue; fParams[parameterId].value = fixedValue;


const bool doLock(sendGui || sendOsc || sendCallback);

if (doLock)
pData->singleMutex.lock();
const CarlaCriticalSection::Scope _cs(fShmControl.lock);


fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter); fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
fShmControl.writeInt(static_cast<int32_t>(parameterId)); fShmControl.writeInt(static_cast<int32_t>(parameterId));
fShmControl.writeFloat(value); fShmControl.writeFloat(value);

if (doLock)
{
fShmControl.commitWrite();
pData->singleMutex.unlock();
}
fShmControl.commitWrite();


CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback); CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
} }
@@ -478,19 +471,11 @@ public:
{ {
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),); CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);


const bool doLock(sendGui || sendOsc || sendCallback);

if (doLock)
pData->singleMutex.lock();
const CarlaCriticalSection::Scope _cs(fShmControl.lock);


fShmControl.writeOpcode(kPluginBridgeOpcodeSetProgram); fShmControl.writeOpcode(kPluginBridgeOpcodeSetProgram);
fShmControl.writeInt(index); fShmControl.writeInt(index);

if (doLock)
{
fShmControl.commitWrite();
pData->singleMutex.unlock();
}
fShmControl.commitWrite();


CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback); CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback);
} }
@@ -499,19 +484,11 @@ public:
{ {
CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),); CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);


const bool doLock(sendGui || sendOsc || sendCallback);

if (doLock)
pData->singleMutex.lock();
const CarlaCriticalSection::Scope _cs(fShmControl.lock);


fShmControl.writeOpcode(kPluginBridgeOpcodeSetMidiProgram); fShmControl.writeOpcode(kPluginBridgeOpcodeSetMidiProgram);
fShmControl.writeInt(index); fShmControl.writeInt(index);

if (doLock)
{
fShmControl.commitWrite();
pData->singleMutex.unlock();
}
fShmControl.commitWrite();


CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
} }
@@ -728,11 +705,14 @@ public:


void activate() noexcept override void activate() noexcept override
{ {
// already locked before
fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
fShmControl.writeInt(PARAMETER_ACTIVE);
fShmControl.writeFloat(1.0f);
fShmControl.commitWrite();
{
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
fShmControl.writeInt(PARAMETER_ACTIVE);
fShmControl.writeFloat(1.0f);
fShmControl.commitWrite();
}


bool timedOut = true; bool timedOut = true;


@@ -746,11 +726,14 @@ public:


void deactivate() noexcept override void deactivate() noexcept override
{ {
// already locked before
fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
fShmControl.writeInt(PARAMETER_ACTIVE);
fShmControl.writeFloat(0.0f);
fShmControl.commitWrite();
{
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameter);
fShmControl.writeInt(PARAMETER_ACTIVE);
fShmControl.writeFloat(0.0f);
fShmControl.commitWrite();
}


bool timedOut = true; bool timedOut = true;


@@ -806,12 +789,15 @@ public:
data2 = static_cast<char>(note.note); data2 = static_cast<char>(note.note);
data3 = static_cast<char>(note.velo); data3 = static_cast<char>(note.velo);


const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
fShmControl.writeLong(0); fShmControl.writeLong(0);
fShmControl.writeInt(3); fShmControl.writeInt(3);
fShmControl.writeChar(data1); fShmControl.writeChar(data1);
fShmControl.writeChar(data2); fShmControl.writeChar(data2);
fShmControl.writeChar(data3); fShmControl.writeChar(data3);
fShmControl.commitWrite();
} }


pData->extNotes.mutex.unlock(); pData->extNotes.mutex.unlock();
@@ -939,12 +925,15 @@ public:


if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F) if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
{ {
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent); fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
fShmControl.writeLong(event.time); fShmControl.writeLong(event.time);
fShmControl.writeInt(3); fShmControl.writeInt(3);
fShmControl.writeChar(static_cast<char>(MIDI_STATUS_CONTROL_CHANGE + event.channel)); fShmControl.writeChar(static_cast<char>(MIDI_STATUS_CONTROL_CHANGE + event.channel));
fShmControl.writeChar(static_cast<char>(ctrlEvent.param)); fShmControl.writeChar(static_cast<char>(ctrlEvent.param));
fShmControl.writeChar(char(ctrlEvent.value*127.0f)); fShmControl.writeChar(char(ctrlEvent.value*127.0f));
fShmControl.commitWrite();
} }


break; break;
@@ -1006,6 +995,9 @@ public:
{ {
const EngineMidiEvent& midiEvent(event.midi); const EngineMidiEvent& midiEvent(event.midi);


if (midiEvent.size == 0 || midiEvent.size > 4)
continue;

uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data)); uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
uint8_t channel = event.channel; uint8_t channel = event.channel;


@@ -1021,18 +1013,24 @@ public:
if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0) if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
continue; continue;


char data[EngineMidiEvent::kDataSize];
char data[4];
data[0] = static_cast<char>(status + channel); data[0] = static_cast<char>(status + channel);


for (uint8_t j=0; j < EngineMidiEvent::kDataSize; ++i)
for (uint8_t j=0; j < 4; ++j)
data[j] = static_cast<char>(midiEvent.data[j]); data[j] = static_cast<char>(midiEvent.data[j]);


fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
fShmControl.writeLong(event.time);
fShmControl.writeInt(midiEvent.size);
{
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
fShmControl.writeLong(event.time);
fShmControl.writeInt(midiEvent.size);


for (uint8_t j=0; j < midiEvent.size && j < 4; ++j)
fShmControl.writeChar(data[j]);
for (uint8_t j=0; j < midiEvent.size; ++j)
fShmControl.writeChar(data[j]);

fShmControl.commitWrite();
}


if (status == MIDI_STATUS_NOTE_ON) if (status == MIDI_STATUS_NOTE_ON)
pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]); pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
@@ -1089,8 +1087,12 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Run plugin // Run plugin


fShmControl.writeOpcode(kPluginBridgeOpcodeProcess);
fShmControl.commitWrite();
{
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeProcess);
fShmControl.commitWrite();
}


if (! waitForServer(2)) if (! waitForServer(2))
{ {
@@ -1173,6 +1175,8 @@ public:


void bufferSizeChanged(const uint32_t newBufferSize) override void bufferSizeChanged(const uint32_t newBufferSize) override
{ {
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

resizeAudioPool(newBufferSize); resizeAudioPool(newBufferSize);


fShmControl.writeOpcode(kPluginBridgeOpcodeSetBufferSize); fShmControl.writeOpcode(kPluginBridgeOpcodeSetBufferSize);
@@ -1182,6 +1186,8 @@ public:


void sampleRateChanged(const double newSampleRate) override void sampleRateChanged(const double newSampleRate) override
{ {
const CarlaCriticalSection::Scope _cs(fShmControl.lock);

fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate); fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate);
fShmControl.writeFloat(static_cast<float>(newSampleRate)); fShmControl.writeFloat(static_cast<float>(newSampleRate));
fShmControl.commitWrite(); fShmControl.commitWrite();


+ 2
- 2
source/utils/CarlaRingBuffer.hpp View File

@@ -45,7 +45,7 @@ struct HeapRingBuffer {
}; };


struct StackRingBuffer { struct StackRingBuffer {
static const uint32_t size = 2048;
static const uint32_t size = 4096;
int32_t head, tail, written; int32_t head, tail, written;
bool invalidateCommit; bool invalidateCommit;
char buf[size]; char buf[size];
@@ -53,7 +53,7 @@ struct StackRingBuffer {


PRE_PACKED_STRUCTURE PRE_PACKED_STRUCTURE
struct StackPackedRingBuffer { struct StackPackedRingBuffer {
static const uint32_t size = 2048;
static const uint32_t size = 4096;
int32_t head, tail, written; int32_t head, tail, written;
bool invalidateCommit; bool invalidateCommit;
char buf[size]; char buf[size];


Loading…
Cancel
Save