Skip to content

Commit e450bde

Browse files
committed
Allow native rtaudio backend with only midi
Signed-off-by: falkTX <falktx@falktx.com>
1 parent dbceab1 commit e450bde

2 files changed

Lines changed: 74 additions & 17 deletions

File tree

distrho/src/jackbridge/JackBridge.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* JackBridge for DPF
3-
* Copyright (C) 2013-2025 Filipe Coelho <falktx@falktx.com>
3+
* Copyright (C) 2013-2026 Filipe Coelho <falktx@falktx.com>
44
*
55
* Permission to use, copy, modify, and/or distribute this software for any purpose with
66
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -60,7 +60,7 @@ typedef void* lib_t;
6060
# undef HAVE_SDL2
6161
#endif
6262

63-
#if defined(HAVE_RTAUDIO) && (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) > 0
63+
#ifdef HAVE_RTAUDIO
6464
// fix conflict between DGL and macOS names
6565
# define Fixed CoreFixed
6666
# define Point CorePoint
@@ -972,7 +972,7 @@ jack_client_t* jackbridge_client_open(const char* client_name, uint32_t options,
972972
delete nativeBridge;
973973
#endif
974974

975-
#if defined(HAVE_SDL2) && DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
975+
#if defined(HAVE_SDL2) && (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0)
976976
nativeBridge = new SDL2Bridge;
977977
if (nativeBridge->open(client_name))
978978
return kValidClient;

distrho/src/jackbridge/RtAudioBridge.hpp

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* RtAudio Bridge for DPF
3-
* Copyright (C) 2021-2025 Filipe Coelho <falktx@falktx.com>
3+
* Copyright (C) 2021-2026 Filipe Coelho <falktx@falktx.com>
44
*
55
* Permission to use, copy, modify, and/or distribute this software for any purpose with
66
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -19,10 +19,6 @@
1919

2020
#include "NativeBridge.hpp"
2121

22-
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) == 0
23-
# error RtAudio without audio does not make sense
24-
#endif
25-
2622
#if defined(DISTRHO_OS_MAC)
2723
# define __MACOSX_CORE__
2824
# define RTAUDIO_API_TYPE MACOSX_CORE
@@ -51,21 +47,27 @@
5147
# include "../../extra/ScopedPointer.hpp"
5248
# include "../../extra/String.hpp"
5349
# include "../../extra/ScopedDenormalDisable.hpp"
50+
# include "../../extra/Thread.hpp"
5451

5552
using DISTRHO_NAMESPACE::ScopedDenormalDisable;
5653
using DISTRHO_NAMESPACE::ScopedPointer;
5754
using DISTRHO_NAMESPACE::String;
5855

59-
struct RtAudioBridge : NativeBridge {
60-
// pointer to RtAudio instance
56+
struct RtAudioBridge : NativeBridge
57+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) == 0
58+
, private DISTRHO_NAMESPACE::Thread
59+
#endif
60+
{
61+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
6162
ScopedPointer<RtAudio> handle;
62-
bool captureEnabled = false;
63+
#endif
6364
#if defined(RTMIDI_API_TYPE) && DISTRHO_PLUGIN_WANT_MIDI_INPUT
6465
std::vector<RtMidiIn> midiIns;
6566
#endif
6667
#if defined(RTMIDI_API_TYPE) && DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
6768
std::vector<RtMidiOut> midiOuts;
6869
#endif
70+
bool audioCaptureEnabled = false;
6971

7072
// caching
7173
String name;
@@ -86,11 +88,19 @@ struct RtAudioBridge : NativeBridge {
8688
bool open(const char* const clientName) override
8789
{
8890
name = clientName;
91+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
8992
return _open(false);
93+
#else
94+
bufferSize = 512;
95+
sampleRate = 48000;
96+
allocBuffers(false, true);
97+
return true;
98+
#endif
9099
}
91100

92101
bool close() override
93102
{
103+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
94104
DISTRHO_SAFE_ASSERT_RETURN(handle != nullptr, false);
95105

96106
if (handle->isStreamRunning())
@@ -99,40 +109,49 @@ struct RtAudioBridge : NativeBridge {
99109
handle->abortStream();
100110
} DISTRHO_SAFE_EXCEPTION("handle->abortStream()");
101111
}
112+
#endif
102113

103-
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
104114
freeBuffers();
105-
#endif
115+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
106116
handle = nullptr;
117+
#endif
107118
return true;
108119
}
109120

110121
bool activate() override
111122
{
123+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
112124
DISTRHO_SAFE_ASSERT_RETURN(handle != nullptr, false);
113125

114126
try {
115127
handle->startStream();
116128
} DISTRHO_SAFE_EXCEPTION_RETURN("handle->startStream()", false);
129+
#else
130+
startThread();
131+
#endif
117132

118133
return true;
119134
}
120135

121136
bool deactivate() override
122137
{
138+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
123139
DISTRHO_SAFE_ASSERT_RETURN(handle != nullptr, false);
124140

125141
try {
126142
handle->stopStream();
127143
} DISTRHO_SAFE_EXCEPTION_RETURN("handle->stopStream()", false);
144+
#else
145+
stopThread(-1);
146+
#endif
128147

129148
return true;
130149
}
131150

132151
bool isAudioInputEnabled() const override
133152
{
134153
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
135-
return captureEnabled;
154+
return audioCaptureEnabled;
136155
#else
137156
return false;
138157
#endif
@@ -149,7 +168,7 @@ struct RtAudioBridge : NativeBridge {
149168
const bool ok = _open(true);
150169

151170
if (ok)
152-
captureEnabled = true;
171+
audioCaptureEnabled = true;
153172
else
154173
_open(false);
155174

@@ -252,6 +271,7 @@ struct RtAudioBridge : NativeBridge {
252271
return true;
253272
}
254273

274+
#if (DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS) != 0
255275
bool supportsBufferSizeChanges() const override
256276
{
257277
return true;
@@ -266,13 +286,13 @@ struct RtAudioBridge : NativeBridge {
266286
// try to open with new buffer size
267287
nextBufferSize = newBufferSize;
268288

269-
const bool ok = _open(captureEnabled);
289+
const bool ok = _open(audioCaptureEnabled);
270290

271291
if (!ok)
272292
{
273293
// revert to old buffer size if new one failed
274294
nextBufferSize = bufferSize;
275-
_open(captureEnabled);
295+
_open(audioCaptureEnabled);
276296
}
277297

278298
if (bufferSizeCallback != nullptr)
@@ -416,6 +436,43 @@ struct RtAudioBridge : NativeBridge {
416436

417437
return 0;
418438
}
439+
#else
440+
void run() override
441+
{
442+
if (jackProcessCallback == nullptr)
443+
return;
444+
445+
const ScopedDenormalDisable sdd;
446+
447+
while (! shouldThreadExit())
448+
{
449+
DISTRHO_NAMESPACE::d_msleep(10);
450+
jackProcessCallback(512, jackProcessArg);
451+
452+
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
453+
if (midiOutBuffer.isDataAvailableForReading())
454+
{
455+
static_assert(kMaxMIDIInputMessageSize + 1u == 4, "change code if bumping this value");
456+
uint8_t data[4] = {};
457+
458+
while (midiOutBuffer.isDataAvailableForReading() &&
459+
midiOutBuffer.readCustomData(data, ARRAY_SIZE(data)))
460+
{
461+
// offset not used in RtMidiOut
462+
midiOutBuffer.readUInt();
463+
464+
for (std::vector<RtMidiOut>::iterator it = midiOuts.begin(), end = midiOuts.end(); it != end; ++it)
465+
{
466+
static_cast<RtMidiOut&>(*it).sendMessage(data + 1, data[0]);
467+
}
468+
}
469+
470+
midiOutBuffer.flush();
471+
}
472+
#endif
473+
}
474+
}
475+
#endif
419476

420477
#if defined(RTMIDI_API_TYPE) && DISTRHO_PLUGIN_WANT_MIDI_INPUT
421478
static void RtMidiCallback(double /*timestamp*/, std::vector<uchar>* const message, void* const userData)

0 commit comments

Comments
 (0)