mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Move AudioPluginHost and NetworkGraphicsDemo projects from examples to extras
This commit is contained in:
parent
66ee9d6d6d
commit
44f9a5c256
166 changed files with 0 additions and 0 deletions
168
extras/AudioPluginHost/AudioPluginHost.jucer
Normal file
168
extras/AudioPluginHost/AudioPluginHost.jucer
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<JUCERPROJECT id="NTe0XB0ij" name="AudioPluginHost" projectType="guiapp" version="1.0.0"
|
||||
juceFolder="../../../juce" vstFolderMac="~/SDKs/vstsdk2.4" vstFolderPC="c:\SDKs\vstsdk2.4"
|
||||
bundleIdentifier="com.roli.pluginhost" jucerVersion="5.2.1" companyName="ROLI Ltd."
|
||||
displaySplashScreen="0" reportAppUsage="0" companyCopyright="ROLI Ltd.">
|
||||
<EXPORTFORMATS>
|
||||
<XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="" rtasFolder="~/SDKs/PT_80_SDK"
|
||||
objCExtraSuffix="M73TRi" vst3Folder="" extraCompilerFlags="-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_video" path="../../modules"/>
|
||||
<MODULEPATH id="juce_opengl" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_cryptography" path="../../modules"/>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</XCODE_MAC>
|
||||
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" vstFolder="" vst3Folder="">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost" libraryPath="/usr/X11R6/lib/"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" optimisation="2" targetName="AudioPluginHost"
|
||||
libraryPath="/usr/X11R6/lib/"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_video" path="../../modules"/>
|
||||
<MODULEPATH id="juce_opengl" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_cryptography" path="../../modules"/>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</LINUX_MAKE>
|
||||
<VS2013 targetFolder="Builds/VisualStudio2013" vstFolder="" vst3Folder="">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" winArchitecture="32-bit" isDebug="1" optimisation="1"
|
||||
targetName="AudioPluginHost"/>
|
||||
<CONFIGURATION name="Release" winArchitecture="32-bit" isDebug="0" targetName="AudioPluginHost"
|
||||
debugInformationFormat="ProgramDatabase"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_video" path="../../modules"/>
|
||||
<MODULEPATH id="juce_opengl" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_cryptography" path="../../modules"/>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</VS2013>
|
||||
<VS2015 targetFolder="Builds/VisualStudio2015" vstFolder="" vst3Folder="">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_video" path="../../modules"/>
|
||||
<MODULEPATH id="juce_opengl" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_cryptography" path="../../modules"/>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</VS2015>
|
||||
<VS2017 targetFolder="Builds/VisualStudio2017" vst3Folder="">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION name="Debug" isDebug="1" targetName="AudioPluginHost"/>
|
||||
<CONFIGURATION name="Release" isDebug="0" targetName="AudioPluginHost" debugInformationFormat="ProgramDatabase"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_video" path="../../modules"/>
|
||||
<MODULEPATH id="juce_opengl" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_extra" path="../../modules"/>
|
||||
<MODULEPATH id="juce_gui_basics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_graphics" path="../../modules"/>
|
||||
<MODULEPATH id="juce_events" path="../../modules"/>
|
||||
<MODULEPATH id="juce_data_structures" path="../../modules"/>
|
||||
<MODULEPATH id="juce_cryptography" path="../../modules"/>
|
||||
<MODULEPATH id="juce_core" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_utils" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_processors" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_formats" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_devices" path="../../modules"/>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../modules"/>
|
||||
</MODULEPATHS>
|
||||
</VS2017>
|
||||
</EXPORTFORMATS>
|
||||
<MAINGROUP id="YdWL7hi7p" name="AudioPluginHost">
|
||||
<FILE id="8tLeuntR4" name="FilterGraph.cpp" compile="1" resource="0"
|
||||
file="Source/FilterGraph.cpp"/>
|
||||
<FILE id="auGSxnlTU" name="FilterGraph.h" compile="0" resource="0"
|
||||
file="Source/FilterGraph.h"/>
|
||||
<FILE id="cnfPX5" name="FilterIOConfiguration.cpp" compile="1" resource="0"
|
||||
file="Source/FilterIOConfiguration.cpp"/>
|
||||
<FILE id="ZVUq7Q" name="FilterIOConfiguration.h" compile="0" resource="0"
|
||||
file="Source/FilterIOConfiguration.h"/>
|
||||
<FILE id="2b09bSUt" name="GraphEditorPanel.cpp" compile="1" resource="0"
|
||||
file="Source/GraphEditorPanel.cpp"/>
|
||||
<FILE id="sj8Yug8cu" name="GraphEditorPanel.h" compile="0" resource="0"
|
||||
file="Source/GraphEditorPanel.h"/>
|
||||
<FILE id="nehnGjkrX" name="HostStartup.cpp" compile="1" resource="0"
|
||||
file="Source/HostStartup.cpp"/>
|
||||
<FILE id="J6HWWSQP1" name="InternalFilters.cpp" compile="1" resource="0"
|
||||
file="Source/InternalFilters.cpp"/>
|
||||
<FILE id="AplCcJ0La" name="InternalFilters.h" compile="0" resource="0"
|
||||
file="Source/InternalFilters.h"/>
|
||||
<FILE id="mFVSjbHfN" name="MainHostWindow.cpp" compile="1" resource="0"
|
||||
file="Source/MainHostWindow.cpp"/>
|
||||
<FILE id="h1kpxyzHi" name="MainHostWindow.h" compile="0" resource="0"
|
||||
file="Source/MainHostWindow.h"/>
|
||||
<FILE id="ZwQDmm" name="PluginWindow.h" compile="0" resource="0" file="Source/PluginWindow.h"/>
|
||||
</MAINGROUP>
|
||||
<JUCEOPTIONS JUCE_WASAPI="1" JUCE_DIRECTSOUND="1" JUCE_ALSA="1" JUCE_USE_FLAC="0"
|
||||
JUCE_USE_OGGVORBIS="0" JUCE_USE_CDBURNER="0" JUCE_USE_CDREADER="0"
|
||||
JUCE_USE_CAMERA="0" JUCE_PLUGINHOST_VST="1" JUCE_PLUGINHOST_AU="1"
|
||||
JUCE_WEB_BROWSER="0" JUCE_PLUGINHOST_VST3="1"/>
|
||||
<MODULES>
|
||||
<MODULE id="juce_audio_basics" showAllCode="1"/>
|
||||
<MODULE id="juce_audio_devices" showAllCode="1"/>
|
||||
<MODULE id="juce_audio_formats" showAllCode="1"/>
|
||||
<MODULE id="juce_audio_processors" showAllCode="1"/>
|
||||
<MODULE id="juce_audio_utils" showAllCode="1"/>
|
||||
<MODULE id="juce_core" showAllCode="1"/>
|
||||
<MODULE id="juce_cryptography" showAllCode="1"/>
|
||||
<MODULE id="juce_data_structures" showAllCode="1"/>
|
||||
<MODULE id="juce_events" showAllCode="1"/>
|
||||
<MODULE id="juce_graphics" showAllCode="1"/>
|
||||
<MODULE id="juce_gui_basics" showAllCode="1"/>
|
||||
<MODULE id="juce_gui_extra" showAllCode="1"/>
|
||||
<MODULE id="juce_opengl" showAllCode="1"/>
|
||||
<MODULE id="juce_video" showAllCode="1"/>
|
||||
</MODULES>
|
||||
</JUCERPROJECT>
|
||||
215
extras/AudioPluginHost/Builds/LinuxMakefile/Makefile
Normal file
215
extras/AudioPluginHost/Builds/LinuxMakefile/Makefile
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
# Automatically generated makefile, created by the Projucer
|
||||
# Don't edit this file! Your changes will be overwritten when you re-save the Projucer project!
|
||||
|
||||
# build with "V=1" for verbose builds
|
||||
ifeq ($(V), 1)
|
||||
V_AT =
|
||||
else
|
||||
V_AT = @
|
||||
endif
|
||||
|
||||
# (this disables dependency generation if multiple architectures are set)
|
||||
DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD)
|
||||
|
||||
ifndef STRIP
|
||||
STRIP=strip
|
||||
endif
|
||||
|
||||
ifndef AR
|
||||
AR=ar
|
||||
endif
|
||||
|
||||
ifndef CONFIG
|
||||
CONFIG=Debug
|
||||
endif
|
||||
|
||||
JUCE_ARCH_LABEL := $(shell uname -m)
|
||||
|
||||
ifeq ($(CONFIG),Debug)
|
||||
JUCE_BINDIR := build
|
||||
JUCE_LIBDIR := build
|
||||
JUCE_OBJDIR := build/intermediate/Debug
|
||||
JUCE_OUTDIR := build
|
||||
|
||||
ifeq ($(TARGET_ARCH),)
|
||||
TARGET_ARCH := -march=native
|
||||
endif
|
||||
|
||||
JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DDEBUG=1 -D_DEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama) -pthread -I$(HOME)/SDKs/VST_SDK/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
|
||||
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0
|
||||
JUCE_TARGET_APP := AudioPluginHost
|
||||
|
||||
JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS)
|
||||
JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS)
|
||||
JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa freetype2 libcurl x11 xext xinerama) -lGL -ldl -lpthread -lrt $(LDFLAGS)
|
||||
|
||||
CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG),Release)
|
||||
JUCE_BINDIR := build
|
||||
JUCE_LIBDIR := build
|
||||
JUCE_OBJDIR := build/intermediate/Release
|
||||
JUCE_OUTDIR := build
|
||||
|
||||
ifeq ($(TARGET_ARCH),)
|
||||
TARGET_ARCH := -march=native
|
||||
endif
|
||||
|
||||
JUCE_CPPFLAGS := $(DEPFLAGS) -DLINUX=1 -DNDEBUG=1 -DJUCER_LINUX_MAKE_6D53C8B4=1 -DJUCE_APP_VERSION=1.0.0 -DJUCE_APP_VERSION_HEX=0x10000 $(shell pkg-config --cflags alsa freetype2 libcurl x11 xext xinerama) -pthread -I$(HOME)/SDKs/VST_SDK/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS)
|
||||
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0
|
||||
JUCE_TARGET_APP := AudioPluginHost
|
||||
|
||||
JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -Os $(CFLAGS)
|
||||
JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++14 $(CXXFLAGS)
|
||||
JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -L/usr/X11R6/lib/ $(shell pkg-config --libs alsa freetype2 libcurl x11 xext xinerama) -fvisibility=hidden -lGL -ldl -lpthread -lrt $(LDFLAGS)
|
||||
|
||||
CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)
|
||||
endif
|
||||
|
||||
OBJECTS_APP := \
|
||||
$(JUCE_OBJDIR)/FilterGraph_62e9c017.o \
|
||||
$(JUCE_OBJDIR)/FilterIOConfiguration_1cc9b659.o \
|
||||
$(JUCE_OBJDIR)/GraphEditorPanel_3dbd4872.o \
|
||||
$(JUCE_OBJDIR)/HostStartup_5ce96f96.o \
|
||||
$(JUCE_OBJDIR)/InternalFilters_beb54bdf.o \
|
||||
$(JUCE_OBJDIR)/MainHostWindow_e920295a.o \
|
||||
$(JUCE_OBJDIR)/include_juce_audio_basics_8a4e984a.o \
|
||||
$(JUCE_OBJDIR)/include_juce_audio_devices_63111d02.o \
|
||||
$(JUCE_OBJDIR)/include_juce_audio_formats_15f82001.o \
|
||||
$(JUCE_OBJDIR)/include_juce_audio_processors_10c03666.o \
|
||||
$(JUCE_OBJDIR)/include_juce_audio_utils_9f9fb2d6.o \
|
||||
$(JUCE_OBJDIR)/include_juce_core_f26d17db.o \
|
||||
$(JUCE_OBJDIR)/include_juce_cryptography_8cb807a8.o \
|
||||
$(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o \
|
||||
$(JUCE_OBJDIR)/include_juce_events_fd7d695.o \
|
||||
$(JUCE_OBJDIR)/include_juce_graphics_f817e147.o \
|
||||
$(JUCE_OBJDIR)/include_juce_gui_basics_e3f79785.o \
|
||||
$(JUCE_OBJDIR)/include_juce_gui_extra_6dee1c1a.o \
|
||||
$(JUCE_OBJDIR)/include_juce_opengl_a8a032b.o \
|
||||
$(JUCE_OBJDIR)/include_juce_video_be78589.o \
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP)
|
||||
|
||||
$(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : check-pkg-config $(OBJECTS_APP) $(RESOURCES)
|
||||
@echo Linking "AudioPluginHost - App"
|
||||
-$(V_AT)mkdir -p $(JUCE_BINDIR)
|
||||
-$(V_AT)mkdir -p $(JUCE_LIBDIR)
|
||||
-$(V_AT)mkdir -p $(JUCE_OUTDIR)
|
||||
$(V_AT)$(CXX) -o $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(OBJECTS_APP) $(JUCE_LDFLAGS) $(JUCE_LDFLAGS_APP) $(RESOURCES) $(TARGET_ARCH)
|
||||
|
||||
$(JUCE_OBJDIR)/FilterGraph_62e9c017.o: ../../Source/FilterGraph.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling FilterGraph.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/FilterIOConfiguration_1cc9b659.o: ../../Source/FilterIOConfiguration.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling FilterIOConfiguration.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/GraphEditorPanel_3dbd4872.o: ../../Source/GraphEditorPanel.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling GraphEditorPanel.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/HostStartup_5ce96f96.o: ../../Source/HostStartup.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling HostStartup.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/InternalFilters_beb54bdf.o: ../../Source/InternalFilters.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling InternalFilters.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/MainHostWindow_e920295a.o: ../../Source/MainHostWindow.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling MainHostWindow.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_audio_basics_8a4e984a.o: ../../JuceLibraryCode/include_juce_audio_basics.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_audio_basics.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_audio_devices_63111d02.o: ../../JuceLibraryCode/include_juce_audio_devices.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_audio_devices.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_audio_formats_15f82001.o: ../../JuceLibraryCode/include_juce_audio_formats.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_audio_formats.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_audio_processors_10c03666.o: ../../JuceLibraryCode/include_juce_audio_processors.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_audio_processors.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_audio_utils_9f9fb2d6.o: ../../JuceLibraryCode/include_juce_audio_utils.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_audio_utils.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_core_f26d17db.o: ../../JuceLibraryCode/include_juce_core.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_core.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_cryptography_8cb807a8.o: ../../JuceLibraryCode/include_juce_cryptography.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_cryptography.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_data_structures_7471b1e3.o: ../../JuceLibraryCode/include_juce_data_structures.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_data_structures.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_events_fd7d695.o: ../../JuceLibraryCode/include_juce_events.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_events.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_graphics_f817e147.o: ../../JuceLibraryCode/include_juce_graphics.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_graphics.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_gui_basics_e3f79785.o: ../../JuceLibraryCode/include_juce_gui_basics.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_gui_basics.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_gui_extra_6dee1c1a.o: ../../JuceLibraryCode/include_juce_gui_extra.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_gui_extra.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_opengl_a8a032b.o: ../../JuceLibraryCode/include_juce_opengl.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_opengl.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
$(JUCE_OBJDIR)/include_juce_video_be78589.o: ../../JuceLibraryCode/include_juce_video.cpp
|
||||
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
|
||||
@echo "Compiling include_juce_video.cpp"
|
||||
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
|
||||
|
||||
check-pkg-config:
|
||||
@command -v pkg-config >/dev/null 2>&1 || { echo >&2 "pkg-config not installed. Please, install it."; exit 1; }
|
||||
@pkg-config --print-errors alsa freetype2 libcurl x11 xext xinerama
|
||||
|
||||
clean:
|
||||
@echo Cleaning AudioPluginHost
|
||||
$(V_AT)$(CLEANCMD)
|
||||
|
||||
strip:
|
||||
@echo Stripping AudioPluginHost
|
||||
-$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET)
|
||||
|
||||
-include $(OBJECTS_APP:%.o=%.d)
|
||||
|
|
@ -0,0 +1,376 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
FCDB1F8A93F59E0F97821456 = {isa = PBXBuildFile; fileRef = 8D8BBC353637DA442C5575DA; };
|
||||
73E371F1B912FCCAE0CD7E5D = {isa = PBXBuildFile; fileRef = 86CA337014D3F67E906FFD28; };
|
||||
21D330A5B13178B12BEAFC3C = {isa = PBXBuildFile; fileRef = D4EBC17BDB7F88CCBC76730B; };
|
||||
B288A89F96704F142ED8E939 = {isa = PBXBuildFile; fileRef = 5ACC21AA45BBF48C3C64D56D; };
|
||||
851C1165C9E4ACDD19C56A96 = {isa = PBXBuildFile; fileRef = 942A0F04EFB8D0B2FF9780BA; };
|
||||
AF42316D915057E930A5624E = {isa = PBXBuildFile; fileRef = A4B568E26157FC282214976F; };
|
||||
2B4B9CF71F94BDD1E3AC89AE = {isa = PBXBuildFile; fileRef = B0935EBBA4F6E2B05F3D1C0A; };
|
||||
AC3BED74AC7C6D9F5739F38B = {isa = PBXBuildFile; fileRef = 9794142D24966F93FFDE51A1; };
|
||||
E3CB85BA817BC9E3942A8AB0 = {isa = PBXBuildFile; fileRef = 9F9B445E6755CAA19E4344ED; };
|
||||
70580743C3D5695F065FF698 = {isa = PBXBuildFile; fileRef = E68018DE199135B7F738FB17; };
|
||||
3470F40DA5D68EC217872906 = {isa = PBXBuildFile; fileRef = 31D55A751C790CB81F58DDB7; };
|
||||
E092A70431B046BF1F50A482 = {isa = PBXBuildFile; fileRef = 5AF0CA7CDFCA90B4DE1F55C3; };
|
||||
E2BAA7CFC729809530FD71EE = {isa = PBXBuildFile; fileRef = B8774D8AD307D798831C0DF7; };
|
||||
68FBFDA1FE637B3EDA09A592 = {isa = PBXBuildFile; fileRef = 4DF6E6E41E10965AD169143B; };
|
||||
BBA1733CF8B064A5FD0B4CF4 = {isa = PBXBuildFile; fileRef = D313CF37B25D7FD313C4F336; };
|
||||
A02C9F4C4B840C27B6CAFEBD = {isa = PBXBuildFile; fileRef = 89309C0C5F3269BD06BE7F27; };
|
||||
4DB15177DDC357F4503F88CF = {isa = PBXBuildFile; fileRef = B457EE687507BF1DEEA7581F; };
|
||||
D92C7BF86C9CCF6B4D14F809 = {isa = PBXBuildFile; fileRef = 7DA35787B5F6F7440D667CC8; };
|
||||
4C88899EB7993A76A97643FE = {isa = PBXBuildFile; fileRef = 9BA1DD697B98005D24F7EC3C; };
|
||||
485A37478F7EAA352DD1A86A = {isa = PBXBuildFile; fileRef = 01FE7ED58992BC9683BA3C94; };
|
||||
040EB574807E8A86F124D851 = {isa = PBXBuildFile; fileRef = B1C6B9E4B9FDC17AA298E541; };
|
||||
A1B0416DA378BB0C3AD6F74B = {isa = PBXBuildFile; fileRef = A66EFAC64B1B67B536C73415; };
|
||||
D493393499E0822C70009A63 = {isa = PBXBuildFile; fileRef = 362BB539489999164C3A3D5B; };
|
||||
6CD3B433544911DA879170AE = {isa = PBXBuildFile; fileRef = 1EC0F33A3BABE58138317375; };
|
||||
15CCE43D7DCFC649638919D4 = {isa = PBXBuildFile; fileRef = 4C7D82F9274A4F9DBF11235C; };
|
||||
5C4D406B924230F83E3580AD = {isa = PBXBuildFile; fileRef = 65968EA1B476D71F14DE1D58; };
|
||||
F4DD98B9310B679D50A2C8A6 = {isa = PBXBuildFile; fileRef = 5D250A57C7DEA80248F30EED; };
|
||||
CAF0DE157C8F7D9F168AA3B6 = {isa = PBXBuildFile; fileRef = 5FBD6C402617272052BB4D81; };
|
||||
0F20A4AE04736634F097F5A6 = {isa = PBXBuildFile; fileRef = B285CAB91AE928C476CA4F9C; };
|
||||
76A80851698FC773D2479B4E = {isa = PBXBuildFile; fileRef = 683CEE986A2467C850FE99E6; };
|
||||
E4A926EF695823F0F13268FF = {isa = PBXBuildFile; fileRef = B8E24A5CEE6B7055537725CF; };
|
||||
A09E93F1B354E1FF8B3E9ABE = {isa = PBXBuildFile; fileRef = 5EF1D381F42AA8764597F189; };
|
||||
7DE202DC1D876F49266D9E7D = {isa = PBXBuildFile; fileRef = 8290D7BAC160B3A56B66891A; };
|
||||
075C54DDDBDEA5AAD2F60154 = {isa = PBXBuildFile; fileRef = 82800DBA287EF4BAB13B42FB; };
|
||||
2C3D221D2AA87F07B3F1044D = {isa = PBXBuildFile; fileRef = 8FE7B37CDE0818DB27BDDEBD; };
|
||||
C38D14DC58F1941DD5E4BF60 = {isa = PBXBuildFile; fileRef = 2BE6C2DFD6EBB9A89109AEB5; };
|
||||
2727A191DB1BAAC9C04B9081 = {isa = PBXBuildFile; fileRef = 37E4D5C341406B7072120006; };
|
||||
84BAFE82A102D9C350672689 = {isa = PBXBuildFile; fileRef = 29D746FC68F69751796671A2; };
|
||||
01FE7ED58992BC9683BA3C94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterIOConfiguration.cpp; path = ../../Source/FilterIOConfiguration.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
18DD15714443AFC3BAAE211C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterIOConfiguration.h; path = ../../Source/FilterIOConfiguration.h; sourceTree = "SOURCE_ROOT"; };
|
||||
1EC0F33A3BABE58138317375 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MainHostWindow.cpp; path = ../../Source/MainHostWindow.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
29D746FC68F69751796671A2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_video.mm"; path = "../../JuceLibraryCode/include_juce_video.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
2B143B5431318DDB2104B46E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FilterGraph.h; path = ../../Source/FilterGraph.h; sourceTree = "SOURCE_ROOT"; };
|
||||
2BE6C2DFD6EBB9A89109AEB5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_extra.mm"; path = "../../JuceLibraryCode/include_juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
30F22843EFEBF7AA841EB4D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
|
||||
31D55A751C790CB81F58DDB7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
||||
362BB539489999164C3A3D5B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InternalFilters.cpp; path = ../../Source/InternalFilters.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
37E4D5C341406B7072120006 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_opengl.mm"; path = "../../JuceLibraryCode/include_juce_opengl.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
3C070DD522CDD11FFC87425D = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_utils"; path = "../../../../modules/juce_audio_utils"; sourceTree = "SOURCE_ROOT"; };
|
||||
3D57FE2A8877F12A61054726 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_core"; path = "../../../../modules/juce_core"; sourceTree = "SOURCE_ROOT"; };
|
||||
4C7D82F9274A4F9DBF11235C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_basics.mm"; path = "../../JuceLibraryCode/include_juce_audio_basics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
4DF6E6E41E10965AD169143B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
5313EB852E41EE58B199B9A2 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_devices"; path = "../../../../modules/juce_audio_devices"; sourceTree = "SOURCE_ROOT"; };
|
||||
57DF618F1DE781556B7AFC32 = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = "SOURCE_ROOT"; };
|
||||
59842A98E5EBBC54B50C04CD = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_events"; path = "../../../../modules/juce_events"; sourceTree = "SOURCE_ROOT"; };
|
||||
5ACC21AA45BBF48C3C64D56D = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
5AF0CA7CDFCA90B4DE1F55C3 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
|
||||
5D250A57C7DEA80248F30EED = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_formats.mm"; path = "../../JuceLibraryCode/include_juce_audio_formats.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
5EF1D381F42AA8764597F189 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
5FBD6C402617272052BB4D81 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_processors.mm"; path = "../../JuceLibraryCode/include_juce_audio_processors.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
65968EA1B476D71F14DE1D58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_devices.mm"; path = "../../JuceLibraryCode/include_juce_audio_devices.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
6692043E22BB181F01767845 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainHostWindow.h; path = ../../Source/MainHostWindow.h; sourceTree = "SOURCE_ROOT"; };
|
||||
683CEE986A2467C850FE99E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_core.mm"; path = "../../JuceLibraryCode/include_juce_core.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
6A71B2BCAC4239072BC2BD7E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_basics"; path = "../../../../modules/juce_audio_basics"; sourceTree = "SOURCE_ROOT"; };
|
||||
714C53257417E615916687E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginWindow.h; path = ../../Source/PluginWindow.h; sourceTree = "SOURCE_ROOT"; };
|
||||
7DA35787B5F6F7440D667CC8 = {isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; };
|
||||
81C1A7770E082F56FE5A90A7 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_opengl"; path = "../../../../modules/juce_opengl"; sourceTree = "SOURCE_ROOT"; };
|
||||
82800DBA287EF4BAB13B42FB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
8290D7BAC160B3A56B66891A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_events.mm"; path = "../../JuceLibraryCode/include_juce_events.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
86CA337014D3F67E906FFD28 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||
89309C0C5F3269BD06BE7F27 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
8D8BBC353637DA442C5575DA = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AudioPluginHost.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
|
||||
8FE7B37CDE0818DB27BDDEBD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_gui_basics.mm"; path = "../../JuceLibraryCode/include_juce_gui_basics.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
938AE72315C6C93949F6220E = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_basics"; path = "../../../../modules/juce_gui_basics"; sourceTree = "SOURCE_ROOT"; };
|
||||
942A0F04EFB8D0B2FF9780BA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
||||
94CB96C8E4B51F52776C2638 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_graphics"; path = "../../../../modules/juce_graphics"; sourceTree = "SOURCE_ROOT"; };
|
||||
9794142D24966F93FFDE51A1 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
9BA1DD697B98005D24F7EC3C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FilterGraph.cpp; path = ../../Source/FilterGraph.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
9F9B445E6755CAA19E4344ED = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
A4B568E26157FC282214976F = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; };
|
||||
A5E7CA8A71D049BE2BD33861 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = "SOURCE_ROOT"; };
|
||||
A66EFAC64B1B67B536C73415 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HostStartup.cpp; path = ../../Source/HostStartup.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
B0935EBBA4F6E2B05F3D1C0A = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
|
||||
B1C6B9E4B9FDC17AA298E541 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GraphEditorPanel.cpp; path = ../../Source/GraphEditorPanel.cpp; sourceTree = "SOURCE_ROOT"; };
|
||||
B285CAB91AE928C476CA4F9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_audio_utils.mm"; path = "../../JuceLibraryCode/include_juce_audio_utils.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
B457EE687507BF1DEEA7581F = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
|
||||
B86B918291E1090C6A720971 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_data_structures"; path = "../../../../modules/juce_data_structures"; sourceTree = "SOURCE_ROOT"; };
|
||||
B8774D8AD307D798831C0DF7 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; };
|
||||
B8E24A5CEE6B7055537725CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_cryptography.mm"; path = "../../JuceLibraryCode/include_juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; };
|
||||
D313CF37B25D7FD313C4F336 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
D4EBC17BDB7F88CCBC76730B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
DD8E5D0C88FA2C287F824357 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GraphEditorPanel.h; path = ../../Source/GraphEditorPanel.h; sourceTree = "SOURCE_ROOT"; };
|
||||
DDE115D3084ACA6DD6AA4471 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_video"; path = "../../../../modules/juce_video"; sourceTree = "SOURCE_ROOT"; };
|
||||
E68018DE199135B7F738FB17 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
|
||||
EE1BEF4055936CD0C543687C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InternalFilters.h; path = ../../Source/InternalFilters.h; sourceTree = "SOURCE_ROOT"; };
|
||||
F299BECFB2AEA6105F014848 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_gui_extra"; path = "../../../../modules/juce_gui_extra"; sourceTree = "SOURCE_ROOT"; };
|
||||
F9AC862E9A3583B6C1488EE0 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_formats"; path = "../../../../modules/juce_audio_formats"; sourceTree = "SOURCE_ROOT"; };
|
||||
FA21631C5536EA3DF55C7FA6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_cryptography"; path = "../../../../modules/juce_cryptography"; sourceTree = "SOURCE_ROOT"; };
|
||||
FAF867E9E731D0880D40511F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_audio_processors"; path = "../../../../modules/juce_audio_processors"; sourceTree = "SOURCE_ROOT"; };
|
||||
97790EAEA01CFA5C3CA9737A = {isa = PBXGroup; children = (
|
||||
9BA1DD697B98005D24F7EC3C,
|
||||
2B143B5431318DDB2104B46E,
|
||||
01FE7ED58992BC9683BA3C94,
|
||||
18DD15714443AFC3BAAE211C,
|
||||
B1C6B9E4B9FDC17AA298E541,
|
||||
DD8E5D0C88FA2C287F824357,
|
||||
A66EFAC64B1B67B536C73415,
|
||||
362BB539489999164C3A3D5B,
|
||||
EE1BEF4055936CD0C543687C,
|
||||
1EC0F33A3BABE58138317375,
|
||||
6692043E22BB181F01767845,
|
||||
714C53257417E615916687E5, ); name = AudioPluginHost; sourceTree = "<group>"; };
|
||||
9D8FE1F65CAD416AA606C47A = {isa = PBXGroup; children = (
|
||||
6A71B2BCAC4239072BC2BD7E,
|
||||
5313EB852E41EE58B199B9A2,
|
||||
F9AC862E9A3583B6C1488EE0,
|
||||
FAF867E9E731D0880D40511F,
|
||||
3C070DD522CDD11FFC87425D,
|
||||
3D57FE2A8877F12A61054726,
|
||||
FA21631C5536EA3DF55C7FA6,
|
||||
B86B918291E1090C6A720971,
|
||||
59842A98E5EBBC54B50C04CD,
|
||||
94CB96C8E4B51F52776C2638,
|
||||
938AE72315C6C93949F6220E,
|
||||
F299BECFB2AEA6105F014848,
|
||||
81C1A7770E082F56FE5A90A7,
|
||||
DDE115D3084ACA6DD6AA4471, ); name = "JUCE Modules"; sourceTree = "<group>"; };
|
||||
7E30376DDAD775FEFE64944C = {isa = PBXGroup; children = (
|
||||
30F22843EFEBF7AA841EB4D6,
|
||||
4C7D82F9274A4F9DBF11235C,
|
||||
65968EA1B476D71F14DE1D58,
|
||||
5D250A57C7DEA80248F30EED,
|
||||
5FBD6C402617272052BB4D81,
|
||||
B285CAB91AE928C476CA4F9C,
|
||||
683CEE986A2467C850FE99E6,
|
||||
B8E24A5CEE6B7055537725CF,
|
||||
5EF1D381F42AA8764597F189,
|
||||
8290D7BAC160B3A56B66891A,
|
||||
82800DBA287EF4BAB13B42FB,
|
||||
8FE7B37CDE0818DB27BDDEBD,
|
||||
2BE6C2DFD6EBB9A89109AEB5,
|
||||
37E4D5C341406B7072120006,
|
||||
29D746FC68F69751796671A2,
|
||||
A5E7CA8A71D049BE2BD33861, ); name = "JUCE Library Code"; sourceTree = "<group>"; };
|
||||
A97EE73C79DA3F729D46AF48 = {isa = PBXGroup; children = (
|
||||
57DF618F1DE781556B7AFC32,
|
||||
7DA35787B5F6F7440D667CC8, ); name = Resources; sourceTree = "<group>"; };
|
||||
D1C4804CD275CB57A5C89A2D = {isa = PBXGroup; children = (
|
||||
86CA337014D3F67E906FFD28,
|
||||
D4EBC17BDB7F88CCBC76730B,
|
||||
5ACC21AA45BBF48C3C64D56D,
|
||||
942A0F04EFB8D0B2FF9780BA,
|
||||
A4B568E26157FC282214976F,
|
||||
B0935EBBA4F6E2B05F3D1C0A,
|
||||
9794142D24966F93FFDE51A1,
|
||||
9F9B445E6755CAA19E4344ED,
|
||||
E68018DE199135B7F738FB17,
|
||||
31D55A751C790CB81F58DDB7,
|
||||
5AF0CA7CDFCA90B4DE1F55C3,
|
||||
B8774D8AD307D798831C0DF7,
|
||||
4DF6E6E41E10965AD169143B,
|
||||
D313CF37B25D7FD313C4F336,
|
||||
89309C0C5F3269BD06BE7F27,
|
||||
B457EE687507BF1DEEA7581F, ); name = Frameworks; sourceTree = "<group>"; };
|
||||
D85C0D11EE4F6C73B9EB5BCD = {isa = PBXGroup; children = (
|
||||
8D8BBC353637DA442C5575DA, ); name = Products; sourceTree = "<group>"; };
|
||||
65BEFC705A89E5C8A9E35C97 = {isa = PBXGroup; children = (
|
||||
97790EAEA01CFA5C3CA9737A,
|
||||
9D8FE1F65CAD416AA606C47A,
|
||||
7E30376DDAD775FEFE64944C,
|
||||
A97EE73C79DA3F729D46AF48,
|
||||
D1C4804CD275CB57A5C89A2D,
|
||||
D85C0D11EE4F6C73B9EB5BCD, ); name = Source; sourceTree = "<group>"; };
|
||||
C8B793AC1BEFBE7A99BE8352 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_DEBUG=1",
|
||||
"DEBUG=1",
|
||||
"JUCER_XCODE_MAC_F6D2F4CF=1",
|
||||
"JUCE_APP_VERSION=1.0.0",
|
||||
"JUCE_APP_VERSION_HEX=0x10000",
|
||||
"JucePlugin_Build_VST=0",
|
||||
"JucePlugin_Build_VST3=0",
|
||||
"JucePlugin_Build_AU=0",
|
||||
"JucePlugin_Build_AUv3=0",
|
||||
"JucePlugin_Build_RTAS=0",
|
||||
"JucePlugin_Build_AAX=0",
|
||||
"JucePlugin_Build_Standalone=0", );
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
HEADER_SEARCH_PATHS = ("~/SDKs/VST_SDK/VST3_SDK", "../../JuceLibraryCode", "../../../../modules", "$(inherited)");
|
||||
INFOPLIST_FILE = Info-App.plist;
|
||||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
|
||||
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.roli.pluginhost;
|
||||
SDKROOT_ppc = macosx10.5;
|
||||
USE_HEADERMAP = NO; }; name = Debug; };
|
||||
49453CC5AD9F08D2738464AC = {isa = XCBuildConfiguration; buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = s;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"_NDEBUG=1",
|
||||
"NDEBUG=1",
|
||||
"JUCER_XCODE_MAC_F6D2F4CF=1",
|
||||
"JUCE_APP_VERSION=1.0.0",
|
||||
"JUCE_APP_VERSION_HEX=0x10000",
|
||||
"JucePlugin_Build_VST=0",
|
||||
"JucePlugin_Build_VST3=0",
|
||||
"JucePlugin_Build_AU=0",
|
||||
"JucePlugin_Build_AUv3=0",
|
||||
"JucePlugin_Build_RTAS=0",
|
||||
"JucePlugin_Build_AAX=0",
|
||||
"JucePlugin_Build_Standalone=0", );
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
HEADER_SEARCH_PATHS = ("~/SDKs/VST_SDK/VST3_SDK", "../../JuceLibraryCode", "../../../../modules", "$(inherited)");
|
||||
INFOPLIST_FILE = Info-App.plist;
|
||||
INFOPLIST_PREPROCESS = NO;
|
||||
INSTALL_PATH = "$(HOME)/Applications";
|
||||
LLVM_LTO = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
|
||||
OTHER_CPLUSPLUSFLAGS = "-Wall -Wshadow -Wstrict-aliasing -Wconversion -Wsign-compare -Woverloaded-virtual -Wextra-semi";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.roli.pluginhost;
|
||||
SDKROOT_ppc = macosx10.5;
|
||||
USE_HEADERMAP = NO; }; name = Release; };
|
||||
8D1CA827F1EFD443BDCF198A = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MISSING_PARENTHESES = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "AudioPluginHost";
|
||||
WARNING_CFLAGS = -Wreorder;
|
||||
ZERO_LINK = NO; }; name = Debug; };
|
||||
C9295196717FABE454A210B7 = {isa = XCBuildConfiguration; buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c11;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MISSING_PARENTHESES = YES;
|
||||
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
|
||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PRODUCT_NAME = "AudioPluginHost";
|
||||
WARNING_CFLAGS = -Wreorder;
|
||||
ZERO_LINK = NO; }; name = Release; };
|
||||
B9D79D85AC7DE5BED1B6547C = {isa = PBXTargetDependency; target = DE12B7643D374BFF7E4FEB1C; };
|
||||
493C2C5E457692E5149C5525 = {isa = XCConfigurationList; buildConfigurations = (
|
||||
8D1CA827F1EFD443BDCF198A,
|
||||
C9295196717FABE454A210B7, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
|
||||
E4ECAE24A646A7D1585F776C = {isa = XCConfigurationList; buildConfigurations = (
|
||||
C8B793AC1BEFBE7A99BE8352,
|
||||
49453CC5AD9F08D2738464AC, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; };
|
||||
2429BB4D705CC57F49418CFB = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = (
|
||||
D92C7BF86C9CCF6B4D14F809, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
E8E94B3C187DA578BFCBDA98 = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
|
||||
4C88899EB7993A76A97643FE,
|
||||
485A37478F7EAA352DD1A86A,
|
||||
040EB574807E8A86F124D851,
|
||||
A1B0416DA378BB0C3AD6F74B,
|
||||
D493393499E0822C70009A63,
|
||||
6CD3B433544911DA879170AE,
|
||||
15CCE43D7DCFC649638919D4,
|
||||
5C4D406B924230F83E3580AD,
|
||||
F4DD98B9310B679D50A2C8A6,
|
||||
CAF0DE157C8F7D9F168AA3B6,
|
||||
0F20A4AE04736634F097F5A6,
|
||||
76A80851698FC773D2479B4E,
|
||||
E4A926EF695823F0F13268FF,
|
||||
A09E93F1B354E1FF8B3E9ABE,
|
||||
7DE202DC1D876F49266D9E7D,
|
||||
075C54DDDBDEA5AAD2F60154,
|
||||
2C3D221D2AA87F07B3F1044D,
|
||||
C38D14DC58F1941DD5E4BF60,
|
||||
2727A191DB1BAAC9C04B9081,
|
||||
84BAFE82A102D9C350672689, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
C515A1FE1A53D3968C22FAEF = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (
|
||||
73E371F1B912FCCAE0CD7E5D,
|
||||
21D330A5B13178B12BEAFC3C,
|
||||
B288A89F96704F142ED8E939,
|
||||
851C1165C9E4ACDD19C56A96,
|
||||
AF42316D915057E930A5624E,
|
||||
2B4B9CF71F94BDD1E3AC89AE,
|
||||
AC3BED74AC7C6D9F5739F38B,
|
||||
E3CB85BA817BC9E3942A8AB0,
|
||||
70580743C3D5695F065FF698,
|
||||
3470F40DA5D68EC217872906,
|
||||
E092A70431B046BF1F50A482,
|
||||
E2BAA7CFC729809530FD71EE,
|
||||
68FBFDA1FE637B3EDA09A592,
|
||||
BBA1733CF8B064A5FD0B4CF4,
|
||||
A02C9F4C4B840C27B6CAFEBD,
|
||||
4DB15177DDC357F4503F88CF, ); runOnlyForDeploymentPostprocessing = 0; };
|
||||
DE12B7643D374BFF7E4FEB1C = {isa = PBXNativeTarget; buildConfigurationList = E4ECAE24A646A7D1585F776C; buildPhases = (
|
||||
2429BB4D705CC57F49418CFB,
|
||||
E8E94B3C187DA578BFCBDA98,
|
||||
C515A1FE1A53D3968C22FAEF, ); buildRules = ( ); dependencies = ( ); name = "AudioPluginHost - App"; productName = AudioPluginHost; productReference = 8D8BBC353637DA442C5575DA; productType = "com.apple.product-type.application"; };
|
||||
ADE6E539DB98A302483A82D0 = {isa = PBXProject; buildConfigurationList = 493C2C5E457692E5149C5525; attributes = { LastUpgradeCheck = 0830; ORGANIZATIONNAME = "ROLI Ltd."; TargetAttributes = { DE12B7643D374BFF7E4FEB1C = { SystemCapabilities = {com.apple.ApplicationGroups.iOS = { enabled = 0; }; com.apple.InAppPurchase = { enabled = 0; }; com.apple.InterAppAudio = { enabled = 0; }; com.apple.Push = { enabled = 0; }; com.apple.Sandbox = { enabled = 0; }; }; }; }; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = 65BEFC705A89E5C8A9E35C97; projectDirPath = ""; projectRoot = ""; targets = (DE12B7643D374BFF7E4FEB1C); };
|
||||
};
|
||||
rootObject = ADE6E539DB98A302483A82D0;
|
||||
}
|
||||
29
extras/AudioPluginHost/Builds/MacOSX/Info-App.plist
Normal file
29
extras/AudioPluginHost/Builds/MacOSX/Info-App.plist
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist>
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.roli.pluginhost</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>AudioPluginHost</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>AudioPluginHost</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>ROLI Ltd.</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
extras/AudioPluginHost/Builds/MacOSX/RecentFilesMenuTemplate.nib
generated
Normal file
BIN
extras/AudioPluginHost/Builds/MacOSX/RecentFilesMenuTemplate.nib
generated
Normal file
Binary file not shown.
|
|
@ -0,0 +1,20 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2013
|
||||
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioPluginHost - App", "AudioPluginHost_App.vcxproj", "{5666EAA2-C82B-D06A-5228-D0E810428536}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
31
extras/AudioPluginHost/Builds/VisualStudio2013/resources.rc
Normal file
31
extras/AudioPluginHost/Builds/VisualStudio2013/resources.rc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifdef JUCE_USER_DEFINED_RC_FILE
|
||||
#include JUCE_USER_DEFINED_RC_FILE
|
||||
#else
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "ROLI Ltd.\0"
|
||||
VALUE "LegalCopyright", "ROLI Ltd.\0"
|
||||
VALUE "FileDescription", "AudioPluginHost\0"
|
||||
VALUE "FileVersion", "1.0.0\0"
|
||||
VALUE "ProductName", "AudioPluginHost\0"
|
||||
VALUE "ProductVersion", "1.0.0\0"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2015
|
||||
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioPluginHost - App", "AudioPluginHost_App.vcxproj", "{5666EAA2-C82B-D06A-5228-D0E810428536}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Debug|x64.Build.0 = Debug|x64
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Release|x64.ActiveCfg = Release|x64
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
31
extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc
Normal file
31
extras/AudioPluginHost/Builds/VisualStudio2015/resources.rc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifdef JUCE_USER_DEFINED_RC_FILE
|
||||
#include JUCE_USER_DEFINED_RC_FILE
|
||||
#else
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "ROLI Ltd.\0"
|
||||
VALUE "LegalCopyright", "ROLI Ltd.\0"
|
||||
VALUE "FileDescription", "AudioPluginHost\0"
|
||||
VALUE "FileVersion", "1.0.0\0"
|
||||
VALUE "ProductName", "AudioPluginHost\0"
|
||||
VALUE "ProductVersion", "1.0.0\0"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2017
|
||||
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioPluginHost - App", "AudioPluginHost_App.vcxproj", "{5666EAA2-C82B-D06A-5228-D0E810428536}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Debug|x64.Build.0 = Debug|x64
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Release|x64.ActiveCfg = Release|x64
|
||||
{5666EAA2-C82B-D06A-5228-D0E810428536}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
31
extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc
Normal file
31
extras/AudioPluginHost/Builds/VisualStudio2017/resources.rc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifdef JUCE_USER_DEFINED_RC_FILE
|
||||
#include JUCE_USER_DEFINED_RC_FILE
|
||||
#else
|
||||
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "ROLI Ltd.\0"
|
||||
VALUE "LegalCopyright", "ROLI Ltd.\0"
|
||||
VALUE "FileDescription", "AudioPluginHost\0"
|
||||
VALUE "FileVersion", "1.0.0\0"
|
||||
VALUE "ProductName", "AudioPluginHost\0"
|
||||
VALUE "ProductVersion", "1.0.0\0"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#endif
|
||||
264
extras/AudioPluginHost/JuceLibraryCode/AppConfig.h
Normal file
264
extras/AudioPluginHost/JuceLibraryCode/AppConfig.h
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
There's a section below where you can add your own custom code safely, and the
|
||||
Projucer will preserve the contents of that block, but the best way to change
|
||||
any of these definitions is by using the Projucer's project settings.
|
||||
|
||||
Any commented-out settings will assume their default values.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//==============================================================================
|
||||
// [BEGIN_USER_CODE_SECTION]
|
||||
|
||||
// (You can add your own code in this section, and the Projucer will not overwrite it)
|
||||
|
||||
// [END_USER_CODE_SECTION]
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
In accordance with the terms of the JUCE 5 End-Use License Agreement, the
|
||||
JUCE Code in SECTION A cannot be removed, changed or otherwise rendered
|
||||
ineffective unless you have a JUCE Indie or Pro license, or are using JUCE
|
||||
under the GPL v3 license.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// BEGIN SECTION A
|
||||
|
||||
#ifndef JUCE_DISPLAY_SPLASH_SCREEN
|
||||
#define JUCE_DISPLAY_SPLASH_SCREEN 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_REPORT_APP_USAGE
|
||||
#define JUCE_REPORT_APP_USAGE 0
|
||||
#endif
|
||||
|
||||
// END SECTION A
|
||||
|
||||
#define JUCE_USE_DARK_SPLASH_SCREEN 1
|
||||
|
||||
//==============================================================================
|
||||
#define JUCE_MODULE_AVAILABLE_juce_audio_basics 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_audio_devices 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_audio_formats 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_audio_processors 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_audio_utils 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_core 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_cryptography 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_data_structures 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_events 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_graphics 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_opengl 1
|
||||
#define JUCE_MODULE_AVAILABLE_juce_video 1
|
||||
|
||||
#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_devices flags:
|
||||
|
||||
#ifndef JUCE_ASIO
|
||||
//#define JUCE_ASIO 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_WASAPI
|
||||
#define JUCE_WASAPI 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_WASAPI_EXCLUSIVE
|
||||
//#define JUCE_WASAPI_EXCLUSIVE 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_DIRECTSOUND
|
||||
#define JUCE_DIRECTSOUND 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_ALSA
|
||||
#define JUCE_ALSA 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_JACK
|
||||
//#define JUCE_JACK 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_ANDROID_OBOE
|
||||
//#define JUCE_USE_ANDROID_OBOE 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_ANDROID_OPENSLES
|
||||
//#define JUCE_USE_ANDROID_OPENSLES 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_WINRT_MIDI
|
||||
//#define JUCE_USE_WINRT_MIDI 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS
|
||||
//#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_formats flags:
|
||||
|
||||
#ifndef JUCE_USE_FLAC
|
||||
#define JUCE_USE_FLAC 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_OGGVORBIS
|
||||
#define JUCE_USE_OGGVORBIS 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_MP3AUDIOFORMAT
|
||||
//#define JUCE_USE_MP3AUDIOFORMAT 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_LAME_AUDIO_FORMAT
|
||||
//#define JUCE_USE_LAME_AUDIO_FORMAT 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT
|
||||
//#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_processors flags:
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_VST
|
||||
#define JUCE_PLUGINHOST_VST 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_VST3
|
||||
#define JUCE_PLUGINHOST_VST3 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_PLUGINHOST_AU
|
||||
#define JUCE_PLUGINHOST_AU 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_audio_utils flags:
|
||||
|
||||
#ifndef JUCE_USE_CDREADER
|
||||
#define JUCE_USE_CDREADER 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_CDBURNER
|
||||
#define JUCE_USE_CDBURNER 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_core flags:
|
||||
|
||||
#ifndef JUCE_FORCE_DEBUG
|
||||
//#define JUCE_FORCE_DEBUG 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_LOG_ASSERTIONS
|
||||
//#define JUCE_LOG_ASSERTIONS 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_CHECK_MEMORY_LEAKS
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
||||
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_INCLUDE_ZLIB_CODE
|
||||
//#define JUCE_INCLUDE_ZLIB_CODE 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_CURL
|
||||
//#define JUCE_USE_CURL 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES
|
||||
//#define JUCE_ALLOW_STATIC_NULL_VARIABLES 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_events flags:
|
||||
|
||||
#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
|
||||
//#define JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_graphics flags:
|
||||
|
||||
#ifndef JUCE_USE_COREIMAGE_LOADER
|
||||
//#define JUCE_USE_COREIMAGE_LOADER 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_DIRECTWRITE
|
||||
//#define JUCE_USE_DIRECTWRITE 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_gui_basics flags:
|
||||
|
||||
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
|
||||
//#define JUCE_ENABLE_REPAINT_DEBUGGING 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XRANDR
|
||||
//#define JUCE_USE_XRANDR 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XINERAMA
|
||||
//#define JUCE_USE_XINERAMA 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XSHM
|
||||
//#define JUCE_USE_XSHM 1
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XRENDER
|
||||
//#define JUCE_USE_XRENDER 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_USE_XCURSOR
|
||||
//#define JUCE_USE_XCURSOR 1
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_gui_extra flags:
|
||||
|
||||
#ifndef JUCE_WEB_BROWSER
|
||||
#define JUCE_WEB_BROWSER 0
|
||||
#endif
|
||||
|
||||
#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
|
||||
//#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// juce_video flags:
|
||||
|
||||
#ifndef JUCE_USE_CAMERA
|
||||
#define JUCE_USE_CAMERA 0
|
||||
#endif
|
||||
//==============================================================================
|
||||
#ifndef JUCE_STANDALONE_APPLICATION
|
||||
#if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)
|
||||
#define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone
|
||||
#else
|
||||
#define JUCE_STANDALONE_APPLICATION 1
|
||||
#endif
|
||||
#endif
|
||||
46
extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h
Normal file
46
extras/AudioPluginHost/JuceLibraryCode/JuceHeader.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
This is the header file that your files should include in order to get all the
|
||||
JUCE library headers. You should avoid including the JUCE headers directly in
|
||||
your own source files, because that wouldn't pick up the correct configuration
|
||||
options for your app.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AppConfig.h"
|
||||
|
||||
#include <juce_audio_basics/juce_audio_basics.h>
|
||||
#include <juce_audio_devices/juce_audio_devices.h>
|
||||
#include <juce_audio_formats/juce_audio_formats.h>
|
||||
#include <juce_audio_processors/juce_audio_processors.h>
|
||||
#include <juce_audio_utils/juce_audio_utils.h>
|
||||
#include <juce_core/juce_core.h>
|
||||
#include <juce_cryptography/juce_cryptography.h>
|
||||
#include <juce_data_structures/juce_data_structures.h>
|
||||
#include <juce_events/juce_events.h>
|
||||
#include <juce_graphics/juce_graphics.h>
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
#include <juce_gui_extra/juce_gui_extra.h>
|
||||
#include <juce_opengl/juce_opengl.h>
|
||||
#include <juce_video/juce_video.h>
|
||||
|
||||
|
||||
#if ! DONT_SET_USING_JUCE_NAMESPACE
|
||||
// If your code uses a lot of JUCE classes, then this will obviously save you
|
||||
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
|
||||
using namespace juce;
|
||||
#endif
|
||||
|
||||
#if ! JUCE_DONT_DECLARE_PROJECTINFO
|
||||
namespace ProjectInfo
|
||||
{
|
||||
const char* const projectName = "AudioPluginHost";
|
||||
const char* const versionString = "1.0.0";
|
||||
const int versionNumber = 0x10000;
|
||||
}
|
||||
#endif
|
||||
12
extras/AudioPluginHost/JuceLibraryCode/ReadMe.txt
Normal file
12
extras/AudioPluginHost/JuceLibraryCode/ReadMe.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
Important Note!!
|
||||
================
|
||||
|
||||
The purpose of this folder is to contain files that are auto-generated by the Projucer,
|
||||
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
|
||||
the Projucer saves your project.
|
||||
|
||||
Therefore, it's a bad idea to make any manual changes to the files in here, or to
|
||||
put any of your own files in here if you don't want to lose them. (Of course you may choose
|
||||
to add the folder's contents to your version-control system so that you can re-merge your own
|
||||
modifications after the Projucer has saved its changes).
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_basics/juce_audio_basics.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_basics/juce_audio_basics.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_devices/juce_audio_devices.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_devices/juce_audio_devices.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_formats/juce_audio_formats.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_formats/juce_audio_formats.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_processors/juce_audio_processors.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_processors/juce_audio_processors.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_utils/juce_audio_utils.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_audio_utils/juce_audio_utils.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_core/juce_core.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_core/juce_core.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_cryptography/juce_cryptography.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_cryptography/juce_cryptography.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_data_structures/juce_data_structures.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_data_structures/juce_data_structures.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_events/juce_events.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_events/juce_events.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_graphics/juce_graphics.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_graphics/juce_graphics.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_gui_basics/juce_gui_basics.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_gui_basics/juce_gui_basics.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_gui_extra/juce_gui_extra.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_gui_extra/juce_gui_extra.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_opengl/juce_opengl.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_opengl/juce_opengl.mm>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_video/juce_video.cpp>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
|
||||
IMPORTANT! This file is auto-generated each time you save your
|
||||
project - if you alter its contents, your changes may be overwritten!
|
||||
|
||||
*/
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include <juce_video/juce_video.mm>
|
||||
456
extras/AudioPluginHost/Source/FilterGraph.cpp
Normal file
456
extras/AudioPluginHost/Source/FilterGraph.cpp
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "MainHostWindow.h"
|
||||
#include "FilterGraph.h"
|
||||
#include "InternalFilters.h"
|
||||
#include "GraphEditorPanel.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
FilterGraph::FilterGraph (AudioPluginFormatManager& fm)
|
||||
: FileBasedDocument (getFilenameSuffix(),
|
||||
getFilenameWildcard(),
|
||||
"Load a filter graph",
|
||||
"Save a filter graph"),
|
||||
formatManager (fm)
|
||||
{
|
||||
newDocument();
|
||||
|
||||
graph.addListener (this);
|
||||
graph.addChangeListener (this);
|
||||
|
||||
setChangedFlag (false);
|
||||
}
|
||||
|
||||
FilterGraph::~FilterGraph()
|
||||
{
|
||||
graph.addListener (this);
|
||||
graph.removeChangeListener (this);
|
||||
graph.clear();
|
||||
}
|
||||
|
||||
FilterGraph::NodeID FilterGraph::getNextUID() noexcept
|
||||
{
|
||||
return ++lastUID;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void FilterGraph::changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
changed();
|
||||
|
||||
for (int i = activePluginWindows.size(); --i >= 0;)
|
||||
if (! graph.getNodes().contains (activePluginWindows.getUnchecked(i)->node))
|
||||
activePluginWindows.remove (i);
|
||||
}
|
||||
|
||||
AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForName (const String& name) const
|
||||
{
|
||||
for (auto* node : graph.getNodes())
|
||||
if (auto p = node->getProcessor())
|
||||
if (p->getName().equalsIgnoreCase (name))
|
||||
return node;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FilterGraph::addPlugin (const PluginDescription& desc, Point<double> p)
|
||||
{
|
||||
struct AsyncCallback : public AudioPluginFormat::InstantiationCompletionCallback
|
||||
{
|
||||
AsyncCallback (FilterGraph& g, Point<double> pos) : owner (g), position (pos)
|
||||
{}
|
||||
|
||||
void completionCallback (AudioPluginInstance* instance, const String& error) override
|
||||
{
|
||||
owner.addFilterCallback (instance, error, position);
|
||||
}
|
||||
|
||||
FilterGraph& owner;
|
||||
Point<double> position;
|
||||
};
|
||||
|
||||
formatManager.createPluginInstanceAsync (desc,
|
||||
graph.getSampleRate(),
|
||||
graph.getBlockSize(),
|
||||
new AsyncCallback (*this, p));
|
||||
}
|
||||
|
||||
void FilterGraph::addFilterCallback (AudioPluginInstance* instance, const String& error, Point<double> pos)
|
||||
{
|
||||
if (instance == nullptr)
|
||||
{
|
||||
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
|
||||
TRANS("Couldn't create filter"),
|
||||
error);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->enableAllBuses();
|
||||
|
||||
if (auto node = graph.addNode (instance))
|
||||
{
|
||||
node->properties.set ("x", pos.x);
|
||||
node->properties.set ("y", pos.y);
|
||||
changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FilterGraph::setNodePosition (NodeID nodeID, Point<double> pos)
|
||||
{
|
||||
if (auto* n = graph.getNodeForId (nodeID))
|
||||
{
|
||||
n->properties.set ("x", jlimit (0.0, 1.0, pos.x));
|
||||
n->properties.set ("y", jlimit (0.0, 1.0, pos.y));
|
||||
}
|
||||
}
|
||||
|
||||
Point<double> FilterGraph::getNodePosition (NodeID nodeID) const
|
||||
{
|
||||
if (auto* n = graph.getNodeForId (nodeID))
|
||||
return { static_cast<double> (n->properties ["x"]),
|
||||
static_cast<double> (n->properties ["y"]) };
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void FilterGraph::clear()
|
||||
{
|
||||
closeAnyOpenPluginWindows();
|
||||
graph.clear();
|
||||
changed();
|
||||
}
|
||||
|
||||
PluginWindow* FilterGraph::getOrCreateWindowFor (AudioProcessorGraph::Node* node, PluginWindow::Type type)
|
||||
{
|
||||
jassert (node != nullptr);
|
||||
|
||||
for (auto* w : activePluginWindows)
|
||||
if (w->node == node && w->type == type)
|
||||
return w;
|
||||
|
||||
if (auto* processor = node->getProcessor())
|
||||
{
|
||||
if (auto* plugin = dynamic_cast<AudioPluginInstance*> (processor))
|
||||
{
|
||||
auto description = plugin->getPluginDescription();
|
||||
|
||||
if (description.pluginFormatName == "Internal")
|
||||
{
|
||||
getCommandManager().invokeDirectly (CommandIDs::showAudioSettings, false);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return activePluginWindows.add (new PluginWindow (node, type, activePluginWindows));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool FilterGraph::closeAnyOpenPluginWindows()
|
||||
{
|
||||
bool wasEmpty = activePluginWindows.isEmpty();
|
||||
activePluginWindows.clear();
|
||||
return ! wasEmpty;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String FilterGraph::getDocumentTitle()
|
||||
{
|
||||
if (! getFile().exists())
|
||||
return "Unnamed";
|
||||
|
||||
return getFile().getFileNameWithoutExtension();
|
||||
}
|
||||
|
||||
void FilterGraph::newDocument()
|
||||
{
|
||||
clear();
|
||||
setFile ({});
|
||||
|
||||
InternalPluginFormat internalFormat;
|
||||
|
||||
addPlugin (internalFormat.audioInDesc, { 0.5, 0.1 });
|
||||
addPlugin (internalFormat.midiInDesc, { 0.25, 0.1 });
|
||||
addPlugin (internalFormat.audioOutDesc, { 0.5, 0.9 });
|
||||
|
||||
setChangedFlag (false);
|
||||
}
|
||||
|
||||
Result FilterGraph::loadDocument (const File& file)
|
||||
{
|
||||
XmlDocument doc (file);
|
||||
ScopedPointer<XmlElement> xml (doc.getDocumentElement());
|
||||
|
||||
if (xml == nullptr || ! xml->hasTagName ("FILTERGRAPH"))
|
||||
return Result::fail ("Not a valid filter graph file");
|
||||
|
||||
restoreFromXml (*xml);
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
Result FilterGraph::saveDocument (const File& file)
|
||||
{
|
||||
ScopedPointer<XmlElement> xml (createXml());
|
||||
|
||||
if (! xml->writeToFile (file, {}))
|
||||
return Result::fail ("Couldn't write to the file");
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
File FilterGraph::getLastDocumentOpened()
|
||||
{
|
||||
RecentlyOpenedFilesList recentFiles;
|
||||
recentFiles.restoreFromString (getAppProperties().getUserSettings()
|
||||
->getValue ("recentFilterGraphFiles"));
|
||||
|
||||
return recentFiles.getFile (0);
|
||||
}
|
||||
|
||||
void FilterGraph::setLastDocumentOpened (const File& file)
|
||||
{
|
||||
RecentlyOpenedFilesList recentFiles;
|
||||
recentFiles.restoreFromString (getAppProperties().getUserSettings()
|
||||
->getValue ("recentFilterGraphFiles"));
|
||||
|
||||
recentFiles.addFile (file);
|
||||
|
||||
getAppProperties().getUserSettings()
|
||||
->setValue ("recentFilterGraphFiles", recentFiles.toString());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void readBusLayoutFromXml (AudioProcessor::BusesLayout& busesLayout, AudioProcessor* plugin,
|
||||
const XmlElement& xml, const bool isInput)
|
||||
{
|
||||
auto& targetBuses = (isInput ? busesLayout.inputBuses
|
||||
: busesLayout.outputBuses);
|
||||
int maxNumBuses = 0;
|
||||
|
||||
if (auto* buses = xml.getChildByName (isInput ? "INPUTS" : "OUTPUTS"))
|
||||
{
|
||||
forEachXmlChildElementWithTagName (*buses, e, "BUS")
|
||||
{
|
||||
const int busIdx = e->getIntAttribute ("index");
|
||||
maxNumBuses = jmax (maxNumBuses, busIdx + 1);
|
||||
|
||||
// the number of buses on busesLayout may not be in sync with the plugin after adding buses
|
||||
// because adding an input bus could also add an output bus
|
||||
for (int actualIdx = plugin->getBusCount (isInput) - 1; actualIdx < busIdx; ++actualIdx)
|
||||
if (! plugin->addBus (isInput))
|
||||
return;
|
||||
|
||||
for (int actualIdx = targetBuses.size() - 1; actualIdx < busIdx; ++actualIdx)
|
||||
targetBuses.add (plugin->getChannelLayoutOfBus (isInput, busIdx));
|
||||
|
||||
auto layout = e->getStringAttribute ("layout");
|
||||
|
||||
if (layout.isNotEmpty())
|
||||
targetBuses.getReference (busIdx) = AudioChannelSet::fromAbbreviatedString (layout);
|
||||
}
|
||||
}
|
||||
|
||||
// if the plugin has more buses than specified in the xml, then try to remove them!
|
||||
while (maxNumBuses < targetBuses.size())
|
||||
{
|
||||
if (! plugin->removeBus (isInput))
|
||||
return;
|
||||
|
||||
targetBuses.removeLast();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static XmlElement* createBusLayoutXml (const AudioProcessor::BusesLayout& layout, const bool isInput)
|
||||
{
|
||||
auto& buses = isInput ? layout.inputBuses
|
||||
: layout.outputBuses;
|
||||
|
||||
auto* xml = new XmlElement (isInput ? "INPUTS" : "OUTPUTS");
|
||||
|
||||
for (int busIdx = 0; busIdx < buses.size(); ++busIdx)
|
||||
{
|
||||
auto& set = buses.getReference (busIdx);
|
||||
|
||||
auto* bus = xml->createNewChildElement ("BUS");
|
||||
bus->setAttribute ("index", busIdx);
|
||||
bus->setAttribute ("layout", set.isDisabled() ? "disabled" : set.getSpeakerArrangementAsString());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
static XmlElement* createNodeXml (AudioProcessorGraph::Node* const node) noexcept
|
||||
{
|
||||
if (auto* plugin = dynamic_cast<AudioPluginInstance*> (node->getProcessor()))
|
||||
{
|
||||
auto e = new XmlElement ("FILTER");
|
||||
e->setAttribute ("uid", (int) node->nodeID);
|
||||
e->setAttribute ("x", node->properties ["x"].toString());
|
||||
e->setAttribute ("y", node->properties ["y"].toString());
|
||||
|
||||
for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)
|
||||
{
|
||||
auto type = (PluginWindow::Type) i;
|
||||
|
||||
if (node->properties.contains (PluginWindow::getOpenProp (type)))
|
||||
{
|
||||
e->setAttribute (PluginWindow::getLastXProp (type), node->properties[PluginWindow::getLastXProp (type)].toString());
|
||||
e->setAttribute (PluginWindow::getLastYProp (type), node->properties[PluginWindow::getLastYProp (type)].toString());
|
||||
e->setAttribute (PluginWindow::getOpenProp (type), node->properties[PluginWindow::getOpenProp (type)].toString());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PluginDescription pd;
|
||||
plugin->fillInPluginDescription (pd);
|
||||
e->addChildElement (pd.createXml());
|
||||
}
|
||||
|
||||
{
|
||||
MemoryBlock m;
|
||||
node->getProcessor()->getStateInformation (m);
|
||||
e->createNewChildElement ("STATE")->addTextElement (m.toBase64Encoding());
|
||||
}
|
||||
|
||||
auto layout = plugin->getBusesLayout();
|
||||
|
||||
auto layouts = e->createNewChildElement ("LAYOUT");
|
||||
layouts->addChildElement (createBusLayoutXml (layout, true));
|
||||
layouts->addChildElement (createBusLayoutXml (layout, false));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
jassertfalse;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FilterGraph::createNodeFromXml (const XmlElement& xml)
|
||||
{
|
||||
PluginDescription pd;
|
||||
|
||||
forEachXmlChildElement (xml, e)
|
||||
{
|
||||
if (pd.loadFromXml (*e))
|
||||
break;
|
||||
}
|
||||
|
||||
String errorMessage;
|
||||
|
||||
if (auto* instance = formatManager.createPluginInstance (pd, graph.getSampleRate(),
|
||||
graph.getBlockSize(), errorMessage))
|
||||
{
|
||||
if (auto* layoutEntity = xml.getChildByName ("LAYOUT"))
|
||||
{
|
||||
auto layout = instance->getBusesLayout();
|
||||
|
||||
readBusLayoutFromXml (layout, instance, *layoutEntity, true);
|
||||
readBusLayoutFromXml (layout, instance, *layoutEntity, false);
|
||||
|
||||
instance->setBusesLayout (layout);
|
||||
}
|
||||
|
||||
if (auto node = graph.addNode (instance, (NodeID) xml.getIntAttribute ("uid")))
|
||||
{
|
||||
if (auto* state = xml.getChildByName ("STATE"))
|
||||
{
|
||||
MemoryBlock m;
|
||||
m.fromBase64Encoding (state->getAllSubText());
|
||||
|
||||
node->getProcessor()->setStateInformation (m.getData(), (int) m.getSize());
|
||||
}
|
||||
|
||||
node->properties.set ("x", xml.getDoubleAttribute ("x"));
|
||||
node->properties.set ("y", xml.getDoubleAttribute ("y"));
|
||||
|
||||
for (int i = 0; i < (int) PluginWindow::Type::numTypes; ++i)
|
||||
{
|
||||
auto type = (PluginWindow::Type) i;
|
||||
|
||||
if (xml.hasAttribute (PluginWindow::getOpenProp (type)))
|
||||
{
|
||||
node->properties.set (PluginWindow::getLastXProp (type), xml.getIntAttribute (PluginWindow::getLastXProp (type)));
|
||||
node->properties.set (PluginWindow::getLastYProp (type), xml.getIntAttribute (PluginWindow::getLastYProp (type)));
|
||||
node->properties.set (PluginWindow::getOpenProp (type), xml.getIntAttribute (PluginWindow::getOpenProp (type)));
|
||||
|
||||
if (node->properties[PluginWindow::getOpenProp (type)])
|
||||
{
|
||||
jassert (node->getProcessor() != nullptr);
|
||||
|
||||
if (auto w = getOrCreateWindowFor (node, type))
|
||||
w->toFront (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement* FilterGraph::createXml() const
|
||||
{
|
||||
auto* xml = new XmlElement ("FILTERGRAPH");
|
||||
|
||||
for (auto* node : graph.getNodes())
|
||||
xml->addChildElement (createNodeXml (node));
|
||||
|
||||
for (auto& connection : graph.getConnections())
|
||||
{
|
||||
auto e = xml->createNewChildElement ("CONNECTION");
|
||||
|
||||
e->setAttribute ("srcFilter", (int) connection.source.nodeID);
|
||||
e->setAttribute ("srcChannel", connection.source.channelIndex);
|
||||
e->setAttribute ("dstFilter", (int) connection.destination.nodeID);
|
||||
e->setAttribute ("dstChannel", connection.destination.channelIndex);
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
void FilterGraph::restoreFromXml (const XmlElement& xml)
|
||||
{
|
||||
clear();
|
||||
|
||||
forEachXmlChildElementWithTagName (xml, e, "FILTER")
|
||||
{
|
||||
createNodeFromXml (*e);
|
||||
changed();
|
||||
}
|
||||
|
||||
forEachXmlChildElementWithTagName (xml, e, "CONNECTION")
|
||||
{
|
||||
graph.addConnection ({ { (NodeID) e->getIntAttribute ("srcFilter"), e->getIntAttribute ("srcChannel") },
|
||||
{ (NodeID) e->getIntAttribute ("dstFilter"), e->getIntAttribute ("dstChannel") } });
|
||||
}
|
||||
|
||||
graph.removeIllegalConnections();
|
||||
}
|
||||
97
extras/AudioPluginHost/Source/FilterGraph.h
Normal file
97
extras/AudioPluginHost/Source/FilterGraph.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PluginWindow.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A collection of filters and some connections between them.
|
||||
*/
|
||||
class FilterGraph : public FileBasedDocument,
|
||||
public AudioProcessorListener,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
FilterGraph (AudioPluginFormatManager&);
|
||||
~FilterGraph();
|
||||
|
||||
//==============================================================================
|
||||
typedef AudioProcessorGraph::NodeID NodeID;
|
||||
|
||||
void addPlugin (const PluginDescription&, Point<double>);
|
||||
|
||||
AudioProcessorGraph::Node::Ptr getNodeForName (const String& name) const;
|
||||
|
||||
void setNodePosition (NodeID, Point<double>);
|
||||
Point<double> getNodePosition (NodeID) const;
|
||||
|
||||
//==============================================================================
|
||||
void clear();
|
||||
|
||||
PluginWindow* getOrCreateWindowFor (AudioProcessorGraph::Node*, PluginWindow::Type);
|
||||
void closeCurrentlyOpenWindowsFor (AudioProcessorGraph::NodeID);
|
||||
bool closeAnyOpenPluginWindows();
|
||||
|
||||
//==============================================================================
|
||||
void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}
|
||||
void audioProcessorChanged (AudioProcessor*) override { changed(); }
|
||||
|
||||
//==============================================================================
|
||||
XmlElement* createXml() const;
|
||||
void restoreFromXml (const XmlElement& xml);
|
||||
|
||||
static const char* getFilenameSuffix() { return ".filtergraph"; }
|
||||
static const char* getFilenameWildcard() { return "*.filtergraph"; }
|
||||
|
||||
//==============================================================================
|
||||
void newDocument();
|
||||
String getDocumentTitle() override;
|
||||
Result loadDocument (const File& file) override;
|
||||
Result saveDocument (const File& file) override;
|
||||
File getLastDocumentOpened() override;
|
||||
void setLastDocumentOpened (const File& file) override;
|
||||
|
||||
//==============================================================================
|
||||
AudioProcessorGraph graph;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioPluginFormatManager& formatManager;
|
||||
OwnedArray<PluginWindow> activePluginWindows;
|
||||
|
||||
NodeID lastUID = 0;
|
||||
NodeID getNextUID() noexcept;
|
||||
|
||||
void createNodeFromXml (const XmlElement& xml);
|
||||
void addFilterCallback (AudioPluginInstance*, const String& error, Point<double>);
|
||||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterGraph)
|
||||
};
|
||||
548
extras/AudioPluginHost/Source/FilterIOConfiguration.cpp
Normal file
548
extras/AudioPluginHost/Source/FilterIOConfiguration.cpp
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "GraphEditorPanel.h"
|
||||
#include "InternalFilters.h"
|
||||
#include "MainHostWindow.h"
|
||||
#include "FilterIOConfiguration.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct NumberedBoxes : public TableListBox,
|
||||
private TableListBoxModel,
|
||||
private Button::Listener
|
||||
{
|
||||
struct Listener
|
||||
{
|
||||
virtual ~Listener() {}
|
||||
|
||||
virtual void addColumn() = 0;
|
||||
virtual void removeColumn() = 0;
|
||||
virtual void columnSelected (int columnId) = 0;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
plusButtonColumnId = 128,
|
||||
minusButtonColumnId = 129
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
NumberedBoxes (Listener& listenerToUse, bool canCurrentlyAddColumn, bool canCurrentlyRemoveColumn)
|
||||
: TableListBox ("NumberedBoxes", this),
|
||||
listener (listenerToUse),
|
||||
canAddColumn (canCurrentlyAddColumn),
|
||||
canRemoveColumn (canCurrentlyRemoveColumn)
|
||||
{
|
||||
auto& tableHeader = getHeader();
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
tableHeader.addColumn (String (i + 1), i + 1, 40);
|
||||
|
||||
setHeaderHeight (0);
|
||||
setRowHeight (40);
|
||||
getHorizontalScrollBar().setAutoHide (false);
|
||||
}
|
||||
|
||||
void setSelected (int columnId)
|
||||
{
|
||||
if (auto* button = dynamic_cast<TextButton*> (getCellComponent (columnId, 0)))
|
||||
button->setToggleState (true, NotificationType::dontSendNotification);
|
||||
}
|
||||
|
||||
void setCanAddColumn (bool canCurrentlyAdd)
|
||||
{
|
||||
if (canCurrentlyAdd != canAddColumn)
|
||||
{
|
||||
canAddColumn = canCurrentlyAdd;
|
||||
|
||||
if (auto* button = dynamic_cast<TextButton*> (getCellComponent (plusButtonColumnId, 0)))
|
||||
button->setEnabled (true);
|
||||
}
|
||||
}
|
||||
|
||||
void setCanRemoveColumn (bool canCurrentlyRemove)
|
||||
{
|
||||
if (canCurrentlyRemove != canRemoveColumn)
|
||||
{
|
||||
canRemoveColumn = canCurrentlyRemove;
|
||||
|
||||
if (auto* button = dynamic_cast<TextButton*> (getCellComponent (minusButtonColumnId, 0)))
|
||||
button->setEnabled (true);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Listener& listener;
|
||||
bool canAddColumn, canRemoveColumn;
|
||||
|
||||
//==============================================================================
|
||||
int getNumRows() override { return 1; }
|
||||
void paintCell (Graphics&, int, int, int, int, bool) override {}
|
||||
void paintRowBackground (Graphics& g, int, int, int, bool) override { g.fillAll (Colours::grey); }
|
||||
|
||||
Component* refreshComponentForCell (int, int columnId, bool,
|
||||
Component* existingComponentToUpdate) override
|
||||
{
|
||||
auto* textButton = dynamic_cast<TextButton*> (existingComponentToUpdate);
|
||||
|
||||
if (textButton == nullptr)
|
||||
textButton = new TextButton();
|
||||
|
||||
textButton->setButtonText (getButtonName (columnId));
|
||||
textButton->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight |
|
||||
Button::ConnectedOnTop | Button::ConnectedOnBottom);
|
||||
|
||||
const bool isPlusMinusButton = (columnId == plusButtonColumnId || columnId == minusButtonColumnId);
|
||||
|
||||
if (isPlusMinusButton)
|
||||
{
|
||||
textButton->setEnabled (columnId == plusButtonColumnId ? canAddColumn : canRemoveColumn);
|
||||
}
|
||||
else
|
||||
{
|
||||
textButton->setRadioGroupId (1, NotificationType::dontSendNotification);
|
||||
textButton->setClickingTogglesState (true);
|
||||
|
||||
auto busColour = Colours::green.withRotatedHue (static_cast<float> (columnId) / 5.0f);
|
||||
textButton->setColour (TextButton::buttonColourId, busColour);
|
||||
textButton->setColour (TextButton::buttonOnColourId, busColour.withMultipliedBrightness (2.0f));
|
||||
}
|
||||
|
||||
textButton->addListener (this);
|
||||
|
||||
return textButton;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String getButtonName (int columnId)
|
||||
{
|
||||
if (columnId == plusButtonColumnId) return "+";
|
||||
if (columnId == minusButtonColumnId) return "-";
|
||||
|
||||
return String (columnId);
|
||||
}
|
||||
|
||||
void buttonClicked (Button* btn) override
|
||||
{
|
||||
auto text = btn->getButtonText();
|
||||
|
||||
if (text == "+") listener.addColumn();
|
||||
if (text == "-") listener.removeColumn();
|
||||
}
|
||||
|
||||
void buttonStateChanged (Button* btn) override
|
||||
{
|
||||
auto text = btn->getButtonText();
|
||||
|
||||
if (text == "+" || text == "-")
|
||||
return;
|
||||
|
||||
if (btn->getToggleState())
|
||||
listener.columnSelected (text.getIntValue());
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NumberedBoxes)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class FilterIOConfigurationWindow::InputOutputConfig : public Component,
|
||||
private ComboBox::Listener,
|
||||
private Button::Listener,
|
||||
private NumberedBoxes::Listener
|
||||
{
|
||||
public:
|
||||
InputOutputConfig (FilterIOConfigurationWindow& parent, bool direction)
|
||||
: owner (parent),
|
||||
ioTitle ("ioLabel", direction ? "Input Configuration" : "Output Configuration"),
|
||||
ioBuses (*this, false, false),
|
||||
isInput (direction)
|
||||
{
|
||||
ioTitle.setFont (ioTitle.getFont().withStyle (Font::bold));
|
||||
nameLabel.setFont (nameLabel.getFont().withStyle (Font::bold));
|
||||
layoutLabel.setFont (layoutLabel.getFont().withStyle (Font::bold));
|
||||
enabledToggle.setClickingTogglesState (true);
|
||||
|
||||
layouts.addListener (this);
|
||||
enabledToggle.addListener (this);
|
||||
|
||||
addAndMakeVisible (layoutLabel);
|
||||
addAndMakeVisible (layouts);
|
||||
addAndMakeVisible (enabledToggle);
|
||||
addAndMakeVisible (ioTitle);
|
||||
addAndMakeVisible (nameLabel);
|
||||
addAndMakeVisible (name);
|
||||
addAndMakeVisible (ioBuses);
|
||||
|
||||
updateBusButtons();
|
||||
updateBusLayout();
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto r = getLocalBounds().reduced (10);
|
||||
|
||||
ioTitle.setBounds (r.removeFromTop (14));
|
||||
r.reduce (10, 0);
|
||||
r.removeFromTop (16);
|
||||
|
||||
ioBuses.setBounds (r.removeFromTop (60));
|
||||
|
||||
{
|
||||
auto label = r.removeFromTop (24);
|
||||
nameLabel.setBounds (label.removeFromLeft (100));
|
||||
enabledToggle.setBounds (label.removeFromRight (80));
|
||||
name.setBounds (label);
|
||||
}
|
||||
|
||||
{
|
||||
auto label = r.removeFromTop (24);
|
||||
layoutLabel.setBounds (label.removeFromLeft (100));
|
||||
layouts.setBounds (label);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void updateBusButtons()
|
||||
{
|
||||
if (auto* filter = owner.getAudioProcessor())
|
||||
{
|
||||
auto& header = ioBuses.getHeader();
|
||||
header.removeAllColumns();
|
||||
|
||||
const int n = filter->getBusCount (isInput);
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
header.addColumn ("", i + 1, 40);
|
||||
|
||||
header.addColumn ("+", NumberedBoxes::plusButtonColumnId, 20);
|
||||
header.addColumn ("-", NumberedBoxes::minusButtonColumnId, 20);
|
||||
|
||||
ioBuses.setCanAddColumn (filter->canAddBus (isInput));
|
||||
ioBuses.setCanRemoveColumn (filter->canRemoveBus (isInput));
|
||||
}
|
||||
|
||||
ioBuses.setSelected (currentBus + 1);
|
||||
}
|
||||
|
||||
void updateBusLayout()
|
||||
{
|
||||
if (auto* filter = owner.getAudioProcessor())
|
||||
{
|
||||
if (auto* bus = filter->getBus (isInput, currentBus))
|
||||
{
|
||||
name.setText (bus->getName(), NotificationType::dontSendNotification);
|
||||
|
||||
int i;
|
||||
for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i)
|
||||
if ((layouts.indexOfItemId(i) == -1) != bus->supportedLayoutWithChannels (i).isDisabled())
|
||||
break;
|
||||
|
||||
// supported layouts have changed
|
||||
if (i < AudioChannelSet::maxChannelsOfNamedLayout)
|
||||
{
|
||||
layouts.clear();
|
||||
|
||||
for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i)
|
||||
{
|
||||
auto set = bus->supportedLayoutWithChannels (i);
|
||||
|
||||
if (! set.isDisabled())
|
||||
layouts.addItem (set.getDescription(), i);
|
||||
}
|
||||
}
|
||||
|
||||
layouts.setSelectedId (bus->getLastEnabledLayout().size());
|
||||
|
||||
const bool canBeDisabled = bus->isNumberOfChannelsSupported (0);
|
||||
|
||||
if (canBeDisabled != enabledToggle.isEnabled())
|
||||
enabledToggle.setEnabled (canBeDisabled);
|
||||
|
||||
enabledToggle.setToggleState (bus->isEnabled(), NotificationType::dontSendNotification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void comboBoxChanged (ComboBox* combo) override
|
||||
{
|
||||
if (combo == &layouts)
|
||||
{
|
||||
if (auto* p = owner.getAudioProcessor())
|
||||
{
|
||||
if (auto* bus = p->getBus (isInput, currentBus))
|
||||
{
|
||||
auto selectedNumChannels = layouts.getSelectedId();
|
||||
|
||||
if (selectedNumChannels != bus->getLastEnabledLayout().size())
|
||||
{
|
||||
if (isPositiveAndBelow (selectedNumChannels, AudioChannelSet::maxChannelsOfNamedLayout)
|
||||
&& bus->setCurrentLayoutWithoutEnabling (bus->supportedLayoutWithChannels (selectedNumChannels)))
|
||||
{
|
||||
if (auto* config = owner.getConfig (! isInput))
|
||||
config->updateBusLayout();
|
||||
|
||||
owner.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void buttonClicked (Button*) override {}
|
||||
|
||||
void buttonStateChanged (Button* btn) override
|
||||
{
|
||||
if (btn == &enabledToggle && enabledToggle.isEnabled())
|
||||
{
|
||||
if (auto* p = owner.getAudioProcessor())
|
||||
{
|
||||
if (auto* bus = p->getBus (isInput, currentBus))
|
||||
{
|
||||
if (bus->isEnabled() != enabledToggle.getToggleState())
|
||||
{
|
||||
bool success = enabledToggle.getToggleState() ? bus->enable()
|
||||
: bus->setCurrentLayout (AudioChannelSet::disabled());
|
||||
|
||||
if (success)
|
||||
{
|
||||
updateBusLayout();
|
||||
|
||||
if (auto* config = owner.getConfig (! isInput))
|
||||
config->updateBusLayout();
|
||||
|
||||
owner.update();
|
||||
}
|
||||
else
|
||||
{
|
||||
enabledToggle.setToggleState (! enabledToggle.getToggleState(),
|
||||
NotificationType::dontSendNotification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void addColumn() override
|
||||
{
|
||||
if (auto* p = owner.getAudioProcessor())
|
||||
{
|
||||
if (p->canAddBus (isInput))
|
||||
{
|
||||
if (p->addBus (isInput))
|
||||
{
|
||||
updateBusButtons();
|
||||
updateBusLayout();
|
||||
|
||||
if (auto* config = owner.getConfig (! isInput))
|
||||
{
|
||||
config->updateBusButtons();
|
||||
config->updateBusLayout();
|
||||
}
|
||||
}
|
||||
|
||||
owner.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeColumn() override
|
||||
{
|
||||
if (auto* p = owner.getAudioProcessor())
|
||||
{
|
||||
if (p->getBusCount (isInput) > 1 && p->canRemoveBus (isInput))
|
||||
{
|
||||
if (p->removeBus (isInput))
|
||||
{
|
||||
currentBus = jmin (p->getBusCount (isInput) - 1, currentBus);
|
||||
|
||||
updateBusButtons();
|
||||
updateBusLayout();
|
||||
|
||||
if (auto* config = owner.getConfig (! isInput))
|
||||
{
|
||||
config->updateBusButtons();
|
||||
config->updateBusLayout();
|
||||
}
|
||||
|
||||
owner.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void columnSelected (int columnId) override
|
||||
{
|
||||
const int newBus = columnId - 1;
|
||||
|
||||
if (currentBus != newBus)
|
||||
{
|
||||
currentBus = newBus;
|
||||
ioBuses.setSelected (currentBus + 1);
|
||||
updateBusLayout();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
FilterIOConfigurationWindow& owner;
|
||||
Label ioTitle, name;
|
||||
Label nameLabel { "nameLabel", "Bus Name:" };
|
||||
Label layoutLabel { "layoutLabel", "Channel Layout:" };
|
||||
ToggleButton enabledToggle { "Enabled" };
|
||||
ComboBox layouts;
|
||||
NumberedBoxes ioBuses;
|
||||
bool isInput;
|
||||
int currentBus = 0;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InputOutputConfig)
|
||||
};
|
||||
|
||||
|
||||
FilterIOConfigurationWindow::FilterIOConfigurationWindow (AudioProcessor& p)
|
||||
: AudioProcessorEditor (&p),
|
||||
title ("title", p.getName())
|
||||
{
|
||||
setOpaque (true);
|
||||
|
||||
title.setFont (title.getFont().withStyle (Font::bold));
|
||||
addAndMakeVisible (title);
|
||||
|
||||
{
|
||||
ScopedLock renderLock (p.getCallbackLock());
|
||||
p.suspendProcessing (true);
|
||||
p.releaseResources();
|
||||
}
|
||||
|
||||
if (p.getBusCount (true) > 0 || p.canAddBus (true))
|
||||
addAndMakeVisible (inConfig = new InputOutputConfig (*this, true));
|
||||
|
||||
if (p.getBusCount (false) > 0 || p.canAddBus (false))
|
||||
addAndMakeVisible (outConfig = new InputOutputConfig (*this, false));
|
||||
|
||||
currentLayout = p.getBusesLayout();
|
||||
setSize (400, (inConfig != nullptr && outConfig != nullptr ? 160 : 0) + 200);
|
||||
}
|
||||
|
||||
FilterIOConfigurationWindow::~FilterIOConfigurationWindow()
|
||||
{
|
||||
if (auto* graph = getGraph())
|
||||
{
|
||||
if (auto* p = getAudioProcessor())
|
||||
{
|
||||
ScopedLock renderLock (graph->getCallbackLock());
|
||||
|
||||
graph->suspendProcessing (true);
|
||||
graph->releaseResources();
|
||||
|
||||
p->prepareToPlay (graph->getSampleRate(), graph->getBlockSize());
|
||||
p->suspendProcessing (false);
|
||||
|
||||
graph->prepareToPlay (graph->getSampleRate(), graph->getBlockSize());
|
||||
graph->suspendProcessing (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FilterIOConfigurationWindow::paint (Graphics& g)
|
||||
{
|
||||
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
|
||||
}
|
||||
|
||||
void FilterIOConfigurationWindow::resized()
|
||||
{
|
||||
auto r = getLocalBounds().reduced (10);
|
||||
|
||||
title.setBounds (r.removeFromTop (14));
|
||||
r.reduce (10, 0);
|
||||
|
||||
if (inConfig != nullptr)
|
||||
inConfig->setBounds (r.removeFromTop (160));
|
||||
|
||||
if (outConfig != nullptr)
|
||||
outConfig->setBounds (r.removeFromTop (160));
|
||||
}
|
||||
|
||||
void FilterIOConfigurationWindow::update()
|
||||
{
|
||||
auto nodeID = getNodeID();
|
||||
|
||||
if (auto* graph = getGraph())
|
||||
if (nodeID != 0)
|
||||
graph->disconnectNode (nodeID);
|
||||
|
||||
if (auto* graphEditor = getGraphEditor())
|
||||
if (auto* panel = graphEditor->graphPanel.get())
|
||||
panel->updateComponents();
|
||||
}
|
||||
|
||||
AudioProcessorGraph::NodeID FilterIOConfigurationWindow::getNodeID() const
|
||||
{
|
||||
if (auto* graph = getGraph())
|
||||
for (auto* node : graph->getNodes())
|
||||
if (node->getProcessor() == getAudioProcessor())
|
||||
return node->nodeID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MainHostWindow* FilterIOConfigurationWindow::getMainWindow() const
|
||||
{
|
||||
auto& desktop = Desktop::getInstance();
|
||||
|
||||
for (int i = desktop.getNumComponents(); --i >= 0;)
|
||||
if (auto* mainWindow = dynamic_cast<MainHostWindow*> (desktop.getComponent(i)))
|
||||
return mainWindow;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GraphDocumentComponent* FilterIOConfigurationWindow::getGraphEditor() const
|
||||
{
|
||||
if (auto* mainWindow = getMainWindow())
|
||||
return mainWindow->graphHolder.get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AudioProcessorGraph* FilterIOConfigurationWindow::getGraph() const
|
||||
{
|
||||
if (auto* graphEditor = getGraphEditor())
|
||||
if (auto* panel = graphEditor->graph.get())
|
||||
return &panel->graph;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
60
extras/AudioPluginHost/Source/FilterIOConfiguration.h
Normal file
60
extras/AudioPluginHost/Source/FilterIOConfiguration.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class MainHostWindow;
|
||||
class GraphDocumentComponent;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class FilterIOConfigurationWindow : public AudioProcessorEditor
|
||||
{
|
||||
public:
|
||||
FilterIOConfigurationWindow (AudioProcessor&);
|
||||
~FilterIOConfigurationWindow();
|
||||
|
||||
//==============================================================================
|
||||
void paint (Graphics& g) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
class InputOutputConfig;
|
||||
|
||||
AudioProcessor::BusesLayout currentLayout;
|
||||
Label title;
|
||||
ScopedPointer<InputOutputConfig> inConfig, outConfig;
|
||||
|
||||
InputOutputConfig* getConfig (bool isInput) noexcept { return isInput ? inConfig : outConfig; }
|
||||
void update();
|
||||
|
||||
MainHostWindow* getMainWindow() const;
|
||||
GraphDocumentComponent* getGraphEditor() const;
|
||||
AudioProcessorGraph* getGraph() const;
|
||||
AudioProcessorGraph::NodeID getNodeID() const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterIOConfigurationWindow)
|
||||
};
|
||||
866
extras/AudioPluginHost/Source/GraphEditorPanel.cpp
Normal file
866
extras/AudioPluginHost/Source/GraphEditorPanel.cpp
Normal file
|
|
@ -0,0 +1,866 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "GraphEditorPanel.h"
|
||||
#include "InternalFilters.h"
|
||||
#include "MainHostWindow.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct GraphEditorPanel::PinComponent : public Component,
|
||||
public SettableTooltipClient
|
||||
{
|
||||
PinComponent (GraphEditorPanel& p, AudioProcessorGraph::NodeAndChannel pinToUse, bool isIn)
|
||||
: panel (p), graph (p.graph), pin (pinToUse), isInput (isIn)
|
||||
{
|
||||
if (auto node = graph.graph.getNodeForId (pin.nodeID))
|
||||
{
|
||||
String tip;
|
||||
|
||||
if (pin.isMIDI())
|
||||
{
|
||||
tip = isInput ? "MIDI Input"
|
||||
: "MIDI Output";
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& processor = *node->getProcessor();
|
||||
auto channel = processor.getOffsetInBusBufferForAbsoluteChannelIndex (isInput, pin.channelIndex, busIdx);
|
||||
|
||||
if (auto* bus = processor.getBus (isInput, busIdx))
|
||||
tip = bus->getName() + ": " + AudioChannelSet::getAbbreviatedChannelTypeName (bus->getCurrentLayout().getTypeOfChannel (channel));
|
||||
else
|
||||
tip = (isInput ? "Main Input: "
|
||||
: "Main Output: ") + String (pin.channelIndex + 1);
|
||||
|
||||
}
|
||||
|
||||
setTooltip (tip);
|
||||
}
|
||||
|
||||
setSize (16, 16);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
auto w = (float) getWidth();
|
||||
auto h = (float) getHeight();
|
||||
|
||||
Path p;
|
||||
p.addEllipse (w * 0.25f, h * 0.25f, w * 0.5f, h * 0.5f);
|
||||
p.addRectangle (w * 0.4f, isInput ? (0.5f * h) : 0.0f, w * 0.2f, h * 0.5f);
|
||||
|
||||
auto colour = (pin.isMIDI() ? Colours::red : Colours::green);
|
||||
|
||||
g.setColour (colour.withRotatedHue (busIdx / 5.0f));
|
||||
g.fillPath (p);
|
||||
}
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
AudioProcessorGraph::NodeAndChannel dummy { 0, 0 };
|
||||
|
||||
panel.beginConnectorDrag (isInput ? dummy : pin,
|
||||
isInput ? pin : dummy,
|
||||
e);
|
||||
}
|
||||
|
||||
void mouseDrag (const MouseEvent& e) override
|
||||
{
|
||||
panel.dragConnector (e);
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
{
|
||||
panel.endDraggingConnector (e);
|
||||
}
|
||||
|
||||
GraphEditorPanel& panel;
|
||||
FilterGraph& graph;
|
||||
AudioProcessorGraph::NodeAndChannel pin;
|
||||
const bool isInput;
|
||||
int busIdx = 0;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PinComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct GraphEditorPanel::FilterComponent : public Component
|
||||
{
|
||||
FilterComponent (GraphEditorPanel& p, uint32 id) : panel (p), graph (p.graph), pluginID (id)
|
||||
{
|
||||
shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 3, { 0, 1 }));
|
||||
setComponentEffect (&shadow);
|
||||
|
||||
setSize (150, 60);
|
||||
}
|
||||
|
||||
FilterComponent (const FilterComponent&) = delete;
|
||||
FilterComponent& operator= (const FilterComponent&) = delete;
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
originalPos = localPointToGlobal (Point<int>());
|
||||
|
||||
toFront (true);
|
||||
|
||||
if (e.mods.isPopupMenu())
|
||||
showPopupMenu();
|
||||
}
|
||||
|
||||
void mouseDrag (const MouseEvent& e) override
|
||||
{
|
||||
if (! e.mods.isPopupMenu())
|
||||
{
|
||||
auto pos = originalPos + e.getOffsetFromDragStart();
|
||||
|
||||
if (getParentComponent() != nullptr)
|
||||
pos = getParentComponent()->getLocalPoint (nullptr, pos);
|
||||
|
||||
pos += getLocalBounds().getCentre();
|
||||
|
||||
graph.setNodePosition (pluginID,
|
||||
{ pos.x / (double) getParentWidth(),
|
||||
pos.y / (double) getParentHeight() });
|
||||
|
||||
panel.updateComponents();
|
||||
}
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
{
|
||||
if (e.mouseWasDraggedSinceMouseDown())
|
||||
{
|
||||
graph.setChangedFlag (true);
|
||||
}
|
||||
else if (e.getNumberOfClicks() == 2)
|
||||
{
|
||||
if (auto f = graph.graph.getNodeForId (pluginID))
|
||||
if (auto* w = graph.getOrCreateWindowFor (f, PluginWindow::Type::normal))
|
||||
w->toFront (true);
|
||||
}
|
||||
}
|
||||
|
||||
bool hitTest (int x, int y) override
|
||||
{
|
||||
for (auto* child : getChildren())
|
||||
if (child->getBounds().contains (x, y))
|
||||
return true;
|
||||
|
||||
return x >= 3 && x < getWidth() - 6 && y >= pinSize && y < getHeight() - pinSize;
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
auto boxArea = getLocalBounds().reduced (4, pinSize);
|
||||
|
||||
g.setColour (findColour (TextEditor::backgroundColourId));
|
||||
g.fillRect (boxArea.toFloat());
|
||||
|
||||
g.setColour (findColour (TextEditor::textColourId));
|
||||
g.setFont (font);
|
||||
g.drawFittedText (getName(), boxArea, Justification::centred, 2);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
if (auto f = graph.graph.getNodeForId (pluginID))
|
||||
{
|
||||
if (auto* processor = f->getProcessor())
|
||||
{
|
||||
for (auto* pin : pins)
|
||||
{
|
||||
const bool isInput = pin->isInput;
|
||||
auto channelIndex = pin->pin.channelIndex;
|
||||
int busIdx = 0;
|
||||
processor->getOffsetInBusBufferForAbsoluteChannelIndex (isInput, channelIndex, busIdx);
|
||||
|
||||
const int total = isInput ? numIns : numOuts;
|
||||
const int index = pin->pin.isMIDI() ? (total - 1) : channelIndex;
|
||||
|
||||
auto totalSpaces = static_cast<float> (total) + (static_cast<float> (jmax (0, processor->getBusCount (isInput) - 1)) * 0.5f);
|
||||
auto indexPos = static_cast<float> (index) + (static_cast<float> (busIdx) * 0.5f);
|
||||
|
||||
pin->setBounds (proportionOfWidth ((1.0f + indexPos) / (totalSpaces + 1.0f)) - pinSize / 2,
|
||||
pin->isInput ? 0 : (getHeight() - pinSize),
|
||||
pinSize, pinSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point<float> getPinPos (int index, bool isInput) const
|
||||
{
|
||||
for (auto* pin : pins)
|
||||
if (pin->pin.channelIndex == index && isInput == pin->isInput)
|
||||
return getPosition().toFloat() + pin->getBounds().getCentre().toFloat();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
const AudioProcessorGraph::Node::Ptr f (graph.graph.getNodeForId (pluginID));
|
||||
jassert (f != nullptr);
|
||||
|
||||
numIns = f->getProcessor()->getTotalNumInputChannels();
|
||||
if (f->getProcessor()->acceptsMidi())
|
||||
++numIns;
|
||||
|
||||
numOuts = f->getProcessor()->getTotalNumOutputChannels();
|
||||
if (f->getProcessor()->producesMidi())
|
||||
++numOuts;
|
||||
|
||||
int w = 100;
|
||||
int h = 60;
|
||||
|
||||
w = jmax (w, (jmax (numIns, numOuts) + 1) * 20);
|
||||
|
||||
const int textWidth = font.getStringWidth (f->getProcessor()->getName());
|
||||
w = jmax (w, 16 + jmin (textWidth, 300));
|
||||
if (textWidth > 300)
|
||||
h = 100;
|
||||
|
||||
setSize (w, h);
|
||||
|
||||
setName (f->getProcessor()->getName());
|
||||
|
||||
{
|
||||
auto p = graph.getNodePosition (pluginID);
|
||||
setCentreRelative ((float) p.x, (float) p.y);
|
||||
}
|
||||
|
||||
if (numIns != numInputs || numOuts != numOutputs)
|
||||
{
|
||||
numInputs = numIns;
|
||||
numOutputs = numOuts;
|
||||
|
||||
pins.clear();
|
||||
|
||||
for (int i = 0; i < f->getProcessor()->getTotalNumInputChannels(); ++i)
|
||||
addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, i }, true)));
|
||||
|
||||
if (f->getProcessor()->acceptsMidi())
|
||||
addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, AudioProcessorGraph::midiChannelIndex }, true)));
|
||||
|
||||
for (int i = 0; i < f->getProcessor()->getTotalNumOutputChannels(); ++i)
|
||||
addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, i }, false)));
|
||||
|
||||
if (f->getProcessor()->producesMidi())
|
||||
addAndMakeVisible (pins.add (new PinComponent (panel, { pluginID, AudioProcessorGraph::midiChannelIndex }, false)));
|
||||
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
AudioProcessor* getProcessor() const
|
||||
{
|
||||
if (auto node = graph.graph.getNodeForId (pluginID))
|
||||
return node->getProcessor();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void showPopupMenu()
|
||||
{
|
||||
PopupMenu m;
|
||||
m.addItem (1, "Delete this filter");
|
||||
m.addItem (2, "Disconnect all pins");
|
||||
m.addSeparator();
|
||||
m.addItem (10, "Show plugin GUI");
|
||||
m.addItem (11, "Show all programs");
|
||||
m.addItem (12, "Show all parameters");
|
||||
m.addSeparator();
|
||||
m.addItem (20, "Configure Audio I/O");
|
||||
m.addItem (21, "Test state save/load");
|
||||
|
||||
switch (m.show())
|
||||
{
|
||||
case 1: graph.graph.removeNode (pluginID); break;
|
||||
case 2: graph.graph.disconnectNode (pluginID); break;
|
||||
case 10: showWindow (PluginWindow::Type::normal); break;
|
||||
case 11: showWindow (PluginWindow::Type::programs); break;
|
||||
case 12: showWindow (PluginWindow::Type::generic); break;
|
||||
case 20: showWindow (PluginWindow::Type::audioIO); break;
|
||||
case 21: testStateSaveLoad(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void testStateSaveLoad()
|
||||
{
|
||||
if (auto* processor = getProcessor())
|
||||
{
|
||||
MemoryBlock state;
|
||||
processor->getStateInformation (state);
|
||||
processor->setStateInformation (state.getData(), (int) state.getSize());
|
||||
}
|
||||
}
|
||||
|
||||
void showWindow (PluginWindow::Type type)
|
||||
{
|
||||
if (auto node = graph.graph.getNodeForId (pluginID))
|
||||
if (auto* w = graph.getOrCreateWindowFor (node, type))
|
||||
w->toFront (true);
|
||||
}
|
||||
|
||||
GraphEditorPanel& panel;
|
||||
FilterGraph& graph;
|
||||
const AudioProcessorGraph::NodeID pluginID;
|
||||
OwnedArray<PinComponent> pins;
|
||||
int numInputs = 0, numOutputs = 0;
|
||||
int pinSize = 16;
|
||||
Point<int> originalPos;
|
||||
Font font { 13.0f, Font::bold };
|
||||
int numIns = 0, numOuts = 0;
|
||||
DropShadowEffect shadow;
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct GraphEditorPanel::ConnectorComponent : public Component,
|
||||
public SettableTooltipClient
|
||||
{
|
||||
ConnectorComponent (GraphEditorPanel& p) : panel (p), graph (p.graph)
|
||||
{
|
||||
setAlwaysOnTop (true);
|
||||
}
|
||||
|
||||
void setInput (AudioProcessorGraph::NodeAndChannel newSource)
|
||||
{
|
||||
if (connection.source != newSource)
|
||||
{
|
||||
connection.source = newSource;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void setOutput (AudioProcessorGraph::NodeAndChannel newDest)
|
||||
{
|
||||
if (connection.destination != newDest)
|
||||
{
|
||||
connection.destination = newDest;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void dragStart (Point<float> pos)
|
||||
{
|
||||
lastInputPos = pos;
|
||||
resizeToFit();
|
||||
}
|
||||
|
||||
void dragEnd (Point<float> pos)
|
||||
{
|
||||
lastOutputPos = pos;
|
||||
resizeToFit();
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
Point<float> p1, p2;
|
||||
getPoints (p1, p2);
|
||||
|
||||
if (lastInputPos != p1 || lastOutputPos != p2)
|
||||
resizeToFit();
|
||||
}
|
||||
|
||||
void resizeToFit()
|
||||
{
|
||||
Point<float> p1, p2;
|
||||
getPoints (p1, p2);
|
||||
|
||||
auto newBounds = Rectangle<float> (p1, p2).expanded (4.0f).getSmallestIntegerContainer();
|
||||
|
||||
if (newBounds != getBounds())
|
||||
setBounds (newBounds);
|
||||
else
|
||||
resized();
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void getPoints (Point<float>& p1, Point<float>& p2) const
|
||||
{
|
||||
p1 = lastInputPos;
|
||||
p2 = lastOutputPos;
|
||||
|
||||
if (auto* src = panel.getComponentForFilter (connection.source.nodeID))
|
||||
p1 = src->getPinPos (connection.source.channelIndex, false);
|
||||
|
||||
if (auto* dest = panel.getComponentForFilter (connection.destination.nodeID))
|
||||
p2 = dest->getPinPos (connection.destination.channelIndex, true);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
if (connection.source.isMIDI() || connection.destination.isMIDI())
|
||||
g.setColour (Colours::red);
|
||||
else
|
||||
g.setColour (Colours::green);
|
||||
|
||||
g.fillPath (linePath);
|
||||
}
|
||||
|
||||
bool hitTest (int x, int y) override
|
||||
{
|
||||
auto pos = Point<int> (x, y).toFloat();
|
||||
|
||||
if (hitPath.contains (pos))
|
||||
{
|
||||
double distanceFromStart, distanceFromEnd;
|
||||
getDistancesFromEnds (pos, distanceFromStart, distanceFromEnd);
|
||||
|
||||
// avoid clicking the connector when over a pin
|
||||
return distanceFromStart > 7.0 && distanceFromEnd > 7.0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void mouseDown (const MouseEvent&) override
|
||||
{
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
void mouseDrag (const MouseEvent& e) override
|
||||
{
|
||||
if (dragging)
|
||||
{
|
||||
panel.dragConnector (e);
|
||||
}
|
||||
else if (e.mouseWasDraggedSinceMouseDown())
|
||||
{
|
||||
dragging = true;
|
||||
|
||||
graph.graph.removeConnection (connection);
|
||||
|
||||
double distanceFromStart, distanceFromEnd;
|
||||
getDistancesFromEnds (getPosition().toFloat() + e.position, distanceFromStart, distanceFromEnd);
|
||||
const bool isNearerSource = (distanceFromStart < distanceFromEnd);
|
||||
|
||||
AudioProcessorGraph::NodeAndChannel dummy { 0, 0 };
|
||||
|
||||
panel.beginConnectorDrag (isNearerSource ? dummy : connection.source,
|
||||
isNearerSource ? connection.destination : dummy,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
{
|
||||
if (dragging)
|
||||
panel.endDraggingConnector (e);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
Point<float> p1, p2;
|
||||
getPoints (p1, p2);
|
||||
|
||||
lastInputPos = p1;
|
||||
lastOutputPos = p2;
|
||||
|
||||
p1 -= getPosition().toFloat();
|
||||
p2 -= getPosition().toFloat();
|
||||
|
||||
linePath.clear();
|
||||
linePath.startNewSubPath (p1);
|
||||
linePath.cubicTo (p1.x, p1.y + (p2.y - p1.y) * 0.33f,
|
||||
p2.x, p1.y + (p2.y - p1.y) * 0.66f,
|
||||
p2.x, p2.y);
|
||||
|
||||
PathStrokeType wideStroke (8.0f);
|
||||
wideStroke.createStrokedPath (hitPath, linePath);
|
||||
|
||||
PathStrokeType stroke (2.5f);
|
||||
stroke.createStrokedPath (linePath, linePath);
|
||||
|
||||
auto arrowW = 5.0f;
|
||||
auto arrowL = 4.0f;
|
||||
|
||||
Path arrow;
|
||||
arrow.addTriangle (-arrowL, arrowW,
|
||||
-arrowL, -arrowW,
|
||||
arrowL, 0.0f);
|
||||
|
||||
arrow.applyTransform (AffineTransform()
|
||||
.rotated (MathConstants<float>::halfPi - (float) atan2 (p2.x - p1.x, p2.y - p1.y))
|
||||
.translated ((p1 + p2) * 0.5f));
|
||||
|
||||
linePath.addPath (arrow);
|
||||
linePath.setUsingNonZeroWinding (true);
|
||||
}
|
||||
|
||||
void getDistancesFromEnds (Point<float> p, double& distanceFromStart, double& distanceFromEnd) const
|
||||
{
|
||||
Point<float> p1, p2;
|
||||
getPoints (p1, p2);
|
||||
|
||||
distanceFromStart = p1.getDistanceFrom (p);
|
||||
distanceFromEnd = p2.getDistanceFrom (p);
|
||||
}
|
||||
|
||||
GraphEditorPanel& panel;
|
||||
FilterGraph& graph;
|
||||
AudioProcessorGraph::Connection connection { { 0, 0 }, { 0, 0 } };
|
||||
Point<float> lastInputPos, lastOutputPos;
|
||||
Path linePath, hitPath;
|
||||
bool dragging = false;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectorComponent)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
GraphEditorPanel::GraphEditorPanel (FilterGraph& g) : graph (g)
|
||||
{
|
||||
graph.addChangeListener (this);
|
||||
setOpaque (true);
|
||||
}
|
||||
|
||||
GraphEditorPanel::~GraphEditorPanel()
|
||||
{
|
||||
graph.removeChangeListener (this);
|
||||
draggingConnector = nullptr;
|
||||
nodes.clear();
|
||||
connectors.clear();
|
||||
}
|
||||
|
||||
void GraphEditorPanel::paint (Graphics& g)
|
||||
{
|
||||
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
|
||||
}
|
||||
|
||||
void GraphEditorPanel::mouseDown (const MouseEvent& e)
|
||||
{
|
||||
if (e.mods.isPopupMenu())
|
||||
{
|
||||
PopupMenu m;
|
||||
|
||||
if (auto* mainWindow = findParentComponentOfClass<MainHostWindow>())
|
||||
{
|
||||
mainWindow->addPluginsToMenu (m);
|
||||
|
||||
auto r = m.show();
|
||||
|
||||
if (auto* desc = mainWindow->getChosenType (r))
|
||||
createNewPlugin (*desc, e.position.toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphEditorPanel::createNewPlugin (const PluginDescription& desc, Point<int> position)
|
||||
{
|
||||
graph.addPlugin (desc, position.toDouble() / Point<double> ((double) getWidth(), (double) getHeight()));
|
||||
}
|
||||
|
||||
GraphEditorPanel::FilterComponent* GraphEditorPanel::getComponentForFilter (const uint32 filterID) const
|
||||
{
|
||||
for (auto* fc : nodes)
|
||||
if (fc->pluginID == filterID)
|
||||
return fc;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GraphEditorPanel::ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProcessorGraph::Connection& conn) const
|
||||
{
|
||||
for (auto* cc : connectors)
|
||||
if (cc->connection == conn)
|
||||
return cc;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GraphEditorPanel::PinComponent* GraphEditorPanel::findPinAt (Point<float> pos) const
|
||||
{
|
||||
for (auto* fc : nodes)
|
||||
{
|
||||
// NB: A Visual Studio optimiser error means we have to put this Component* in a local
|
||||
// variable before trying to cast it, or it gets mysteriously optimised away..
|
||||
auto* comp = fc->getComponentAt (pos.toInt() - fc->getPosition());
|
||||
|
||||
if (auto* pin = dynamic_cast<PinComponent*> (comp))
|
||||
return pin;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GraphEditorPanel::resized()
|
||||
{
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
void GraphEditorPanel::changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
void GraphEditorPanel::updateComponents()
|
||||
{
|
||||
for (int i = nodes.size(); --i >= 0;)
|
||||
if (graph.graph.getNodeForId (nodes.getUnchecked(i)->pluginID) == nullptr)
|
||||
nodes.remove (i);
|
||||
|
||||
for (int i = connectors.size(); --i >= 0;)
|
||||
if (! graph.graph.isConnected (connectors.getUnchecked(i)->connection))
|
||||
connectors.remove (i);
|
||||
|
||||
for (auto* fc : nodes)
|
||||
fc->update();
|
||||
|
||||
for (auto* cc : connectors)
|
||||
cc->update();
|
||||
|
||||
for (auto* f : graph.graph.getNodes())
|
||||
{
|
||||
if (getComponentForFilter (f->nodeID) == 0)
|
||||
{
|
||||
auto* comp = nodes.add (new FilterComponent (*this, f->nodeID));
|
||||
addAndMakeVisible (comp);
|
||||
comp->update();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& c : graph.graph.getConnections())
|
||||
{
|
||||
if (getComponentForConnection (c) == 0)
|
||||
{
|
||||
auto* comp = connectors.add (new ConnectorComponent (*this));
|
||||
addAndMakeVisible (comp);
|
||||
|
||||
comp->setInput (c.source);
|
||||
comp->setOutput (c.destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphEditorPanel::beginConnectorDrag (AudioProcessorGraph::NodeAndChannel source,
|
||||
AudioProcessorGraph::NodeAndChannel dest,
|
||||
const MouseEvent& e)
|
||||
{
|
||||
auto* c = dynamic_cast<ConnectorComponent*> (e.originalComponent);
|
||||
connectors.removeObject (c, false);
|
||||
draggingConnector = c;
|
||||
|
||||
if (draggingConnector == nullptr)
|
||||
draggingConnector = new ConnectorComponent (*this);
|
||||
|
||||
draggingConnector->setInput (source);
|
||||
draggingConnector->setOutput (dest);
|
||||
|
||||
addAndMakeVisible (draggingConnector);
|
||||
draggingConnector->toFront (false);
|
||||
|
||||
dragConnector (e);
|
||||
}
|
||||
|
||||
void GraphEditorPanel::dragConnector (const MouseEvent& e)
|
||||
{
|
||||
auto e2 = e.getEventRelativeTo (this);
|
||||
|
||||
if (draggingConnector != nullptr)
|
||||
{
|
||||
draggingConnector->setTooltip ({});
|
||||
|
||||
auto pos = e2.position;
|
||||
|
||||
if (auto* pin = findPinAt (pos))
|
||||
{
|
||||
auto connection = draggingConnector->connection;
|
||||
|
||||
if (connection.source.nodeID == 0 && ! pin->isInput)
|
||||
{
|
||||
connection.source = pin->pin;
|
||||
}
|
||||
else if (connection.destination.nodeID == 0 && pin->isInput)
|
||||
{
|
||||
connection.destination = pin->pin;
|
||||
}
|
||||
|
||||
if (graph.graph.canConnect (connection))
|
||||
{
|
||||
pos = (pin->getParentComponent()->getPosition() + pin->getBounds().getCentre()).toFloat();
|
||||
draggingConnector->setTooltip (pin->getTooltip());
|
||||
}
|
||||
}
|
||||
|
||||
if (draggingConnector->connection.source.nodeID == 0)
|
||||
draggingConnector->dragStart (pos);
|
||||
else
|
||||
draggingConnector->dragEnd (pos);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphEditorPanel::endDraggingConnector (const MouseEvent& e)
|
||||
{
|
||||
if (draggingConnector == nullptr)
|
||||
return;
|
||||
|
||||
draggingConnector->setTooltip ({});
|
||||
|
||||
auto e2 = e.getEventRelativeTo (this);
|
||||
auto connection = draggingConnector->connection;
|
||||
|
||||
draggingConnector = nullptr;
|
||||
|
||||
if (auto* pin = findPinAt (e2.position))
|
||||
{
|
||||
if (connection.source.nodeID == 0)
|
||||
{
|
||||
if (pin->isInput)
|
||||
return;
|
||||
|
||||
connection.source = pin->pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! pin->isInput)
|
||||
return;
|
||||
|
||||
connection.destination = pin->pin;
|
||||
}
|
||||
|
||||
graph.graph.addConnection (connection);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct GraphDocumentComponent::TooltipBar : public Component,
|
||||
private Timer
|
||||
{
|
||||
TooltipBar()
|
||||
{
|
||||
startTimer (100);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.setFont (Font (getHeight() * 0.7f, Font::bold));
|
||||
g.setColour (Colours::black);
|
||||
g.drawFittedText (tip, 10, 0, getWidth() - 12, getHeight(), Justification::centredLeft, 1);
|
||||
}
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
String newTip;
|
||||
|
||||
if (auto* underMouse = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse())
|
||||
if (auto* ttc = dynamic_cast<TooltipClient*> (underMouse))
|
||||
if (! (underMouse->isMouseButtonDown() || underMouse->isCurrentlyBlockedByAnotherModalComponent()))
|
||||
newTip = ttc->getTooltip();
|
||||
|
||||
if (newTip != tip)
|
||||
{
|
||||
tip = newTip;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
String tip;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipBar)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
GraphDocumentComponent::GraphDocumentComponent (AudioPluginFormatManager& fm, AudioDeviceManager& dm)
|
||||
: graph (new FilterGraph (fm)), deviceManager (dm),
|
||||
graphPlayer (getAppProperties().getUserSettings()->getBoolValue ("doublePrecisionProcessing", false))
|
||||
{
|
||||
addAndMakeVisible (graphPanel = new GraphEditorPanel (*graph));
|
||||
|
||||
deviceManager.addChangeListener (graphPanel);
|
||||
|
||||
graphPlayer.setProcessor (&graph->graph);
|
||||
|
||||
keyState.addListener (&graphPlayer.getMidiMessageCollector());
|
||||
|
||||
addAndMakeVisible (keyboardComp = new MidiKeyboardComponent (keyState, MidiKeyboardComponent::horizontalKeyboard));
|
||||
addAndMakeVisible (statusBar = new TooltipBar());
|
||||
|
||||
deviceManager.addAudioCallback (&graphPlayer);
|
||||
deviceManager.addMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());
|
||||
|
||||
graphPanel->updateComponents();
|
||||
}
|
||||
|
||||
GraphDocumentComponent::~GraphDocumentComponent()
|
||||
{
|
||||
releaseGraph();
|
||||
|
||||
keyState.removeListener (&graphPlayer.getMidiMessageCollector());
|
||||
}
|
||||
|
||||
void GraphDocumentComponent::resized()
|
||||
{
|
||||
const int keysHeight = 60;
|
||||
const int statusHeight = 20;
|
||||
|
||||
graphPanel->setBounds (0, 0, getWidth(), getHeight() - keysHeight);
|
||||
statusBar->setBounds (0, getHeight() - keysHeight - statusHeight, getWidth(), statusHeight);
|
||||
keyboardComp->setBounds (0, getHeight() - keysHeight, getWidth(), keysHeight);
|
||||
}
|
||||
|
||||
void GraphDocumentComponent::createNewPlugin (const PluginDescription& desc, Point<int> pos)
|
||||
{
|
||||
graphPanel->createNewPlugin (desc, pos);
|
||||
}
|
||||
|
||||
void GraphDocumentComponent::unfocusKeyboardComponent()
|
||||
{
|
||||
keyboardComp->unfocusAllComponents();
|
||||
}
|
||||
|
||||
void GraphDocumentComponent::releaseGraph()
|
||||
{
|
||||
deviceManager.removeAudioCallback (&graphPlayer);
|
||||
deviceManager.removeMidiInputCallback (String(), &graphPlayer.getMidiMessageCollector());
|
||||
|
||||
if (graphPanel != nullptr)
|
||||
{
|
||||
deviceManager.removeChangeListener (graphPanel);
|
||||
graphPanel = nullptr;
|
||||
}
|
||||
|
||||
keyboardComp = nullptr;
|
||||
statusBar = nullptr;
|
||||
|
||||
graphPlayer.setProcessor (nullptr);
|
||||
graph = nullptr;
|
||||
}
|
||||
|
||||
void GraphDocumentComponent::setDoublePrecision (bool doublePrecision)
|
||||
{
|
||||
graphPlayer.setDoublePrecisionProcessing (doublePrecision);
|
||||
}
|
||||
|
||||
bool GraphDocumentComponent::closeAnyOpenPluginWindows()
|
||||
{
|
||||
return graphPanel->graph.closeAnyOpenPluginWindows();
|
||||
}
|
||||
116
extras/AudioPluginHost/Source/GraphEditorPanel.h
Normal file
116
extras/AudioPluginHost/Source/GraphEditorPanel.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FilterGraph.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A panel that displays and edits a FilterGraph.
|
||||
*/
|
||||
class GraphEditorPanel : public Component,
|
||||
public ChangeListener
|
||||
{
|
||||
public:
|
||||
GraphEditorPanel (FilterGraph& graph);
|
||||
~GraphEditorPanel();
|
||||
|
||||
void createNewPlugin (const PluginDescription&, Point<int> position);
|
||||
|
||||
void paint (Graphics&) override;
|
||||
void mouseDown (const MouseEvent&) override;
|
||||
void resized() override;
|
||||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
void updateComponents();
|
||||
|
||||
//==============================================================================
|
||||
void beginConnectorDrag (AudioProcessorGraph::NodeAndChannel source,
|
||||
AudioProcessorGraph::NodeAndChannel dest,
|
||||
const MouseEvent&);
|
||||
void dragConnector (const MouseEvent&);
|
||||
void endDraggingConnector (const MouseEvent&);
|
||||
|
||||
//==============================================================================
|
||||
FilterGraph& graph;
|
||||
|
||||
private:
|
||||
struct FilterComponent;
|
||||
struct ConnectorComponent;
|
||||
struct PinComponent;
|
||||
|
||||
OwnedArray<FilterComponent> nodes;
|
||||
OwnedArray<ConnectorComponent> connectors;
|
||||
ScopedPointer<ConnectorComponent> draggingConnector;
|
||||
|
||||
FilterComponent* getComponentForFilter (AudioProcessorGraph::NodeID) const;
|
||||
ConnectorComponent* getComponentForConnection (const AudioProcessorGraph::Connection&) const;
|
||||
PinComponent* findPinAt (Point<float>) const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphEditorPanel)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A panel that embeds a GraphEditorPanel with a midi keyboard at the bottom.
|
||||
|
||||
It also manages the graph itself, and plays it.
|
||||
*/
|
||||
class GraphDocumentComponent : public Component
|
||||
{
|
||||
public:
|
||||
GraphDocumentComponent (AudioPluginFormatManager& formatManager,
|
||||
AudioDeviceManager& deviceManager);
|
||||
~GraphDocumentComponent();
|
||||
|
||||
//==============================================================================
|
||||
void createNewPlugin (const PluginDescription&, Point<int> position);
|
||||
void setDoublePrecision (bool doublePrecision);
|
||||
bool closeAnyOpenPluginWindows();
|
||||
|
||||
//==============================================================================
|
||||
ScopedPointer<FilterGraph> graph;
|
||||
|
||||
void resized();
|
||||
void unfocusKeyboardComponent();
|
||||
void releaseGraph();
|
||||
|
||||
ScopedPointer<GraphEditorPanel> graphPanel;
|
||||
ScopedPointer<MidiKeyboardComponent> keyboardComp;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioDeviceManager& deviceManager;
|
||||
AudioProcessorPlayer graphPlayer;
|
||||
MidiKeyboardState keyState;
|
||||
|
||||
struct TooltipBar;
|
||||
ScopedPointer<TooltipBar> statusBar;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GraphDocumentComponent)
|
||||
};
|
||||
133
extras/AudioPluginHost/Source/HostStartup.cpp
Normal file
133
extras/AudioPluginHost/Source/HostStartup.cpp
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "MainHostWindow.h"
|
||||
#include "InternalFilters.h"
|
||||
|
||||
#if ! (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU)
|
||||
#error "If you're building the audio plugin host, you probably want to enable VST and/or AU support"
|
||||
#endif
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class PluginHostApp : public JUCEApplication,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
PluginHostApp() {}
|
||||
|
||||
void initialise (const String&) override
|
||||
{
|
||||
// initialise our settings file..
|
||||
|
||||
PropertiesFile::Options options;
|
||||
options.applicationName = "Juce Audio Plugin Host";
|
||||
options.filenameSuffix = "settings";
|
||||
options.osxLibrarySubFolder = "Preferences";
|
||||
|
||||
appProperties = new ApplicationProperties();
|
||||
appProperties->setStorageParameters (options);
|
||||
|
||||
mainWindow = new MainHostWindow();
|
||||
mainWindow->setUsingNativeTitleBar (true);
|
||||
|
||||
commandManager.registerAllCommandsForTarget (this);
|
||||
commandManager.registerAllCommandsForTarget (mainWindow);
|
||||
|
||||
mainWindow->menuItemsChanged();
|
||||
|
||||
// Important note! We're going to use an async update here so that if we need
|
||||
// to re-open a file and instantiate some plugins, it will happen AFTER this
|
||||
// initialisation method has returned.
|
||||
// On Windows this probably won't make a difference, but on OSX there's a subtle event loop
|
||||
// issue that can happen if a plugin runs one of those irritating modal dialogs while it's
|
||||
// being loaded. If that happens inside this method, the OSX event loop seems to be in some
|
||||
// kind of special "initialisation" mode and things get confused. But if we load the plugin
|
||||
// later when the normal event loop is running, everything's fine.
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void handleAsyncUpdate() override
|
||||
{
|
||||
File fileToOpen;
|
||||
|
||||
for (int i = 0; i < getCommandLineParameterArray().size(); ++i)
|
||||
{
|
||||
fileToOpen = File::getCurrentWorkingDirectory().getChildFile (getCommandLineParameterArray()[i]);
|
||||
|
||||
if (fileToOpen.existsAsFile())
|
||||
break;
|
||||
}
|
||||
|
||||
if (! fileToOpen.existsAsFile())
|
||||
{
|
||||
RecentlyOpenedFilesList recentFiles;
|
||||
recentFiles.restoreFromString (getAppProperties().getUserSettings()->getValue ("recentFilterGraphFiles"));
|
||||
|
||||
if (recentFiles.getNumFiles() > 0)
|
||||
fileToOpen = recentFiles.getFile (0);
|
||||
}
|
||||
|
||||
if (fileToOpen.existsAsFile())
|
||||
if (auto* graph = mainWindow->graphHolder.get())
|
||||
if (auto* ioGraph = graph->graph.get())
|
||||
ioGraph->loadFrom (fileToOpen, true);
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
mainWindow = nullptr;
|
||||
appProperties = nullptr;
|
||||
LookAndFeel::setDefaultLookAndFeel (nullptr);
|
||||
}
|
||||
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
if (mainWindow != nullptr)
|
||||
mainWindow->tryToQuitApplication();
|
||||
else
|
||||
JUCEApplicationBase::quit();
|
||||
}
|
||||
|
||||
const String getApplicationName() override { return "Juce Plug-In Host"; }
|
||||
const String getApplicationVersion() override { return ProjectInfo::versionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
|
||||
ApplicationCommandManager commandManager;
|
||||
ScopedPointer<ApplicationProperties> appProperties;
|
||||
|
||||
private:
|
||||
ScopedPointer<MainHostWindow> mainWindow;
|
||||
};
|
||||
|
||||
static PluginHostApp& getApp() { return *dynamic_cast<PluginHostApp*>(JUCEApplication::getInstance()); }
|
||||
ApplicationCommandManager& getCommandManager() { return getApp().commandManager; }
|
||||
ApplicationProperties& getAppProperties() { return *getApp().appProperties; }
|
||||
|
||||
|
||||
// This kicks the whole thing off..
|
||||
START_JUCE_APPLICATION (PluginHostApp)
|
||||
81
extras/AudioPluginHost/Source/InternalFilters.cpp
Normal file
81
extras/AudioPluginHost/Source/InternalFilters.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "InternalFilters.h"
|
||||
#include "FilterGraph.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
InternalPluginFormat::InternalPluginFormat()
|
||||
{
|
||||
{
|
||||
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
|
||||
p.fillInPluginDescription (audioOutDesc);
|
||||
}
|
||||
|
||||
{
|
||||
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
|
||||
p.fillInPluginDescription (audioInDesc);
|
||||
}
|
||||
|
||||
{
|
||||
AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
|
||||
p.fillInPluginDescription (midiInDesc);
|
||||
}
|
||||
}
|
||||
|
||||
AudioPluginInstance* InternalPluginFormat::createInstance (const String& name)
|
||||
{
|
||||
if (name == audioOutDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
|
||||
if (name == audioInDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode);
|
||||
if (name == midiInDesc.name) return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InternalPluginFormat::createPluginInstance (const PluginDescription& desc,
|
||||
double /*initialSampleRate*/,
|
||||
int /*initialBufferSize*/,
|
||||
void* userData,
|
||||
void (*callback) (void*, AudioPluginInstance*, const String&))
|
||||
{
|
||||
auto* p = createInstance (desc.name);
|
||||
|
||||
callback (userData, p, p == nullptr ? NEEDS_TRANS ("Invalid internal filter name") : String());
|
||||
}
|
||||
|
||||
bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void InternalPluginFormat::getAllTypes (OwnedArray<PluginDescription>& results)
|
||||
{
|
||||
results.add (new PluginDescription (audioInDesc));
|
||||
results.add (new PluginDescription (audioOutDesc));
|
||||
results.add (new PluginDescription (midiInDesc));
|
||||
}
|
||||
66
extras/AudioPluginHost/Source/InternalFilters.h
Normal file
66
extras/AudioPluginHost/Source/InternalFilters.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FilterGraph.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Manages the internal plugin types.
|
||||
*/
|
||||
class InternalPluginFormat : public AudioPluginFormat
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
InternalPluginFormat();
|
||||
~InternalPluginFormat() {}
|
||||
|
||||
//==============================================================================
|
||||
PluginDescription audioInDesc, audioOutDesc, midiInDesc;
|
||||
|
||||
void getAllTypes (OwnedArray<PluginDescription>&);
|
||||
|
||||
//==============================================================================
|
||||
String getName() const override { return "Internal"; }
|
||||
bool fileMightContainThisPluginType (const String&) override { return true; }
|
||||
FileSearchPath getDefaultLocationsToSearch() override { return {}; }
|
||||
bool canScanForPlugins() const override { return false; }
|
||||
void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) override {}
|
||||
bool doesPluginStillExist (const PluginDescription&) override { return true; }
|
||||
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override { return fileOrIdentifier; }
|
||||
bool pluginNeedsRescanning (const PluginDescription&) override { return false; }
|
||||
StringArray searchPathsForPlugins (const FileSearchPath&, bool, bool) override { return {}; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void createPluginInstance (const PluginDescription&, double initialSampleRate, int initialBufferSize,
|
||||
void* userData, void (*callback) (void*, AudioPluginInstance*, const String&)) override;
|
||||
AudioPluginInstance* createInstance (const String& name);
|
||||
|
||||
bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const noexcept override;
|
||||
};
|
||||
604
extras/AudioPluginHost/Source/MainHostWindow.cpp
Normal file
604
extras/AudioPluginHost/Source/MainHostWindow.cpp
Normal file
|
|
@ -0,0 +1,604 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../JuceLibraryCode/JuceHeader.h"
|
||||
#include "MainHostWindow.h"
|
||||
#include "InternalFilters.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class MainHostWindow::PluginListWindow : public DocumentWindow
|
||||
{
|
||||
public:
|
||||
PluginListWindow (MainHostWindow& mw, AudioPluginFormatManager& pluginFormatManager)
|
||||
: DocumentWindow ("Available Plugins",
|
||||
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::minimiseButton | DocumentWindow::closeButton),
|
||||
owner (mw)
|
||||
{
|
||||
auto deadMansPedalFile = getAppProperties().getUserSettings()
|
||||
->getFile().getSiblingFile ("RecentlyCrashedPluginsList");
|
||||
|
||||
setContentOwned (new PluginListComponent (pluginFormatManager,
|
||||
owner.knownPluginList,
|
||||
deadMansPedalFile,
|
||||
getAppProperties().getUserSettings(), true), true);
|
||||
|
||||
setResizable (true, false);
|
||||
setResizeLimits (300, 400, 800, 1500);
|
||||
setTopLeftPosition (60, 60);
|
||||
|
||||
restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("listWindowPos"));
|
||||
setVisible (true);
|
||||
}
|
||||
|
||||
~PluginListWindow()
|
||||
{
|
||||
getAppProperties().getUserSettings()->setValue ("listWindowPos", getWindowStateAsString());
|
||||
clearContentComponent();
|
||||
}
|
||||
|
||||
void closeButtonPressed() override
|
||||
{
|
||||
owner.pluginListWindow = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
MainHostWindow& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListWindow)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
MainHostWindow::MainHostWindow()
|
||||
: DocumentWindow (JUCEApplication::getInstance()->getApplicationName(),
|
||||
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::allButtons)
|
||||
{
|
||||
formatManager.addDefaultFormats();
|
||||
formatManager.addFormat (new InternalPluginFormat());
|
||||
|
||||
ScopedPointer<XmlElement> savedAudioState (getAppProperties().getUserSettings()
|
||||
->getXmlValue ("audioDeviceState"));
|
||||
|
||||
deviceManager.initialise (256, 256, savedAudioState, true);
|
||||
|
||||
setResizable (true, false);
|
||||
setResizeLimits (500, 400, 10000, 10000);
|
||||
centreWithSize (800, 600);
|
||||
|
||||
graphHolder = new GraphDocumentComponent (formatManager, deviceManager);
|
||||
|
||||
setContentNonOwned (graphHolder, false);
|
||||
|
||||
restoreWindowStateFromString (getAppProperties().getUserSettings()->getValue ("mainWindowPos"));
|
||||
|
||||
setVisible (true);
|
||||
|
||||
InternalPluginFormat internalFormat;
|
||||
internalFormat.getAllTypes (internalTypes);
|
||||
|
||||
ScopedPointer<XmlElement> savedPluginList (getAppProperties().getUserSettings()->getXmlValue ("pluginList"));
|
||||
|
||||
if (savedPluginList != nullptr)
|
||||
knownPluginList.recreateFromXml (*savedPluginList);
|
||||
|
||||
pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings()
|
||||
->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer);
|
||||
|
||||
knownPluginList.addChangeListener (this);
|
||||
|
||||
if (auto* filterGraph = graphHolder->graph.get())
|
||||
filterGraph->addChangeListener (this);
|
||||
|
||||
addKeyListener (getCommandManager().getKeyMappings());
|
||||
|
||||
Process::setPriority (Process::HighPriority);
|
||||
|
||||
#if JUCE_MAC
|
||||
setMacMainMenu (this);
|
||||
#else
|
||||
setMenuBar (this);
|
||||
#endif
|
||||
|
||||
getCommandManager().setFirstCommandTarget (this);
|
||||
}
|
||||
|
||||
MainHostWindow::~MainHostWindow()
|
||||
{
|
||||
pluginListWindow = nullptr;
|
||||
knownPluginList.removeChangeListener (this);
|
||||
|
||||
if (auto* filterGraph = graphHolder->graph.get())
|
||||
filterGraph->removeChangeListener (this);
|
||||
|
||||
getAppProperties().getUserSettings()->setValue ("mainWindowPos", getWindowStateAsString());
|
||||
clearContentComponent();
|
||||
|
||||
#if JUCE_MAC
|
||||
setMacMainMenu (nullptr);
|
||||
#else
|
||||
setMenuBar (nullptr);
|
||||
#endif
|
||||
|
||||
graphHolder = nullptr;
|
||||
}
|
||||
|
||||
void MainHostWindow::closeButtonPressed()
|
||||
{
|
||||
tryToQuitApplication();
|
||||
}
|
||||
|
||||
struct AsyncQuitRetrier : private Timer
|
||||
{
|
||||
AsyncQuitRetrier() { startTimer (500); }
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
stopTimer();
|
||||
delete this;
|
||||
|
||||
if (auto app = JUCEApplicationBase::getInstance())
|
||||
app->systemRequestedQuit();
|
||||
}
|
||||
};
|
||||
|
||||
void MainHostWindow::tryToQuitApplication()
|
||||
{
|
||||
if (graphHolder->closeAnyOpenPluginWindows())
|
||||
{
|
||||
// Really important thing to note here: if the last call just deleted any plugin windows,
|
||||
// we won't exit immediately - instead we'll use our AsyncQuitRetrier to let the message
|
||||
// loop run for another brief moment, then try again. This will give any plugins a chance
|
||||
// to flush any GUI events that may have been in transit before the app forces them to
|
||||
// be unloaded
|
||||
new AsyncQuitRetrier();
|
||||
}
|
||||
else if (ModalComponentManager::getInstance()->cancelAllModalComponents())
|
||||
{
|
||||
new AsyncQuitRetrier();
|
||||
}
|
||||
else if (graphHolder == nullptr || graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
|
||||
{
|
||||
// Some plug-ins do not want [NSApp stop] to be called
|
||||
// before the plug-ins are not deallocated.
|
||||
graphHolder->releaseGraph();
|
||||
|
||||
JUCEApplication::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void MainHostWindow::changeListenerCallback (ChangeBroadcaster* changed)
|
||||
{
|
||||
if (changed == &knownPluginList)
|
||||
{
|
||||
menuItemsChanged();
|
||||
|
||||
// save the plugin list every time it gets chnaged, so that if we're scanning
|
||||
// and it crashes, we've still saved the previous ones
|
||||
ScopedPointer<XmlElement> savedPluginList (knownPluginList.createXml());
|
||||
|
||||
if (savedPluginList != nullptr)
|
||||
{
|
||||
getAppProperties().getUserSettings()->setValue ("pluginList", savedPluginList);
|
||||
getAppProperties().saveIfNeeded();
|
||||
}
|
||||
}
|
||||
else if (graphHolder != nullptr && changed == graphHolder->graph)
|
||||
{
|
||||
auto title = JUCEApplication::getInstance()->getApplicationName();
|
||||
auto f = graphHolder->graph->getFile();
|
||||
|
||||
if (f.existsAsFile())
|
||||
title = f.getFileName() + " - " + title;
|
||||
|
||||
setName (title);
|
||||
}
|
||||
}
|
||||
|
||||
StringArray MainHostWindow::getMenuBarNames()
|
||||
{
|
||||
StringArray names;
|
||||
names.add ("File");
|
||||
names.add ("Plugins");
|
||||
names.add ("Options");
|
||||
names.add ("Windows");
|
||||
return names;
|
||||
}
|
||||
|
||||
PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& /*menuName*/)
|
||||
{
|
||||
PopupMenu menu;
|
||||
|
||||
if (topLevelMenuIndex == 0)
|
||||
{
|
||||
// "File" menu
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::newFile);
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::open);
|
||||
|
||||
RecentlyOpenedFilesList recentFiles;
|
||||
recentFiles.restoreFromString (getAppProperties().getUserSettings()
|
||||
->getValue ("recentFilterGraphFiles"));
|
||||
|
||||
PopupMenu recentFilesMenu;
|
||||
recentFiles.createPopupMenuItems (recentFilesMenu, 100, true, true);
|
||||
menu.addSubMenu ("Open recent file", recentFilesMenu);
|
||||
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::save);
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::saveAs);
|
||||
menu.addSeparator();
|
||||
menu.addCommandItem (&getCommandManager(), StandardApplicationCommandIDs::quit);
|
||||
}
|
||||
else if (topLevelMenuIndex == 1)
|
||||
{
|
||||
// "Plugins" menu
|
||||
PopupMenu pluginsMenu;
|
||||
addPluginsToMenu (pluginsMenu);
|
||||
menu.addSubMenu ("Create plugin", pluginsMenu);
|
||||
menu.addSeparator();
|
||||
menu.addItem (250, "Delete all plugins");
|
||||
}
|
||||
else if (topLevelMenuIndex == 2)
|
||||
{
|
||||
// "Options" menu
|
||||
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::showPluginListEditor);
|
||||
|
||||
PopupMenu sortTypeMenu;
|
||||
sortTypeMenu.addItem (200, "List plugins in default order", true, pluginSortMethod == KnownPluginList::defaultOrder);
|
||||
sortTypeMenu.addItem (201, "List plugins in alphabetical order", true, pluginSortMethod == KnownPluginList::sortAlphabetically);
|
||||
sortTypeMenu.addItem (202, "List plugins by category", true, pluginSortMethod == KnownPluginList::sortByCategory);
|
||||
sortTypeMenu.addItem (203, "List plugins by manufacturer", true, pluginSortMethod == KnownPluginList::sortByManufacturer);
|
||||
sortTypeMenu.addItem (204, "List plugins based on the directory structure", true, pluginSortMethod == KnownPluginList::sortByFileSystemLocation);
|
||||
menu.addSubMenu ("Plugin menu type", sortTypeMenu);
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::showAudioSettings);
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::toggleDoublePrecision);
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::aboutBox);
|
||||
}
|
||||
else if (topLevelMenuIndex == 3)
|
||||
{
|
||||
menu.addCommandItem (&getCommandManager(), CommandIDs::allWindowsForward);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/)
|
||||
{
|
||||
if (menuItemID == 250)
|
||||
{
|
||||
if (graphHolder != nullptr)
|
||||
if (auto* graph = graphHolder->graph.get())
|
||||
graph->clear();
|
||||
}
|
||||
else if (menuItemID >= 100 && menuItemID < 200)
|
||||
{
|
||||
RecentlyOpenedFilesList recentFiles;
|
||||
recentFiles.restoreFromString (getAppProperties().getUserSettings()
|
||||
->getValue ("recentFilterGraphFiles"));
|
||||
|
||||
if (graphHolder != nullptr)
|
||||
if (auto* graph = graphHolder->graph.get())
|
||||
if (graph != nullptr && graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
|
||||
graph->loadFrom (recentFiles.getFile (menuItemID - 100), true);
|
||||
}
|
||||
else if (menuItemID >= 200 && menuItemID < 210)
|
||||
{
|
||||
if (menuItemID == 200) pluginSortMethod = KnownPluginList::defaultOrder;
|
||||
else if (menuItemID == 201) pluginSortMethod = KnownPluginList::sortAlphabetically;
|
||||
else if (menuItemID == 202) pluginSortMethod = KnownPluginList::sortByCategory;
|
||||
else if (menuItemID == 203) pluginSortMethod = KnownPluginList::sortByManufacturer;
|
||||
else if (menuItemID == 204) pluginSortMethod = KnownPluginList::sortByFileSystemLocation;
|
||||
|
||||
getAppProperties().getUserSettings()->setValue ("pluginSortMethod", (int) pluginSortMethod);
|
||||
|
||||
menuItemsChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto* desc = getChosenType (menuItemID))
|
||||
createPlugin (*desc,
|
||||
{ proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),
|
||||
proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) });
|
||||
}
|
||||
}
|
||||
|
||||
void MainHostWindow::menuBarActivated (bool isActivated)
|
||||
{
|
||||
if (isActivated && graphHolder != nullptr)
|
||||
graphHolder->unfocusKeyboardComponent();
|
||||
}
|
||||
|
||||
void MainHostWindow::createPlugin (const PluginDescription& desc, Point<int> pos)
|
||||
{
|
||||
if (graphHolder != nullptr)
|
||||
graphHolder->createNewPlugin (desc, pos);
|
||||
}
|
||||
|
||||
void MainHostWindow::addPluginsToMenu (PopupMenu& m) const
|
||||
{
|
||||
if (graphHolder != nullptr)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (auto* t : internalTypes)
|
||||
m.addItem (++i, t->name + " (" + t->pluginFormatName + ")",
|
||||
graphHolder->graph->getNodeForName (t->name) == nullptr);
|
||||
}
|
||||
|
||||
m.addSeparator();
|
||||
|
||||
knownPluginList.addToMenu (m, pluginSortMethod);
|
||||
}
|
||||
|
||||
const PluginDescription* MainHostWindow::getChosenType (const int menuID) const
|
||||
{
|
||||
if (menuID >= 1 && menuID < 1 + internalTypes.size())
|
||||
return internalTypes [menuID - 1];
|
||||
|
||||
return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ApplicationCommandTarget* MainHostWindow::getNextCommandTarget()
|
||||
{
|
||||
return findFirstTargetParentComponent();
|
||||
}
|
||||
|
||||
void MainHostWindow::getAllCommands (Array<CommandID>& commands)
|
||||
{
|
||||
// this returns the set of all commands that this target can perform..
|
||||
const CommandID ids[] = { CommandIDs::newFile,
|
||||
CommandIDs::open,
|
||||
CommandIDs::save,
|
||||
CommandIDs::saveAs,
|
||||
CommandIDs::showPluginListEditor,
|
||||
CommandIDs::showAudioSettings,
|
||||
CommandIDs::toggleDoublePrecision,
|
||||
CommandIDs::aboutBox,
|
||||
CommandIDs::allWindowsForward
|
||||
};
|
||||
|
||||
commands.addArray (ids, numElementsInArray (ids));
|
||||
}
|
||||
|
||||
void MainHostWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
|
||||
{
|
||||
const String category ("General");
|
||||
|
||||
switch (commandID)
|
||||
{
|
||||
case CommandIDs::newFile:
|
||||
result.setInfo ("New", "Creates a new filter graph file", category, 0);
|
||||
result.defaultKeypresses.add(KeyPress('n', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::open:
|
||||
result.setInfo ("Open...", "Opens a filter graph file", category, 0);
|
||||
result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::save:
|
||||
result.setInfo ("Save", "Saves the current graph to a file", category, 0);
|
||||
result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::saveAs:
|
||||
result.setInfo ("Save As...",
|
||||
"Saves a copy of the current graph to a file",
|
||||
category, 0);
|
||||
result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::shiftModifier | ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::showPluginListEditor:
|
||||
result.setInfo ("Edit the list of available plug-Ins...", String(), category, 0);
|
||||
result.addDefaultKeypress ('p', ModifierKeys::commandModifier);
|
||||
break;
|
||||
|
||||
case CommandIDs::showAudioSettings:
|
||||
result.setInfo ("Change the audio device settings", String(), category, 0);
|
||||
result.addDefaultKeypress ('a', ModifierKeys::commandModifier);
|
||||
break;
|
||||
|
||||
case CommandIDs::toggleDoublePrecision:
|
||||
updatePrecisionMenuItem (result);
|
||||
break;
|
||||
|
||||
case CommandIDs::aboutBox:
|
||||
result.setInfo ("About...", String(), category, 0);
|
||||
break;
|
||||
|
||||
case CommandIDs::allWindowsForward:
|
||||
result.setInfo ("All Windows Forward", "Bring all plug-in windows forward", category, 0);
|
||||
result.addDefaultKeypress ('w', ModifierKeys::commandModifier);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool MainHostWindow::perform (const InvocationInfo& info)
|
||||
{
|
||||
switch (info.commandID)
|
||||
{
|
||||
case CommandIDs::newFile:
|
||||
if (graphHolder != nullptr && graphHolder->graph != nullptr && graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
|
||||
graphHolder->graph->newDocument();
|
||||
break;
|
||||
|
||||
case CommandIDs::open:
|
||||
if (graphHolder != nullptr && graphHolder->graph != nullptr && graphHolder->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
|
||||
graphHolder->graph->loadFromUserSpecifiedFile (true);
|
||||
break;
|
||||
|
||||
case CommandIDs::save:
|
||||
if (graphHolder != nullptr && graphHolder->graph != nullptr)
|
||||
graphHolder->graph->save (true, true);
|
||||
break;
|
||||
|
||||
case CommandIDs::saveAs:
|
||||
if (graphHolder != nullptr && graphHolder->graph != nullptr)
|
||||
graphHolder->graph->saveAs (File(), true, true, true);
|
||||
break;
|
||||
|
||||
case CommandIDs::showPluginListEditor:
|
||||
if (pluginListWindow == nullptr)
|
||||
pluginListWindow = new PluginListWindow (*this, formatManager);
|
||||
|
||||
pluginListWindow->toFront (true);
|
||||
break;
|
||||
|
||||
case CommandIDs::showAudioSettings:
|
||||
showAudioSettings();
|
||||
break;
|
||||
|
||||
case CommandIDs::toggleDoublePrecision:
|
||||
if (auto* props = getAppProperties().getUserSettings())
|
||||
{
|
||||
bool newIsDoublePrecision = ! isDoublePrecisionProcessing();
|
||||
props->setValue ("doublePrecisionProcessing", var (newIsDoublePrecision));
|
||||
|
||||
{
|
||||
ApplicationCommandInfo cmdInfo (info.commandID);
|
||||
updatePrecisionMenuItem (cmdInfo);
|
||||
menuItemsChanged();
|
||||
}
|
||||
|
||||
if (graphHolder != nullptr)
|
||||
graphHolder->setDoublePrecision (newIsDoublePrecision);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommandIDs::aboutBox:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case CommandIDs::allWindowsForward:
|
||||
{
|
||||
auto& desktop = Desktop::getInstance();
|
||||
|
||||
for (int i = 0; i < desktop.getNumComponents(); ++i)
|
||||
desktop.getComponent (i)->toBehind (this);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainHostWindow::showAudioSettings()
|
||||
{
|
||||
AudioDeviceSelectorComponent audioSettingsComp (deviceManager,
|
||||
0, 256,
|
||||
0, 256,
|
||||
true, true, true, false);
|
||||
|
||||
audioSettingsComp.setSize (500, 450);
|
||||
|
||||
DialogWindow::LaunchOptions o;
|
||||
o.content.setNonOwned (&audioSettingsComp);
|
||||
o.dialogTitle = "Audio Settings";
|
||||
o.componentToCentreAround = this;
|
||||
o.dialogBackgroundColour = getLookAndFeel().findColour (ResizableWindow::backgroundColourId);
|
||||
o.escapeKeyTriggersCloseButton = true;
|
||||
o.useNativeTitleBar = false;
|
||||
o.resizable = false;
|
||||
|
||||
o.runModal();
|
||||
|
||||
ScopedPointer<XmlElement> audioState (deviceManager.createStateXml());
|
||||
|
||||
getAppProperties().getUserSettings()->setValue ("audioDeviceState", audioState);
|
||||
getAppProperties().getUserSettings()->saveIfNeeded();
|
||||
|
||||
if (graphHolder != nullptr)
|
||||
if (graphHolder->graph != nullptr)
|
||||
graphHolder->graph->graph.removeIllegalConnections();
|
||||
}
|
||||
|
||||
bool MainHostWindow::isInterestedInFileDrag (const StringArray&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainHostWindow::fileDragEnter (const StringArray&, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void MainHostWindow::fileDragMove (const StringArray&, int, int)
|
||||
{
|
||||
}
|
||||
|
||||
void MainHostWindow::fileDragExit (const StringArray&)
|
||||
{
|
||||
}
|
||||
|
||||
void MainHostWindow::filesDropped (const StringArray& files, int x, int y)
|
||||
{
|
||||
if (graphHolder != nullptr)
|
||||
{
|
||||
if (files.size() == 1 && File (files[0]).hasFileExtension (FilterGraph::getFilenameSuffix()))
|
||||
{
|
||||
if (auto* filterGraph = graphHolder->graph.get())
|
||||
if (filterGraph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
|
||||
filterGraph->loadFrom (File (files[0]), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
OwnedArray<PluginDescription> typesFound;
|
||||
knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound);
|
||||
|
||||
auto pos = graphHolder->getLocalPoint (this, Point<int> (x, y));
|
||||
|
||||
for (int i = 0; i < jmin (5, typesFound.size()); ++i)
|
||||
if (auto* desc = typesFound.getUnchecked(i))
|
||||
createPlugin (*desc, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MainHostWindow::isDoublePrecisionProcessing()
|
||||
{
|
||||
if (auto* props = getAppProperties().getUserSettings())
|
||||
return props->getBoolValue ("doublePrecisionProcessing", false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainHostWindow::updatePrecisionMenuItem (ApplicationCommandInfo& info)
|
||||
{
|
||||
info.setInfo ("Double floating point precision rendering", String(), "General", 0);
|
||||
info.setTicked (isDoublePrecisionProcessing());
|
||||
}
|
||||
109
extras/AudioPluginHost/Source/MainHostWindow.h
Normal file
109
extras/AudioPluginHost/Source/MainHostWindow.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FilterGraph.h"
|
||||
#include "GraphEditorPanel.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
namespace CommandIDs
|
||||
{
|
||||
static const int open = 0x30000;
|
||||
static const int save = 0x30001;
|
||||
static const int saveAs = 0x30002;
|
||||
static const int newFile = 0x30003;
|
||||
static const int showPluginListEditor = 0x30100;
|
||||
static const int showAudioSettings = 0x30200;
|
||||
static const int aboutBox = 0x30300;
|
||||
static const int allWindowsForward = 0x30400;
|
||||
static const int toggleDoublePrecision = 0x30500;
|
||||
}
|
||||
|
||||
ApplicationCommandManager& getCommandManager();
|
||||
ApplicationProperties& getAppProperties();
|
||||
|
||||
//==============================================================================
|
||||
class MainHostWindow : public DocumentWindow,
|
||||
public MenuBarModel,
|
||||
public ApplicationCommandTarget,
|
||||
public ChangeListener,
|
||||
public FileDragAndDropTarget
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
MainHostWindow();
|
||||
~MainHostWindow();
|
||||
|
||||
//==============================================================================
|
||||
void closeButtonPressed() override;
|
||||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
|
||||
bool isInterestedInFileDrag (const StringArray& files) override;
|
||||
void fileDragEnter (const StringArray& files, int, int) override;
|
||||
void fileDragMove (const StringArray& files, int, int) override;
|
||||
void fileDragExit (const StringArray& files) override;
|
||||
void filesDropped (const StringArray& files, int, int) override;
|
||||
|
||||
void menuBarActivated (bool isActive) override;
|
||||
|
||||
StringArray getMenuBarNames() override;
|
||||
PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName) override;
|
||||
void menuItemSelected (int menuItemID, int topLevelMenuIndex) override;
|
||||
ApplicationCommandTarget* getNextCommandTarget() override;
|
||||
void getAllCommands (Array<CommandID>&) override;
|
||||
void getCommandInfo (CommandID, ApplicationCommandInfo&) override;
|
||||
bool perform (const InvocationInfo&) override;
|
||||
|
||||
void tryToQuitApplication();
|
||||
|
||||
void createPlugin (const PluginDescription&, Point<int> pos);
|
||||
|
||||
void addPluginsToMenu (PopupMenu&) const;
|
||||
const PluginDescription* getChosenType (int menuID) const;
|
||||
|
||||
bool isDoublePrecisionProcessing();
|
||||
void updatePrecisionMenuItem (ApplicationCommandInfo& info);
|
||||
|
||||
ScopedPointer<GraphDocumentComponent> graphHolder;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioDeviceManager deviceManager;
|
||||
AudioPluginFormatManager formatManager;
|
||||
|
||||
OwnedArray<PluginDescription> internalTypes;
|
||||
KnownPluginList knownPluginList;
|
||||
KnownPluginList::SortMethod pluginSortMethod;
|
||||
|
||||
class PluginListWindow;
|
||||
ScopedPointer<PluginListWindow> pluginListWindow;
|
||||
|
||||
void showAudioSettings();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainHostWindow)
|
||||
};
|
||||
201
extras/AudioPluginHost/Source/PluginWindow.h
Normal file
201
extras/AudioPluginHost/Source/PluginWindow.h
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2017 - ROLI Ltd.
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
||||
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
||||
27th April 2017).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-5-licence
|
||||
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FilterIOConfiguration.h"
|
||||
class FilterGraph;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A desktop window containing a plugin's GUI.
|
||||
*/
|
||||
class PluginWindow : public DocumentWindow
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
normal = 0,
|
||||
generic,
|
||||
programs,
|
||||
audioIO,
|
||||
numTypes
|
||||
};
|
||||
|
||||
PluginWindow (AudioProcessorGraph::Node* n, Type t, OwnedArray<PluginWindow>& windowList)
|
||||
: DocumentWindow (n->getProcessor()->getName(),
|
||||
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::minimiseButton | DocumentWindow::closeButton),
|
||||
activeWindowList (windowList),
|
||||
node (n), type (t)
|
||||
{
|
||||
setSize (400, 300);
|
||||
|
||||
if (auto* ui = createProcessorEditor (*node->getProcessor(), type))
|
||||
setContentOwned (ui, true);
|
||||
|
||||
setTopLeftPosition (node->properties.getWithDefault (getLastXProp (type), Random::getSystemRandom().nextInt (500)),
|
||||
node->properties.getWithDefault (getLastYProp (type), Random::getSystemRandom().nextInt (500)));
|
||||
|
||||
node->properties.set (getOpenProp (type), true);
|
||||
|
||||
setVisible (true);
|
||||
}
|
||||
|
||||
~PluginWindow()
|
||||
{
|
||||
clearContentComponent();
|
||||
}
|
||||
|
||||
void moved() override
|
||||
{
|
||||
node->properties.set (getLastXProp (type), getX());
|
||||
node->properties.set (getLastYProp (type), getY());
|
||||
}
|
||||
|
||||
void closeButtonPressed() override
|
||||
{
|
||||
node->properties.set (getOpenProp (type), false);
|
||||
activeWindowList.removeObject (this);
|
||||
}
|
||||
|
||||
static String getLastXProp (Type type) { return "uiLastX_" + getTypeName (type); }
|
||||
static String getLastYProp (Type type) { return "uiLastY_" + getTypeName (type); }
|
||||
static String getOpenProp (Type type) { return "uiopen_" + getTypeName (type); }
|
||||
|
||||
OwnedArray<PluginWindow>& activeWindowList;
|
||||
const AudioProcessorGraph::Node::Ptr node;
|
||||
const Type type;
|
||||
|
||||
private:
|
||||
float getDesktopScaleFactor() const override { return 1.0f; }
|
||||
|
||||
static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, PluginWindow::Type type)
|
||||
{
|
||||
if (type == PluginWindow::Type::normal)
|
||||
{
|
||||
if (auto* ui = processor.createEditorIfNeeded())
|
||||
return ui;
|
||||
|
||||
type = PluginWindow::Type::generic;
|
||||
}
|
||||
|
||||
if (type == PluginWindow::Type::generic)
|
||||
return new GenericAudioProcessorEditor (&processor);
|
||||
|
||||
if (type == PluginWindow::Type::programs)
|
||||
return new ProgramAudioProcessorEditor (processor);
|
||||
|
||||
if (type == PluginWindow::Type::audioIO)
|
||||
return new FilterIOConfigurationWindow (processor);
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
static String getTypeName (Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Type::normal: return "Normal";
|
||||
case Type::generic: return "Generic";
|
||||
case Type::programs: return "Programs";
|
||||
case Type::audioIO: return "IO";
|
||||
default: return {};
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct ProgramAudioProcessorEditor : public AudioProcessorEditor
|
||||
{
|
||||
ProgramAudioProcessorEditor (AudioProcessor& p) : AudioProcessorEditor (p)
|
||||
{
|
||||
setOpaque (true);
|
||||
|
||||
addAndMakeVisible (panel);
|
||||
|
||||
Array<PropertyComponent*> programs;
|
||||
|
||||
auto numPrograms = p.getNumPrograms();
|
||||
int totalHeight = 0;
|
||||
|
||||
for (int i = 0; i < numPrograms; ++i)
|
||||
{
|
||||
auto name = p.getProgramName (i).trim();
|
||||
|
||||
if (name.isEmpty())
|
||||
name = "Unnamed";
|
||||
|
||||
auto pc = new PropertyComp (name, p);
|
||||
programs.add (pc);
|
||||
totalHeight += pc->getPreferredHeight();
|
||||
}
|
||||
|
||||
panel.addProperties (programs);
|
||||
|
||||
setSize (400, jlimit (25, 400, totalHeight));
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (Colours::grey);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
panel.setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
private:
|
||||
struct PropertyComp : public PropertyComponent,
|
||||
private AudioProcessorListener
|
||||
{
|
||||
PropertyComp (const String& name, AudioProcessor& p) : PropertyComponent (name), owner (p)
|
||||
{
|
||||
owner.addListener (this);
|
||||
}
|
||||
|
||||
~PropertyComp()
|
||||
{
|
||||
owner.removeListener (this);
|
||||
}
|
||||
|
||||
void refresh() override {}
|
||||
void audioProcessorChanged (AudioProcessor*) override {}
|
||||
void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}
|
||||
|
||||
AudioProcessor& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyComp)
|
||||
};
|
||||
|
||||
PropertyPanel panel;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor)
|
||||
};
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow)
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue