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[2] = velocity;
fNotesRingBuffer.writeCustomData(midiData, 3);
fNotesRingBuffer.commitWrite();
fNotesRingBuffer.commitWrite("PluginJack::sendNote");
}
# endif



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

@@ -1,6 +1,6 @@
/*
* 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
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -19,6 +19,7 @@

#include "JackBridge.hpp"

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

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

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

struct NativeBridge {
// Current status information
@@ -64,23 +67,24 @@ struct NativeBridge {
kPortMaskInputMIDI = kPortMaskInput|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* 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;
#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 kRingBufferMessageSize = 1u /*+ sizeof(double)*/ + kMaxMIDIInputMessageSize;
uint8_t midiDataStorage[kMaxMIDIInputMessageSize];
HeapRingBuffer midiInBufferCurrent;
HeapRingBuffer midiInBufferPending;
#endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
#endif
Mutex midiInLock;
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
HeapRingBuffer midiOutBuffer;
#endif
#endif

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



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

@@ -1,6 +1,6 @@
/*
* 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
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -19,7 +19,7 @@

#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
#endif

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

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

const MutexLocker cml(self->midiInLock);

self->midiInBufferPending.writeByte(static_cast<uint8_t>(len));
// TODO timestamp
// self->midiInBufferPending.writeDouble(timestamp);
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.commitWrite();
self->midiInBufferPending.commitWrite("RtMidiCallback");
}
#endif
};


Loading…
Cancel
Save