Browse Source

Fix data concurrency when using RtMidi input

Signed-off-by: falkTX <falktx@falktx.com>
pull/506/head
falkTX 2 months ago
parent
commit
c16ddd0445
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 26 additions and 17 deletions
  1. +1
    -1
      distrho/src/DistrhoPluginJACK.cpp
  2. +19
    -12
      distrho/src/jackbridge/NativeBridge.hpp
  3. +6
    -4
      distrho/src/jackbridge/RtAudioBridge.hpp

+ 1
- 1
distrho/src/DistrhoPluginJACK.cpp View File

@@ -552,7 +552,7 @@ protected:
midiData[1] = note; midiData[1] = note;
midiData[2] = velocity; midiData[2] = velocity;
fNotesRingBuffer.writeCustomData(midiData, 3); fNotesRingBuffer.writeCustomData(midiData, 3);
fNotesRingBuffer.commitWrite();
fNotesRingBuffer.commitWrite("PluginJack::sendNote");
} }
# endif # endif




+ 19
- 12
distrho/src/jackbridge/NativeBridge.hpp View File

@@ -1,6 +1,6 @@
/* /*
* Native Bridge for DPF * Native Bridge for DPF
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any purpose with * Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this * or without fee is hereby granted, provided that the above copyright notice and this
@@ -19,6 +19,7 @@


#include "JackBridge.hpp" #include "JackBridge.hpp"


#include "../../extra/Mutex.hpp"
#include "../../extra/RingBuffer.hpp" #include "../../extra/RingBuffer.hpp"


#if DISTRHO_PLUGIN_NUM_INPUTS > 2 #if DISTRHO_PLUGIN_NUM_INPUTS > 2
@@ -34,6 +35,8 @@
#endif #endif


using DISTRHO_NAMESPACE::HeapRingBuffer; using DISTRHO_NAMESPACE::HeapRingBuffer;
using DISTRHO_NAMESPACE::Mutex;
using DISTRHO_NAMESPACE::MutexLocker;


struct NativeBridge { struct NativeBridge {
// Current status information // Current status information
@@ -64,23 +67,24 @@ struct NativeBridge {
kPortMaskInputMIDI = kPortMaskInput|kPortMaskMIDI, kPortMaskInputMIDI = kPortMaskInput|kPortMaskMIDI,
kPortMaskOutputMIDI = kPortMaskOutput|kPortMaskMIDI, kPortMaskOutputMIDI = kPortMaskOutput|kPortMaskMIDI,
}; };
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
float* audioBuffers[DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS]; float* audioBuffers[DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS];
float* audioBufferStorage; float* audioBufferStorage;
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool midiAvailable; bool midiAvailable;
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
static constexpr const uint32_t kMaxMIDIInputMessageSize = 3; static constexpr const uint32_t kMaxMIDIInputMessageSize = 3;
static constexpr const uint32_t kRingBufferMessageSize = 1u /*+ sizeof(double)*/ + kMaxMIDIInputMessageSize; static constexpr const uint32_t kRingBufferMessageSize = 1u /*+ sizeof(double)*/ + kMaxMIDIInputMessageSize;
uint8_t midiDataStorage[kMaxMIDIInputMessageSize]; uint8_t midiDataStorage[kMaxMIDIInputMessageSize];
HeapRingBuffer midiInBufferCurrent; HeapRingBuffer midiInBufferCurrent;
HeapRingBuffer midiInBufferPending; HeapRingBuffer midiInBufferPending;
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
#endif
Mutex midiInLock;
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
HeapRingBuffer midiOutBuffer; HeapRingBuffer midiOutBuffer;
#endif
#endif


NativeBridge() NativeBridge()
: bufferSize(0), : bufferSize(0),
@@ -158,7 +162,10 @@ struct NativeBridge {
if (midiAvailable) if (midiAvailable)
{ {
// NOTE: this function is only called once per run // NOTE: this function is only called once per run
midiInBufferCurrent.copyFromAndClearOther(midiInBufferPending);
{
const MutexLocker cml(midiInLock);
midiInBufferCurrent.copyFromAndClearOther(midiInBufferPending);
}
return midiInBufferCurrent.getReadableDataSize() / kRingBufferMessageSize; return midiInBufferCurrent.getReadableDataSize() / kRingBufferMessageSize;
} }
#endif #endif
@@ -212,10 +219,10 @@ struct NativeBridge {
case 2: fail |= !midiOutBuffer.writeByte(0); case 2: fail |= !midiOutBuffer.writeByte(0);
} }
fail |= !midiOutBuffer.writeUInt(time); fail |= !midiOutBuffer.writeUInt(time);
midiOutBuffer.commitWrite();
midiOutBuffer.commitWrite("NativeBridge::writeEvent (with data)");
return !fail; return !fail;
} }
midiOutBuffer.commitWrite();
midiOutBuffer.commitWrite("NativeBridge::writeEvent (without data)");
} }
#endif #endif




+ 6
- 4
distrho/src/jackbridge/RtAudioBridge.hpp View File

@@ -1,6 +1,6 @@
/* /*
* RtAudio Bridge for DPF * RtAudio Bridge for DPF
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any purpose with * Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this * or without fee is hereby granted, provided that the above copyright notice and this
@@ -19,7 +19,7 @@


#include "NativeBridge.hpp" #include "NativeBridge.hpp"


#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS == 0
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) == 0
# error RtAudio without audio does not make sense # error RtAudio without audio does not make sense
#endif #endif


@@ -425,13 +425,15 @@ struct RtAudioBridge : NativeBridge {


RtAudioBridge* const self = static_cast<RtAudioBridge*>(userData); RtAudioBridge* const self = static_cast<RtAudioBridge*>(userData);


const MutexLocker cml(self->midiInLock);

self->midiInBufferPending.writeByte(static_cast<uint8_t>(len)); self->midiInBufferPending.writeByte(static_cast<uint8_t>(len));
// TODO timestamp // TODO timestamp
// self->midiInBufferPending.writeDouble(timestamp); // self->midiInBufferPending.writeDouble(timestamp);
self->midiInBufferPending.writeCustomData(message->data(), len); self->midiInBufferPending.writeCustomData(message->data(), len);
for (uint8_t i=len; i<kMaxMIDIInputMessageSize; ++i)
for (uint8_t i = len; i < kMaxMIDIInputMessageSize; ++i)
self->midiInBufferPending.writeByte(0); self->midiInBufferPending.writeByte(0);
self->midiInBufferPending.commitWrite();
self->midiInBufferPending.commitWrite("RtMidiCallback");
} }
#endif #endif
}; };


Loading…
Cancel
Save