commit e2e2b5507f683a6b62adbd984b62cdde0ed05c3d
parent 7403ec875198b47894cedb5d8545588907c86280
Author: falkTX <falktx@falktx.com>
Date: Mon, 11 Jul 2022 14:16:02 +0100
Introduce ways for standalones to request audio input and midi
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
4 files changed, 211 insertions(+), 13 deletions(-)
diff --git a/distrho/DistrhoStandaloneUtils.hpp b/distrho/DistrhoStandaloneUtils.hpp
@@ -0,0 +1,71 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2022 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
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef DISTRHO_STANDALONE_UTILS_HPP_INCLUDED
+#define DISTRHO_STANDALONE_UTILS_HPP_INCLUDED
+
+#include "src/DistrhoDefines.h"
+
+START_NAMESPACE_DISTRHO
+
+/* ------------------------------------------------------------------------------------------------------------
+ * Standalone plugin related utilities */
+
+/**
+ @defgroup PluginRelatedUtilities Plugin related utilities
+
+ @{
+ */
+
+/**
+ Check if the current standalone supports audio input.
+*/
+bool supportsAudioInput();
+
+/**
+ Check if the current standalone supports MIDI.
+*/
+bool supportsMIDI();
+
+/**
+ Check if the current standalone has audio input enabled.
+*/
+bool isAudioInputEnabled();
+
+/**
+ Check if the current standalone has MIDI enabled.
+*/
+bool isMIDIEnabled();
+
+/**
+ Request permissions to use audio input.
+ Only valid to call if audio input is supported but not currently enabled.
+*/
+bool requestAudioInput();
+
+/**
+ Request permissions to use MIDI.
+ Only valid to call if MIDI is supported but not currently enabled.
+*/
+bool requestMIDI();
+
+/** @} */
+
+// -----------------------------------------------------------------------------------------------------------
+
+END_NAMESPACE_DISTRHO
+
+#endif // DISTRHO_STANDALONE_UTILS_HPP_INCLUDED
diff --git a/distrho/src/jackbridge/JackBridge.cpp b/distrho/src/jackbridge/JackBridge.cpp
@@ -15,6 +15,7 @@
*/
#include "JackBridge.hpp"
+#include "../../DistrhoStandaloneUtils.hpp"
#if ! (defined(JACKBRIDGE_DIRECT) || defined(JACKBRIDGE_DUMMY))
@@ -42,7 +43,7 @@
# include "WebBridge.hpp"
#endif
-#if defined(HAVE_RTAUDIO) && DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
+#if defined(HAVE_RTAUDIO) && defined(DISTRHO_PROPER_CPP11_SUPPORT) && DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
# include "RtAudioBridge.hpp"
# ifdef RTAUDIO_API_TYPE
# include "rtaudio/RtAudio.cpp"
@@ -2242,3 +2243,71 @@ bool jackbridge_set_property_change_callback(jack_client_t* client, JackProperty
}
// -----------------------------------------------------------------------------
+
+START_NAMESPACE_DISTRHO
+
+bool supportsAudioInput()
+{
+#if defined(JACKBRIDGE_DUMMY)
+ return false;
+#elif !defined(JACKBRIDGE_DIRECT)
+ if (usingNativeBridge)
+ return nativeBridge->supportsAudioInput();
+#endif
+ return true;
+}
+
+bool supportsMIDI()
+{
+#if defined(JACKBRIDGE_DUMMY)
+ return false;
+#elif !defined(JACKBRIDGE_DIRECT)
+ if (usingNativeBridge)
+ return nativeBridge->supportsMIDI();
+#endif
+ return true;
+}
+
+bool isAudioInputEnabled()
+{
+#if defined(JACKBRIDGE_DUMMY)
+ return false;
+#elif !defined(JACKBRIDGE_DIRECT)
+ if (usingNativeBridge)
+ return nativeBridge->isAudioInputEnabled();
+#endif
+ return true;
+}
+
+bool isMIDIEnabled()
+{
+#if defined(JACKBRIDGE_DUMMY)
+ return false;
+#elif !defined(JACKBRIDGE_DIRECT)
+ if (usingNativeBridge)
+ return nativeBridge->isMIDIEnabled();
+#endif
+ return true;
+}
+
+bool requestAudioInput()
+{
+#if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
+ if (usingNativeBridge)
+ return nativeBridge->requestAudioInput();
+#endif
+ return false;
+}
+
+bool requestMIDI()
+{
+#if !(defined(JACKBRIDGE_DUMMY) || defined(JACKBRIDGE_DIRECT))
+ if (usingNativeBridge)
+ return nativeBridge->requestMIDI();
+#endif
+ return false;
+}
+
+END_NAMESPACE_DISTRHO
+
+// -----------------------------------------------------------------------------
diff --git a/distrho/src/jackbridge/NativeBridge.hpp b/distrho/src/jackbridge/NativeBridge.hpp
@@ -67,6 +67,29 @@ struct NativeBridge {
virtual bool activate() = 0;
virtual bool deactivate() = 0;
+ virtual bool supportsAudioInput() const
+ {
+ #if DISTRHO_PLUGIN_NUM_INPUTS > 0
+ return true;
+ #else
+ return false;
+ #endif
+ }
+
+ virtual bool isAudioInputEnabled() const
+ {
+ #if DISTRHO_PLUGIN_NUM_INPUTS > 0
+ return true;
+ #else
+ return false;
+ #endif
+ }
+
+ virtual bool supportsMIDI() const { return false; }
+ virtual bool isMIDIEnabled() const { return false; }
+ virtual bool requestAudioInput() { return false; }
+ virtual bool requestMIDI() { return false; }
+
uint32_t getEventCount()
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
diff --git a/distrho/src/jackbridge/WebBridge.hpp b/distrho/src/jackbridge/WebBridge.hpp
@@ -131,7 +131,7 @@ struct WebBridge : NativeBridge {
// main processor
WAB.processor = WAB.audioContext['createScriptProcessor'](bufferSize, numInputs, numOutputs);
WAB.processor['onaudioprocess'] = function (e) {
- var timestamp = performance.now();
+ // var timestamp = performance.now();
for (var i = 0; i < numInputs; ++i) {
var buffer = e['inputBuffer']['getChannelData'](i);
for (var j = 0; j < bufferSize; ++j) {
@@ -139,7 +139,7 @@ struct WebBridge : NativeBridge {
HEAPF32[$3 + (((bufferSize * i) + j) << 2) >> 2] = buffer[j];
}
}
- dynCall('vif', $4, [$5, timestamp]);
+ dynCall('vi', $4, [$5]);
for (var i = 0; i < numOutputs; ++i) {
var buffer = e['outputBuffer']['getChannelData'](i);
var offset = bufferSize * (numInputs + i);
@@ -161,9 +161,6 @@ struct WebBridge : NativeBridge {
});
}, DISTRHO_PLUGIN_NUM_INPUTS, DISTRHO_PLUGIN_NUM_OUTPUTS, bufferSize, audioBufferStorage, WebAudioCallback, this);
-// enableInput();
- enableMIDI();
-
return true;
}
@@ -185,7 +182,25 @@ struct WebBridge : NativeBridge {
return true;
}
- bool enableInput()
+ bool supportsAudioInput() const override
+ {
+ #if DISTRHO_PLUGIN_NUM_INPUTS > 0
+ return captureAvailable;
+ #else
+ return false;
+ #endif
+ }
+
+ bool isAudioInputEnabled() const override
+ {
+ #if DISTRHO_PLUGIN_NUM_INPUTS > 0
+ return EM_ASM_INT({ return Module['WebAudioBridge'].captureStreamNode ? 1 : 0 }) != 0;
+ #else
+ return false;
+ #endif
+ }
+
+ bool requestAudioInput() override
{
DISTRHO_SAFE_ASSERT_RETURN(DISTRHO_PLUGIN_NUM_INPUTS > 0, false);
@@ -224,7 +239,25 @@ struct WebBridge : NativeBridge {
return true;
}
- bool enableMIDI()
+ bool supportsMIDI() const override
+ {
+ #if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+ return midiAvailable;
+ #else
+ return false;
+ #endif
+ }
+
+ bool isMIDIEnabled() const override
+ {
+ #if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+ return EM_ASM_INT({ return Module['WebAudioBridge'].midi ? 1 : 0 }) != 0;
+ #else
+ return false;
+ #endif
+ }
+
+ bool requestMIDI() override
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
if (midiAvailable)
@@ -287,10 +320,10 @@ struct WebBridge : NativeBridge {
}
}
- static void WebAudioCallback(void* const userData, const double timestamp)
+ static void WebAudioCallback(void* const userData /* , const double timestamp */)
{
WebBridge* const self = static_cast<WebBridge*>(userData);
- self->timestamp = timestamp;
+ // self->timestamp = timestamp;
const uint numFrames = self->bufferSize;
@@ -299,11 +332,12 @@ struct WebBridge : NativeBridge {
self->jackProcessCallback(numFrames, self->jackProcessArg);
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
- if (self->midiAvailable)
+ if (self->midiAvailable && self->midiOutBuffer.isDataAvailableForReading())
{
static_assert(kMaxMIDIInputMessageSize + 1u == 4, "change code if bumping this value");
uint32_t offset = 0;
uint8_t bytes[4] = {};
+ double timestamp = EM_ASM_DOUBLE({ return performance.now(); });
while (self->midiOutBuffer.isDataAvailableForReading() &&
self->midiOutBuffer.readCustomData(bytes, ARRAY_SIZE(bytes)))
@@ -313,7 +347,7 @@ struct WebBridge : NativeBridge {
EM_ASM({
var WAB = Module['WebAudioBridge'];
if (WAB.midi) {
- var timestamp = performance.now() + $0;
+ var timestamp = $5 + $0;
var size = $1;
WAB.midi.outputs.forEach(function(port) {
if (port.state !== 'disconnected') {
@@ -323,8 +357,9 @@ struct WebBridge : NativeBridge {
}
});
}
- }, offset, bytes[0], bytes[1], bytes[2], bytes[3]);
+ }, offset, bytes[0], bytes[1], bytes[2], bytes[3], timestamp);
}
+
self->midiOutBuffer.clearData();
}
#endif