diff --git a/source/discovery/Makefile b/source/discovery/Makefile index a25e6d07a..974f4ca14 100644 --- a/source/discovery/Makefile +++ b/source/discovery/Makefile @@ -8,49 +8,68 @@ include ../Makefile.mk # -------------------------------------------------------------- -BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../utils +BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../utils -Wno-multichar + BUILD_CXX_FLAGS += $(QTCORE_FLAGS) LINK_FLAGS += $(QTCORE_LIBS) +ifeq ($(HAVE_JUCE),true) +BUILD_CXX_FLAGS += $(JUCE_CORE_FLAGS) $(JUCE_AUDIO_BASICS_FLAGS) -DHAVE_JUCE +LINK_FLAGS += $(JUCE_CORE_LIBS) $(JUCE_AUDIO_BASICS_LIBS) +endif + # -------------------------------------------------------------- BUILD_CXX_FLAGS += -DWANT_NATIVE ifeq ($(CARLA_PLUGIN_SUPPORT),true) BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST -ifeq ($(CARLA_VESTIGE_HEADER),true) +ifeq ($(CARLA_VESTIGE_HEADER),true) # TODO: and not have juce BUILD_CXX_FLAGS += -DVESTIGE_HEADER endif endif # -------------------------------------------------------------- -ifeq ($(HAVE_CSOUND),true) +# ifeq ($(HAVE_CSOUND),true) # NATIVE_FLAGS += $(shell pkg-config --cflags --libs sndfile) -lcsound64 -DWANT_CSOUND -# NATIVE_FLAGS += $(JUCE_CORE_FLAGS) $(JUCE_CORE_LIBS) -endif - -ifeq ($(HAVE_FLUIDSYNTH),true) -NATIVE_FLAGS += $(shell pkg-config --cflags --libs fluidsynth) -DWANT_FLUIDSYNTH -endif - -ifeq ($(HAVE_LINUXSAMPLER),true) +# endif +# +# ifeq ($(HAVE_FLUIDSYNTH),true) +# NATIVE_FLAGS += $(shell pkg-config --cflags --libs fluidsynth) -DWANT_FLUIDSYNTH +# endif +# +# ifeq ($(HAVE_LINUXSAMPLER),true) # NATIVE_FLAGS += $(shell pkg-config --cflags --libs linuxsampler) -DWANT_LINUXSAMPLER -endif +# endif # -------------------------------------------------------------- -ifeq ($(CARLA_PLUGIN_SUPPORT),true) -LIBS = ../modules/lilv.a -LIBS_posix32 = ../modules/lilv.posix32.a -LIBS_posix64 = ../modules/lilv.posix64.a -LIBS_win32 = ../modules/lilv.win32.a -LIBS_win64 = ../modules/lilv.win64.a -LINK_FLAGS += $(LILV_LIBS) +ifeq ($(HAVE_JUCE),true) +LIBS += ../modules/juce_core.a +LIBS_posix32 += ../modules/juce_core.posix32.a +LIBS_posix64 += ../modules/juce_core.posix64.a +LIBS_win32 += ../modules/juce_core.win32.a +LIBS_win64 += ../modules/juce_core.win64.a +LIBS += ../modules/juce_audio_basics.a +LIBS_posix32 += ../modules/juce_audio_basics.posix32.a +LIBS_posix64 += ../modules/juce_audio_basics.posix64.a +LIBS_win32 += ../modules/juce_audio_basics.win32.a +LIBS_win64 += ../modules/juce_audio_basics.win64.a +# LIBS += ../modules/juce_audio_processors.a +# LIBS_posix32 += ../modules/juce_audio_processors.posix32.a +# LIBS_posix64 += ../modules/juce_audio_processors.posix64.a +# LIBS_win32 += ../modules/juce_audio_processors.win32.a +# LIBS_win64 += ../modules/juce_audio_processors.win64.a endif -ifeq ($(HAVE_CSOUND),true) -# LIBS = ../modules/juce_core.a +ifeq ($(CARLA_PLUGIN_SUPPORT),true) +LIBS += ../modules/lilv.a +LIBS_posix32 += ../modules/lilv.posix32.a +LIBS_posix64 += ../modules/lilv.posix64.a +LIBS_win32 += ../modules/lilv.win32.a +LIBS_win64 += ../modules/lilv.win64.a +LINK_FLAGS += $(LILV_LIBS) endif POSIX_BUILD_FLAGS = $(BUILD_CXX_FLAGS) diff --git a/source/discovery/carla-discovery.cpp b/source/discovery/carla-discovery.cpp index 859a7bee5..769c5de2c 100644 --- a/source/discovery/carla-discovery.cpp +++ b/source/discovery/carla-discovery.cpp @@ -20,6 +20,16 @@ #include "CarlaString.hpp" #include "CarlaMIDI.h" +#ifdef HAVE_JUCE +# define JUCE_PLUGIN_HOST_NO_UI +# undef WANT_VST +# undef WANT_AU +# include "juce_core.h" +# include "juce_audio_processors.h" +#else +# undef WANT_CSOUND +#endif + #ifdef WANT_LADSPA # include "CarlaLadspaUtils.hpp" #endif @@ -27,26 +37,26 @@ # include "CarlaDssiUtils.hpp" #endif #ifdef WANT_LV2 -# include # include "CarlaLv2Utils.hpp" #endif #ifdef WANT_VST # include "CarlaVstUtils.hpp" #endif #ifdef WANT_CSOUND -# include "juce_core.h" # include #endif #ifdef WANT_FLUIDSYNTH # include #endif #ifdef WANT_LINUXSAMPLER -# include # include "linuxsampler/EngineFactory.h" #endif #include -# include + +#include +#include +#include #define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl; @@ -263,6 +273,23 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode } #endif +#ifdef WANT_CSOUND +// -------------------------------------------------------------------------- +// Csound stuff + +static int csound_midiInOpen(CSOUND*, void**, const char*) { return 0; } +static int csound_midiRead(CSOUND*, void*, unsigned char*, int) { return 0; } +static int csound_midiInClose(CSOUND*, void*) { return 0; } + +static int csound_midiOutOpen(CSOUND*, void**, const char*) { return 0; } +static int csound_midiWrite(CSOUND*, void*, const unsigned char*, int) { return 0; } +static int csound_midiOutClose(CSOUND*, void*) { return 0; } + +# ifndef DEBUG +static void csound_silence(CSOUND*, int, const char*, va_list) {} +# endif +#endif + #ifdef WANT_LINUXSAMPLER // -------------------------------------------------------------------------- // LinuxSampler stuff @@ -1386,27 +1413,113 @@ void do_vst_check(void*& libHandle, const bool init) #endif } -#ifdef WANT_CSOUND -static int csound_midiInOpen(CSOUND*, void**, const char*) { return 0; } -static int csound_midiRead(CSOUND*, void*, unsigned char*, int) { return 0; } -static int csound_midiInClose(CSOUND*, void*) { return 0; } +void do_au_check(void*& libHandle, const bool init) +{ +#if 0 //def WANT_AU +#else + DISCOVERY_OUT("error", "AU support not available"); + return; -static int csound_midiOutOpen(CSOUND*, void**, const char*) { return 0; } -static int csound_midiWrite(CSOUND*, void*, const unsigned char*, int) { return 0; } -static int csound_midiOutClose(CSOUND*, void*) { return 0; } + // unused + (void)libHandle; + (void)init; +#endif +}; -#if 1//ndef DEBUG -static void csound_silence(CSOUND*, int, const char*, va_list) {} +#ifdef HAVE_JUCE +void do_juce_check(const char* const filename, const char* const stype, const bool init) +{ + using namespace juce; + + ScopedPointer pluginFormat; + + if (stype == nullptr) + return; +#if JUCE_PLUGINHOST_AU && JUCE_MAC + else if (std::strcmp(stype, "au") == 0) + pluginFormat = new AudioUnitPluginFormat(); +#endif +#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX + else if (std::strcmp(stype, "ladspa") == 0) + pluginFormat = new LADSPAPluginFormat(); #endif +#if JUCE_PLUGINHOST_VST + else if (std::strcmp(stype, "vst") == 0) + pluginFormat = new VSTPluginFormat(); +#endif + + if (pluginFormat == nullptr) + { + DISCOVERY_OUT("error", stype << " support not available"); + return; + } + + OwnedArray results; + pluginFormat->findAllTypesForFile(results, filename); + + for (auto it = results.begin(), end = results.end(); it != end; ++it) + { + static int iv=0; + carla_stderr2("LOOKING FOR PLUGIN %i", iv++); + PluginDescription* desc(*it); + + int hints = 0x0; + int audioIns = desc->numInputChannels; + int audioOuts = desc->numOutputChannels; + int midiIns = 0; + int midiOuts = 0; + int parameters = 0; + int programs = 0; + + if (desc->isInstrument) + hints |= PLUGIN_IS_SYNTH; + +// if (init) +// { +// if (AudioPluginInstance* const instance = pluginFormat->createInstanceFromDescription(*desc, kSampleRate, kBufferSize)) +// { +// instance->refreshParameterList(); +// +// parameters = instance->getNumParameters(); +// programs = instance->getNumPrograms(); +// +// if (instance->hasEditor()) +// hints |= PLUGIN_HAS_CUSTOM_UI; +// if (instance->acceptsMidi()) +// midiIns = 1; +// if (instance->producesMidi()) +// midiOuts = 1; +// +// delete instance; +// } +// } + + DISCOVERY_OUT("init", "-----------"); + DISCOVERY_OUT("name", desc->name); + DISCOVERY_OUT("label", desc->descriptiveName); + DISCOVERY_OUT("maker", desc->manufacturerName); + DISCOVERY_OUT("copyright", desc->manufacturerName); + DISCOVERY_OUT("uniqueId", desc->uid); + DISCOVERY_OUT("hints", hints); + DISCOVERY_OUT("audio.ins", audioIns); + DISCOVERY_OUT("audio.outs", audioOuts); + DISCOVERY_OUT("midi.ins", midiIns); + DISCOVERY_OUT("midi.outs", midiOuts); + DISCOVERY_OUT("parameters.ins", parameters); + DISCOVERY_OUT("programs", programs); + DISCOVERY_OUT("build", BINARY_NATIVE); + DISCOVERY_OUT("end", "------------"); + } +} #endif void do_csound_check(const char* const filename, const bool init) { #ifdef WANT_CSOUND Csound csound; -#if 1//ndef DEBUG +# ifndef DEBUG csound.SetMessageCallback(csound_silence); -#endif +# endif csound.SetHostImplementedAudioIO(true, kBufferSize); csound.SetHostImplementedMIDIIO(true); csound.Reset(); @@ -1672,8 +1785,10 @@ int main(int argc, char* argv[]) { case PLUGIN_LADSPA: case PLUGIN_DSSI: +#ifndef HAVE_JUCE case PLUGIN_VST: case PLUGIN_AU: +#endif openLib = true; default: break; @@ -1737,10 +1852,18 @@ int main(int argc, char* argv[]) do_lv2_check(filename, doInit); break; case PLUGIN_VST: +#ifdef HAVE_JUCE + do_juce_check(filename, "vst", doInit); +#else do_vst_check(handle, doInit); +#endif break; case PLUGIN_AU: - //do_au_check(handle, doInit); +#ifdef HAVE_JUCE + do_juce_check(filename, "au", doInit); +#else + do_au_check(handle, doInit); +#endif break; case PLUGIN_CSOUND: do_csound_check(filename, doInit); @@ -1763,3 +1886,36 @@ int main(int argc, char* argv[]) return 0; } + +#ifdef HAVE_JUCE +// -------------------------------------------------------------------------- +// we want juce processors but without UI code +// this is copied from juce_audio_processors.cpp + +#include "juce_core/native/juce_BasicNativeHeaders.h" + +namespace juce +{ + +static inline +bool arrayContainsPlugin(const OwnedArray& list, const PluginDescription& desc) +{ + for (int i = list.size(); --i >= 0;) + { + if (list.getUnchecked(i)->isDuplicateOf(desc)) + return true; + } + + return false; +} + +#include "juce_audio_processors/format/juce_AudioPluginFormat.cpp" +#include "juce_audio_processors/processors/juce_AudioProcessor.cpp" +#include "juce_audio_processors/processors/juce_PluginDescription.cpp" +#include "juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" +#include "juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" +#include "juce_audio_processors/format_types/juce_VSTPluginFormat.cpp" +} +#endif + +// -------------------------------------------------------------------------- diff --git a/source/modules/juce_audio_processors/AppConfig.h b/source/modules/juce_audio_processors/AppConfig.h index 8f4f8cfd9..4bdf4716d 100755 --- a/source/modules/juce_audio_processors/AppConfig.h +++ b/source/modules/juce_audio_processors/AppConfig.h @@ -19,13 +19,13 @@ @see VSTPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU */ -#define JUCE_PLUGINHOST_VST 0 +#define JUCE_PLUGINHOST_VST 1 /** Config: JUCE_PLUGINHOST_AU Enables the AudioUnit plugin hosting classes. This is Mac-only, of course. @see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST */ -#define JUCE_PLUGINHOST_AU 0 +#define JUCE_PLUGINHOST_AU 1 #endif // CARLA_JUCE_AUDIO_PROCESSORS_APPCONFIG_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index e0cc66c79..dd371699c 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -191,7 +191,11 @@ class IdleCallRecursionPreventer { public: IdleCallRecursionPreventer() +#ifndef JUCE_PLUGIN_HOST_NO_UI : isMessageThread (MessageManager::getInstance()->isThisTheMessageThread()) +#else + : isMessageThread (false) +#endif { if (isMessageThread) ++insideVSTCallback; @@ -237,7 +241,7 @@ static void* NewCFMFromMachO (void* const machofp) noexcept #endif //============================================================================== -#if JUCE_LINUX +#if JUCE_LINUX && ! defined(JUCE_PLUGIN_HOST_NO_UI) extern Display* display; extern XContext windowHandleXContext; @@ -710,9 +714,13 @@ static const int defaultVSTBlockSizeValue = 512; //============================================================================== //============================================================================== +#ifndef JUCE_PLUGIN_HOST_NO_UI class VSTPluginInstance : public AudioPluginInstance, private Timer, private AsyncUpdater +#else +class VSTPluginInstance : public AudioPluginInstance +#endif { public: VSTPluginInstance (const ModuleHandle::Ptr& module_) @@ -782,8 +790,10 @@ public: UseResFile (module->resFileId); #endif + #ifndef JUCE_PLUGIN_HOST_NO_UI // Must delete any editors before deleting the plugin instance! jassert (getActiveEditor() == 0); + #endif _fpreset(); // some dodgy plugs fuck around with this @@ -1088,7 +1098,9 @@ public: //============================================================================== bool hasEditor() const override { return effect != nullptr && (effect->flags & effFlagsHasEditor) != 0; } +#ifndef JUCE_PLUGIN_HOST_NO_UI AudioProcessorEditor* createEditor() override; +#endif //============================================================================== const String getInputChannelName (int index) const override @@ -1237,6 +1249,7 @@ public: void setCurrentProgramStateInformation (const void* data, int size) override { loadFromFXBFile (data, size); } //============================================================================== +#ifndef JUCE_PLUGIN_HOST_NO_UI void timerCallback() override { if (dispatch (effIdle, 0, 0, 0, 0) == 0) @@ -1248,6 +1261,7 @@ public: // indicates that something about the plugin has changed.. updateHostDisplay(); } +#endif VstIntPtr handleCallback (VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) { @@ -1265,6 +1279,7 @@ public: #pragma warning (pop) #endif +#ifndef JUCE_PLUGIN_HOST_NO_UI case audioMasterIdle: if (insideVSTCallback == 0 && MessageManager::getInstance()->isThisTheMessageThread()) { @@ -1293,6 +1308,7 @@ public: case audioMasterUpdateDisplay: triggerAsyncUpdate(); break; case audioMasterIOChanged: setLatencySamples (effect->initialDelay); break; case audioMasterNeedIdle: startTimer (50); break; +#endif case audioMasterGetSampleRate: return (VstIntPtr) (getSampleRate() > 0 ? getSampleRate() : defaultVSTSampleRateValue); case audioMasterGetBlockSize: return (VstIntPtr) (getBlockSize() > 0 ? getBlockSize() : defaultVSTBlockSizeValue); @@ -1378,10 +1394,12 @@ public: case audioMasterGetVendorString: case audioMasterGetProductString: { - String hostName ("Juce VST Host"); + String hostName ("Carla"); +#ifndef JUCE_PLUGIN_HOST_NO_UI if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) hostName = app->getApplicationName(); +#endif hostName.copyToUTF8 ((char*) ptr, (size_t) jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); break; @@ -1882,6 +1900,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginInstance) }; +#ifndef JUCE_PLUGIN_HOST_NO_UI //============================================================================== static Array activeVSTWindows; @@ -2588,13 +2607,16 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSTPluginWindow) }; +#endif +#ifndef JUCE_PLUGIN_HOST_NO_UI //============================================================================== AudioProcessorEditor* VSTPluginInstance::createEditor() { return hasEditor() ? new VSTPluginWindow (*this) : nullptr; } +#endif //============================================================================== // entry point for all callbacks from the plugin diff --git a/source/modules/juce_audio_processors/juce_audio_processors.cpp b/source/modules/juce_audio_processors/juce_audio_processors.cpp index 955d770c3..d6a92f37b 100644 --- a/source/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/source/modules/juce_audio_processors/juce_audio_processors.cpp @@ -37,7 +37,7 @@ #include "../juce_core/native/juce_BasicNativeHeaders.h" #include "juce_audio_processors.h" -#include "../juce_gui_extra/juce_gui_extra.h" +//#include "../juce_gui_extra/juce_gui_extra.h" //============================================================================== #if JUCE_MAC diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 8f4f43ab6..c7ed5e258 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -44,9 +44,11 @@ AudioProcessor::AudioProcessor() AudioProcessor::~AudioProcessor() { +#ifndef JUCE_PLUGIN_HOST_NO_UI // ooh, nasty - the editor should have been deleted before the filter // that it refers to is deleted.. jassert (activeEditor == nullptr); +#endif #if JUCE_DEBUG // This will fail if you've called beginParameterChangeGesture() for one @@ -214,6 +216,7 @@ void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) void AudioProcessor::reset() {} void AudioProcessor::processBlockBypassed (AudioSampleBuffer&, MidiBuffer&) {} +#ifndef JUCE_PLUGIN_HOST_NO_UI //============================================================================== void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept { @@ -244,6 +247,7 @@ AudioProcessorEditor* AudioProcessor::createEditorIfNeeded() return ed; } +#endif //============================================================================== void AudioProcessor::getCurrentProgramStateInformation (juce::MemoryBlock& destData) diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 4d6276e3b..b69f9edae 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -331,6 +331,7 @@ public: */ void setNonRealtime (bool isNonRealtime) noexcept; +#ifndef JUCE_PLUGIN_HOST_NO_UI //============================================================================== /** Creates the filter's UI. @@ -360,12 +361,14 @@ public: @see hasEditor */ virtual AudioProcessorEditor* createEditor() = 0; +#endif /** Your filter must override this and return true if it can create an editor component. @see createEditor */ virtual bool hasEditor() const = 0; +#ifndef JUCE_PLUGIN_HOST_NO_UI //============================================================================== /** Returns the active editor, if there is one. Bear in mind this can return nullptr, even if an editor has previously been opened. @@ -376,6 +379,7 @@ public: This may call createEditor() internally to create the component. */ AudioProcessorEditor* createEditorIfNeeded(); +#endif //============================================================================== /** This must return the correct value immediately after the object has been @@ -582,7 +586,7 @@ public: //============================================================================== /** LV2 specific calls, saving/restore as string. */ virtual String getStateInformationString () { return String::empty; } - virtual void setStateInformationString (const String& data) {} + virtual void setStateInformationString (const String&) {} //============================================================================== /** Adds a listener that will be called when an aspect of this processor changes. */ @@ -602,9 +606,11 @@ public: /** This is called by the processor to specify its details before being played. */ void setPlayConfigDetails (int numIns, int numOuts, double sampleRate, int blockSize) noexcept; +#ifndef JUCE_PLUGIN_HOST_NO_UI //============================================================================== /** Not for public use - this is called before deleting an editor component. */ void editorBeingDeleted (AudioProcessorEditor*) noexcept; +#endif /** Not for public use - this is called to initialise the processor before playing. */ void setSpeakerArrangement (const String& inputs, const String& outputs); @@ -656,7 +662,9 @@ protected: private: Array listeners; +#ifndef JUCE_PLUGIN_HOST_NO_UI Component::SafePointer activeEditor; +#endif double sampleRate; int blockSize, numInputChannels, numOutputChannels, latencySamples; bool suspended, nonRealtime; diff --git a/source/utils/CarlaVstUtils.hpp b/source/utils/CarlaVstUtils.hpp index 7499fa555..18eec9e6d 100644 --- a/source/utils/CarlaVstUtils.hpp +++ b/source/utils/CarlaVstUtils.hpp @@ -23,6 +23,13 @@ // ----------------------------------------------------------------------- // Include fixes +// Define __cdecl if needed +#ifndef CARLA_OS_WIN +# ifndef __cdecl +# define __cdecl +# endif +#endif + // Disable deprecated VST features (NOT) #define VST_2_4_EXTENSIONS 1 #define VST_FORCE_DEPRECATED 0 @@ -106,7 +113,7 @@ #define kVstTransportChanged 1 #define kVstVersion 2400 #define DECLARE_VST_DEPRECATED(idx) idx -#define VSTCALLBACK +#define VSTCALLBACK __cdecl struct ERect { int16_t top, left, bottom, right; };