Browse Source

Merge branch 'falkTX:main' into open_recent

pull/1834/head
kleph GitHub 8 months ago
parent
commit
5618919a6b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
100 changed files with 2811 additions and 5809 deletions
  1. +0
    -3
      .clang-format
  2. +5
    -5
      .github/workflows/build.yml
  3. +13
    -16
      .github/workflows/cmake.yml
  4. +8
    -8
      .github/workflows/dpf.yml
  5. +10
    -10
      .github/workflows/release.yml
  6. +1
    -0
      .gitignore
  7. +4
    -10
      INSTALL.md
  8. +13
    -15
      Makefile
  9. +11
    -36
      Makefile.print.mk
  10. +1
    -1
      README.md
  11. +2
    -7
      cmake/CMakeLists.txt
  12. +6
    -0
      data/docker/.dockerignore
  13. +46
    -0
      data/docker/Dockerfile
  14. +25
    -0
      data/docker/build.sh
  15. +0
    -9
      resources/ui/carla_host.ui
  16. +1
    -1
      resources/ui/carla_settings.ui
  17. +96
    -75
      source/Makefile.deps.mk
  18. +6
    -16
      source/Makefile.mk
  19. +7
    -26
      source/backend/CarlaEngine.hpp
  20. +2
    -24
      source/backend/CarlaEngineInit.hpp
  21. +2
    -21
      source/backend/CarlaHost.h
  22. +3
    -19
      source/backend/CarlaPlugin.hpp
  23. +2
    -35
      source/backend/CarlaStandalone.cpp
  24. +3
    -19
      source/backend/CarlaStandaloneNSM.cpp
  25. +3
    -52
      source/backend/CarlaUtils.h
  26. +0
    -29
      source/backend/Makefile
  27. +0
    -7
      source/backend/Makefile.mk
  28. +21
    -98
      source/backend/engine/CarlaEngine.cpp
  29. +7
    -21
      source/backend/engine/CarlaEngineBridge.cpp
  30. +3
    -31
      source/backend/engine/CarlaEngineJack.cpp
  31. +0
    -1142
      source/backend/engine/CarlaEngineJuce.cpp
  32. +21
    -101
      source/backend/engine/CarlaEngineNative.cpp
  33. +1
    -1
      source/backend/engine/CarlaEngineOsc.hpp
  34. +18
    -7
      source/backend/engine/CarlaEngineOscHandlers.cpp
  35. +6
    -17
      source/backend/engine/CarlaEngineRtAudio.cpp
  36. +0
    -19
      source/backend/engine/Makefile
  37. +5
    -21
      source/backend/plugin/CarlaPlugin.cpp
  38. +1106
    -27
      source/backend/plugin/CarlaPluginAU.cpp
  39. +8
    -8
      source/backend/plugin/CarlaPluginBridge.cpp
  40. +10
    -10
      source/backend/plugin/CarlaPluginJSFX.cpp
  41. +4
    -18
      source/backend/plugin/CarlaPluginJack.cpp
  42. +0
    -1920
      source/backend/plugin/CarlaPluginJuce.cpp
  43. +3
    -3
      source/backend/plugin/CarlaPluginLADSPADSSI.cpp
  44. +6
    -20
      source/backend/plugin/CarlaPluginLV2.cpp
  45. +1
    -1
      source/backend/plugin/CarlaPluginNative.cpp
  46. +2
    -26
      source/backend/plugin/CarlaPluginVST2.cpp
  47. +175
    -57
      source/backend/plugin/CarlaPluginVST3.cpp
  48. +4
    -33
      source/backend/plugin/Makefile
  49. +11
    -103
      source/backend/utils/CachedPlugins.cpp
  50. +4
    -55
      source/backend/utils/Information.cpp
  51. +0
    -47
      source/backend/utils/JUCE.cpp
  52. +3
    -28
      source/backend/utils/Makefile
  53. +105
    -30
      source/backend/utils/PluginDiscovery.cpp
  54. +15
    -22
      source/bridges-plugin/CarlaBridgePlugin.cpp
  55. +1
    -12
      source/bridges-plugin/CarlaBridgeSingleLV2.cpp
  56. +3
    -36
      source/bridges-plugin/Makefile
  57. +1
    -1
      source/carla.kdev4
  58. +0
    -32
      source/discovery/Makefile
  59. +488
    -259
      source/discovery/carla-discovery.cpp
  60. +6
    -19
      source/frontend/CarlaFrontend.h
  61. +29
    -30
      source/frontend/Makefile
  62. +8
    -17
      source/frontend/bigmeter-ui
  63. +4
    -16
      source/frontend/carla
  64. +4
    -16
      source/frontend/carla-control
  65. +4
    -16
      source/frontend/carla-jack-multi
  66. +4
    -16
      source/frontend/carla-jack-single
  67. +4
    -16
      source/frontend/carla-patchbay
  68. +12
    -18
      source/frontend/carla-plugin
  69. +4
    -16
      source/frontend/carla-rack
  70. +18
    -25
      source/frontend/carla_app.py
  71. +8
    -17
      source/frontend/carla_backend_qt.py
  72. +7
    -23
      source/frontend/carla_frontend.py
  73. +76
    -43
      source/frontend/carla_host.py
  74. +8
    -17
      source/frontend/carla_host_control.py
  75. +16
    -20
      source/frontend/carla_settings.py
  76. +33
    -33
      source/frontend/carla_shared.py
  77. +12
    -19
      source/frontend/carla_skin.py
  78. +0
    -25
      source/frontend/carla_utils.py
  79. +35
    -31
      source/frontend/carla_widgets.py
  80. +0
    -1
      source/frontend/dialogs/__init__.py
  81. +0
    -97
      source/frontend/dialogs/aboutjucedialog.cpp
  82. +0
    -55
      source/frontend/dialogs/aboutjucedialog.hpp
  83. +0
    -77
      source/frontend/dialogs/aboutjucedialog.py
  84. +0
    -187
      source/frontend/dialogs/aboutjucedialog.ui
  85. +31
    -28
      source/frontend/midipattern-ui
  86. +10
    -18
      source/frontend/notes-ui
  87. +10
    -18
      source/frontend/patchcanvas/__init__.py
  88. +12
    -19
      source/frontend/patchcanvas/canvasbezierline.py
  89. +12
    -19
      source/frontend/patchcanvas/canvasbezierlinemov.py
  90. +14
    -19
      source/frontend/patchcanvas/canvasbox.py
  91. +10
    -18
      source/frontend/patchcanvas/canvasboxshadow.py
  92. +10
    -18
      source/frontend/patchcanvas/canvasfadeanimation.py
  93. +15
    -20
      source/frontend/patchcanvas/canvasicon.py
  94. +12
    -19
      source/frontend/patchcanvas/canvasline.py
  95. +12
    -19
      source/frontend/patchcanvas/canvaslinemov.py
  96. +26
    -20
      source/frontend/patchcanvas/canvasport.py
  97. +8
    -17
      source/frontend/patchcanvas/canvasportglow.py
  98. +12
    -19
      source/frontend/patchcanvas/patchcanvas.py
  99. +13
    -20
      source/frontend/patchcanvas/scene.py
  100. +10
    -18
      source/frontend/patchcanvas/theme.py

+ 0
- 3
.clang-format View File

@@ -1,3 +0,0 @@
DisableFormat: true
SortIncludes: Never


+ 5
- 5
.github/workflows/build.yml View File

@@ -15,9 +15,9 @@ jobs:
include: include:
- target: debian:11 - target: debian:11
- target: debian:12 - target: debian:12
- target: ubuntu:18.04
- target: ubuntu:20.04 - target: ubuntu:20.04
- target: ubuntu:22.04 - target: ubuntu:22.04
- target: ubuntu:24.04
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: ${{ matrix.target }} image: ${{ matrix.target }}
@@ -43,11 +43,11 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
#- target: macos-11
- target: macos-12 - target: macos-12
- target: macos-13
runs-on: ${{ matrix.target }} runs-on: ${{ matrix.target }}
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up dependencies - name: Set up dependencies
@@ -61,12 +61,12 @@ jobs:
wasm: wasm:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
id: cache id: cache
uses: actions/cache@v3
uses: actions/cache@v4
with: with:
path: | path: |
~/emsdk ~/emsdk


+ 13
- 16
.github/workflows/cmake.yml View File

@@ -12,14 +12,13 @@ jobs:
include: include:
- container: debian:11 - container: debian:11
- container: debian:12 - container: debian:12
#- container: ubuntu:20.04
- container: ubuntu:22.04 - container: ubuntu:22.04
- container: ubuntu:23.10
- container: ubuntu:24.04
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: ${{ matrix.container }} image: ${{ matrix.container }}
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up dependencies - name: Set up dependencies
run: | run: |
apt-get update -qq apt-get update -qq
@@ -31,7 +30,7 @@ jobs:
run: cmake --build build -j $(nproc) run: cmake --build build -j $(nproc)
- name: install - name: install
run: cmake --install build --verbose run: cmake --install build --verbose
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: linux-${{ env.PACK_NAME }} name: linux-${{ env.PACK_NAME }}
path: ${{ env.DESTDIR }} path: ${{ env.DESTDIR }}
@@ -44,7 +43,7 @@ jobs:
- frameworks: OFF - frameworks: OFF
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up dependencies - name: Set up dependencies
run: | run: |
brew install cmake fluid-synth liblo libmagic libsndfile pkg-config brew install cmake fluid-synth liblo libmagic libsndfile pkg-config
@@ -59,9 +58,9 @@ jobs:
run: cmake --build build -j $(sysctl -n hw.logicalcpu) run: cmake --build build -j $(sysctl -n hw.logicalcpu)
- name: install - name: install
run: cmake --install build --verbose run: cmake --install build --verbose
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: macos-${{ env.PACK_NAME }}
name: macos-${{ env.PACK_NAME }}-${{ matrix.frameworks }}
path: ${{ env.DESTDIR }} path: ${{ env.DESTDIR }}


mingw32-cross: mingw32-cross:
@@ -70,14 +69,13 @@ jobs:
include: include:
- container: debian:11 - container: debian:11
- container: debian:12 - container: debian:12
#- container: ubuntu:20.04
- container: ubuntu:22.04 - container: ubuntu:22.04
- container: ubuntu:23.10
- container: ubuntu:24.04
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: ${{ matrix.container }} image: ${{ matrix.container }}
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up dependencies - name: Set up dependencies
run: | run: |
dpkg --add-architecture i386 dpkg --add-architecture i386
@@ -97,7 +95,7 @@ jobs:
run: cmake --build build -j $(nproc) run: cmake --build build -j $(nproc)
- name: install - name: install
run: cmake --install build --verbose run: cmake --install build --verbose
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: mingw32-${{ env.PACK_NAME }} name: mingw32-${{ env.PACK_NAME }}
path: ${{ env.DESTDIR }} path: ${{ env.DESTDIR }}
@@ -108,14 +106,13 @@ jobs:
include: include:
- container: debian:11 - container: debian:11
- container: debian:12 - container: debian:12
#- container: ubuntu:20.04
- container: ubuntu:22.04 - container: ubuntu:22.04
- container: ubuntu:23.10
- container: ubuntu:24.04
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: ${{ matrix.container }} image: ${{ matrix.container }}
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up dependencies - name: Set up dependencies
run: | run: |
dpkg --add-architecture i386 dpkg --add-architecture i386
@@ -135,7 +132,7 @@ jobs:
run: cmake --build build -j $(nproc) run: cmake --build build -j $(nproc)
- name: install - name: install
run: cmake --install build --verbose run: cmake --install build --verbose
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: mingw64-${{ env.PACK_NAME }} name: mingw64-${{ env.PACK_NAME }}
path: ${{ env.DESTDIR }} path: ${{ env.DESTDIR }}
@@ -143,7 +140,7 @@ jobs:
windows: windows:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: configure - name: configure
run: cmake -S cmake -B build run: cmake -S cmake -B build
- name: build - name: build


+ 8
- 8
.github/workflows/dpf.yml View File

@@ -13,9 +13,9 @@ jobs:
target: [linux-x86_64] target: [linux-x86_64]
# TODO: add PawPaw bootstrap type # TODO: add PawPaw bootstrap type
# linux-arm64, linux-armhf, linux-i686, linux-riscv64, # linux-arm64, linux-armhf, linux-i686, linux-riscv64,
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: distrho/dpf-makefile-action@v1 - uses: distrho/dpf-makefile-action@v1
@@ -28,9 +28,9 @@ jobs:
strategy: strategy:
matrix: matrix:
target: [macos-intel, macos-universal, macos-universal-10.15] target: [macos-intel, macos-universal, macos-universal-10.15]
runs-on: macos-11
runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: fake dpf script - name: fake dpf script
@@ -50,7 +50,7 @@ jobs:
target: [win32, win64] target: [win32, win64]
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: distrho/dpf-makefile-action@v1 - uses: distrho/dpf-makefile-action@v1
@@ -66,7 +66,7 @@ jobs:
#pluginval: #pluginval:
#runs-on: ubuntu-20.04 #runs-on: ubuntu-20.04
#steps: #steps:
#- uses: actions/checkout@v3
#- uses: actions/checkout@v4
#with: #with:
#submodules: recursive #submodules: recursive
#- uses: distrho/dpf-makefile-action@v1 #- uses: distrho/dpf-makefile-action@v1
@@ -75,9 +75,9 @@ jobs:
#pawpaw: true #pawpaw: true


source: source:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- uses: distrho/dpf-makefile-action@v1 - uses: distrho/dpf-makefile-action@v1


+ 10
- 10
.github/workflows/release.yml View File

@@ -14,13 +14,13 @@ env:
jobs: jobs:
# macOS native universal build # macOS native universal build
macos_universal: macos_universal:
runs-on: macos-11
runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3
uses: actions/cache@v4
with: with:
path: | path: |
~/PawPawBuilds ~/PawPawBuilds
@@ -46,7 +46,7 @@ jobs:
make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1
make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1
make dist ${MAKE_ARGS} -j 1 make dist ${MAKE_ARGS} -j 1
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: macOS dmg name: macOS dmg
path: ./*.dmg path: ./*.dmg
@@ -64,11 +64,11 @@ jobs:
win32: win32:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3
uses: actions/cache@v4
with: with:
path: | path: |
~/PawPawBuilds ~/PawPawBuilds
@@ -110,7 +110,7 @@ jobs:
make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1
make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1
make dist ${MAKE_ARGS} -j 1 make dist ${MAKE_ARGS} -j 1
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: win32 zip name: win32 zip
path: ./*.zip path: ./*.zip
@@ -128,11 +128,11 @@ jobs:
win64: win64:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: with:
submodules: recursive submodules: recursive
- name: Set up cache - name: Set up cache
uses: actions/cache@v3
uses: actions/cache@v4
with: with:
path: | path: |
~/PawPawBuilds ~/PawPawBuilds
@@ -175,7 +175,7 @@ jobs:
make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1
make dist ${MAKE_ARGS} TESTING=true -j 1 make dist ${MAKE_ARGS} TESTING=true -j 1
make dist ${MAKE_ARGS} -j 1 make dist ${MAKE_ARGS} -j 1
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with: with:
name: win64 zip name: win64 zip
path: ./*.zip path: ./*.zip


+ 1
- 0
.gitignore View File

@@ -60,6 +60,7 @@ qrc_resources.cpp
*.pyc *.pyc


# Qt files # Qt files
qt_config.py
*_ui.hpp *_ui.hpp
*_ui.py *_ui.py
*_rc.cpp *_rc.cpp


+ 4
- 10
INSTALL.md View File

@@ -38,20 +38,14 @@ Optional for extra Linux-only engine features:


- ALSA - ALSA
- PulseAudio - PulseAudio
- X11 (LV2/VST X11 UI support)
- X11 (CLAP/LV2/VST2/VST3 X11 UI support)


Optional for extended LV2 UIs support: (Linux only) Optional for extended LV2 UIs support: (Linux only)


- Gtk2
- Gtk3
- Qt4 - Qt4
- Qt5 - Qt5


Optional for Linux VST3 support:

- freetype2
- Xcursor
- Xext
NOTE: Gtk2 and Gtk3 support is always on, as Carla uses dlopen + dlsym to support them


Optional for extra samplers support: Optional for extra samplers support:


@@ -73,14 +67,14 @@ Under Debian based systems, you can use this command to install everything:
``` ```
sudo apt install python3-pyqt5.qtsvg python3-rdflib pyqt5-dev-tools \ sudo apt install python3-pyqt5.qtsvg python3-rdflib pyqt5-dev-tools \
libmagic-dev liblo-dev libasound2-dev libpulse-dev libx11-dev libxcursor-dev libxext-dev \ libmagic-dev liblo-dev libasound2-dev libpulse-dev libx11-dev libxcursor-dev libxext-dev \
libgtk2.0-dev libgtk-3-dev libqt4-dev qtbase5-dev libfluidsynth-dev
qtbase5-dev libfluidsynth-dev
``` ```


Under Fedora, you can use the following command instead: Under Fedora, you can use the following command instead:
``` ```
sudo dnf install python3-qt5-devel python3-rdflib \ sudo dnf install python3-qt5-devel python3-rdflib \
file-devel liblo-devel alsa-lib-devel pulseaudio-libs-devel libX11-devel file-devel liblo-devel alsa-lib-devel pulseaudio-libs-devel libX11-devel
gtk2-devel gtk3-devel qt4-devel qt5-devel fluidsynth-devel libsndfile-devel
qt5-devel fluidsynth-devel libsndfile-devel
``` ```


## BUILD BRIDGES (Experimental) ## BUILD BRIDGES (Experimental)


+ 13
- 15
Makefile View File

@@ -78,23 +78,12 @@ ifeq ($(HAVE_QT5),true)
3RD_LIBS += $(MODULEDIR)/theme.qt5.a 3RD_LIBS += $(MODULEDIR)/theme.qt5.a
endif endif


ifeq ($(HAVE_YSFX),true)
3RD_LIBS += $(MODULEDIR)/ysfx.a
ifeq ($(HAVE_QT6),true)
3RD_LIBS += $(MODULEDIR)/theme.qt6.a
endif endif


ifeq ($(USING_JUCE),true)
3RD_LIBS += $(MODULEDIR)/carla_juce.a
3RD_LIBS += $(MODULEDIR)/juce_audio_basics.a
ifeq ($(USING_JUCE_AUDIO_DEVICES),true)
3RD_LIBS += $(MODULEDIR)/juce_audio_devices.a
endif
3RD_LIBS += $(MODULEDIR)/juce_audio_processors.a
3RD_LIBS += $(MODULEDIR)/juce_core.a
3RD_LIBS += $(MODULEDIR)/juce_data_structures.a
3RD_LIBS += $(MODULEDIR)/juce_events.a
3RD_LIBS += $(MODULEDIR)/juce_graphics.a
3RD_LIBS += $(MODULEDIR)/juce_gui_basics.a
3RD_LIBS += $(MODULEDIR)/juce_gui_extra.a
ifeq ($(HAVE_YSFX),true)
3RD_LIBS += $(MODULEDIR)/ysfx.a
endif endif


ifeq ($(USING_RTAUDIO),true) ifeq ($(USING_RTAUDIO),true)
@@ -136,6 +125,9 @@ $(MODULEDIR)/theme.qt4.a: .FORCE
$(MODULEDIR)/theme.qt5.a: .FORCE $(MODULEDIR)/theme.qt5.a: .FORCE
@$(MAKE) -C source/theme qt5 @$(MAKE) -C source/theme qt5


$(MODULEDIR)/theme.qt6.a: .FORCE
@$(MAKE) -C source/theme qt6

$(MODULEDIR)/%.arm32.a: .FORCE $(MODULEDIR)/%.arm32.a: .FORCE
ifneq ($(WINDOWS),true) ifneq ($(WINDOWS),true)
@$(MAKE) -C source/modules/$* arm32 @$(MAKE) -C source/modules/$* arm32
@@ -340,6 +332,10 @@ else
$(MAKE) -C source/discovery win64 $(MAKE) -C source/discovery win64
endif endif


mingw64:
$(MAKE) AR=i686-w64-mingw32-ar CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ win32
$(MAKE) AR=x86_64-w64-mingw32-ar CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ win64

# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Binaries (wine) # Binaries (wine)


@@ -711,6 +707,8 @@ endif
$(LINK) ../carla_utils.py $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../carla_utils.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../carla_widgets.py $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../carla_widgets.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../externalui.py $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../externalui.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../qt_compat.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../qt_config.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../resources_rc.py $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../resources_rc.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../ui_carla_about.py $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../ui_carla_about.py $(DESTDIR)$(DATADIR)/carla/resources
$(LINK) ../ui_carla_edit.py $(DESTDIR)$(DATADIR)/carla/resources $(LINK) ../ui_carla_edit.py $(DESTDIR)$(DATADIR)/carla/resources


+ 11
- 36
Makefile.print.mk View File

@@ -27,7 +27,7 @@ endif
features_print_main: features_print_main:
@printf -- "$(tS)---> Main features $(tE)\n" @printf -- "$(tS)---> Main features $(tE)\n"
ifeq ($(HAVE_FRONTEND),true) ifeq ($(HAVE_FRONTEND),true)
@printf -- "Front-End: $(ANS_YES)\n"
@printf -- "Front-End: $(ANS_YES) (Qt$(FRONTEND_TYPE))\n"
@printf -- "LV2 plugin: $(ANS_YES)\n" @printf -- "LV2 plugin: $(ANS_YES)\n"
ifneq ($(HAIKU),true) ifneq ($(HAIKU),true)
@printf -- "VST2 plugin: $(ANS_YES)\n" @printf -- "VST2 plugin: $(ANS_YES)\n"
@@ -41,13 +41,9 @@ else
endif endif
ifeq ($(HAVE_HYLIA),true) ifeq ($(HAVE_HYLIA),true)
@printf -- "Link support: $(ANS_YES)\n" @printf -- "Link support: $(ANS_YES)\n"
else
ifeq ($(MACOS_OLD),true)
@printf -- "Link support: $(ANS_NO) $(mZ)MacOS >= 10.8 only$(mE)\n"
else else
@printf -- "Link support: $(ANS_NO) $(mZ)Linux, MacOS and Windows only$(mE)\n" @printf -- "Link support: $(ANS_NO) $(mZ)Linux, MacOS and Windows only$(mE)\n"
endif endif
endif
ifeq ($(HAVE_LIBLO),true) ifeq ($(HAVE_LIBLO),true)
@printf -- "OSC support: $(ANS_YES)\n" @printf -- "OSC support: $(ANS_YES)\n"
else else
@@ -55,12 +51,10 @@ else
endif endif
ifeq ($(WINDOWS),true) ifeq ($(WINDOWS),true)
@printf -- "Binary detect: $(ANS_YES)\n" @printf -- "Binary detect: $(ANS_YES)\n"
else
ifeq ($(HAVE_LIBMAGIC),true)
else ifeq ($(HAVE_LIBMAGIC),true)
@printf -- "Binary detect: $(ANS_YES)\n" @printf -- "Binary detect: $(ANS_YES)\n"
else else
@printf -- "Binary detect: $(ANS_NO) $(mS)Missing libmagic/file$(mE)\n" @printf -- "Binary detect: $(ANS_NO) $(mS)Missing libmagic/file$(mE)\n"
endif
endif endif
@printf -- "\n" @printf -- "\n"


@@ -94,11 +88,9 @@ else
@printf -- "CoreAudio: $(ANS_NO) $(mZ)MacOS only$(mE)\n" @printf -- "CoreAudio: $(ANS_NO) $(mZ)MacOS only$(mE)\n"
endif endif
ifeq ($(WINDOWS),true) ifeq ($(WINDOWS),true)
@printf -- "ASIO: $(ANS_YES)\n"
@printf -- "DirectSound: $(ANS_YES)\n" @printf -- "DirectSound: $(ANS_YES)\n"
@printf -- "WASAPI: $(ANS_YES)\n" @printf -- "WASAPI: $(ANS_YES)\n"
else else
@printf -- "ASIO: $(ANS_NO) $(mZ)Windows only$(mE)\n"
@printf -- "DirectSound: $(ANS_NO) $(mZ)Windows only$(mE)\n" @printf -- "DirectSound: $(ANS_NO) $(mZ)Windows only$(mE)\n"
@printf -- "WASAPI: $(ANS_NO) $(mZ)Windows only$(mE)\n" @printf -- "WASAPI: $(ANS_NO) $(mZ)Windows only$(mE)\n"
endif endif
@@ -116,37 +108,20 @@ endif
@printf -- "LV2: $(ANS_YES)\n" @printf -- "LV2: $(ANS_YES)\n"
@printf -- "CLAP: $(ANS_YES)\n" @printf -- "CLAP: $(ANS_YES)\n"
ifeq ($(MACOS_OR_WINDOWS),true) ifeq ($(MACOS_OR_WINDOWS),true)
ifeq ($(USING_JUCE),true)
@printf -- "VST2: $(ANS_YES) (with UI, using JUCE)\n"
@printf -- "VST3: $(ANS_YES) (with UI, using JUCE)\n"
else # USING_JUCE
@printf -- "VST2: $(ANS_YES) (with UI)\n" @printf -- "VST2: $(ANS_YES) (with UI)\n"
@printf -- "VST3: $(ANS_NO)\n"
endif # USING_JUCE
else # MACOS_OR_WINDOWS
ifeq ($(HAIKU),true)
@printf -- "VST3: $(ANS_YES) (with UI)\n"
else ifeq ($(HAIKU),true)
@printf -- "VST2: $(ANS_YES) (without UI)\n" @printf -- "VST2: $(ANS_YES) (without UI)\n"
@printf -- "VST3: $(ANS_NO)\n"
else # HAIKU
ifeq ($(HAVE_X11),true)
@printf -- "VST3: $(ANS_YES) (without UI)\n"
else ifeq ($(HAVE_X11),true)
@printf -- "VST2: $(ANS_YES) (with UI)\n" @printf -- "VST2: $(ANS_YES) (with UI)\n"
ifeq ($(USING_JUCE),true)
@printf -- "VST3: $(ANS_YES) (with UI, using JUCE)\n"
else # USING_JUCE
@printf -- "VST3: $(ANS_NO)\n"
endif # USING_JUCE
else # HAVE_X11
@printf -- "VST3: $(ANS_YES) (with UI)\n"
else
@printf -- "VST2: $(ANS_YES) (without UI) $(mS)Missing X11$(mE)\n" @printf -- "VST2: $(ANS_YES) (without UI) $(mS)Missing X11$(mE)\n"
@printf -- "VST3: $(ANS_NO)\n"
endif # HAVE_X11
endif # HAIKU
endif # MACOS_OR_WINDOWS
@printf -- "VST3: $(ANS_YES) (without UI) $(mS)Missing X11$(mE)\n"
endif
ifeq ($(MACOS),true) ifeq ($(MACOS),true)
ifeq ($(USING_JUCE),true)
@printf -- "AU: $(ANS_YES) (with UI, using JUCE)\n"
else # USING_JUCE
@printf -- "AU: $(ANS_NO)\n"
endif # USING_JUCE
@printf -- "AU: $(ANS_YES) (with UI)\n"
else # MACOS else # MACOS
@printf -- "AU: $(ANS_NO) $(mZ)MacOS only$(mE)\n" @printf -- "AU: $(ANS_NO) $(mZ)MacOS only$(mE)\n"
endif # MACOS endif # MACOS


+ 1
- 1
README.md View File

@@ -14,7 +14,7 @@ Features
* SF2/3 and SFZ sound banks * SF2/3 and SFZ sound banks
* Internal audio and midi file player * Internal audio and midi file player
* Automation of plugin parameters via MIDI CC * Automation of plugin parameters via MIDI CC
* Remote control over OSC
* Remote control over [OSC](https://opensoundcontrol.stanford.edu/)
* Rack and Patchbay processing modes, plus Single and Multi-Client if using JACK * Rack and Patchbay processing modes, plus Single and Multi-Client if using JACK
* Native audio drivers (ALSA, DirectSound, CoreAudio, etc) and JACK * Native audio drivers (ALSA, DirectSound, CoreAudio, etc) and JACK




+ 2
- 7
cmake/CMakeLists.txt View File

@@ -790,7 +790,6 @@ target_sources(carla-bridge-native
../source/backend/plugin/CarlaPluginAU.cpp ../source/backend/plugin/CarlaPluginAU.cpp
../source/backend/plugin/CarlaPluginCLAP.cpp ../source/backend/plugin/CarlaPluginCLAP.cpp
../source/backend/plugin/CarlaPluginFluidSynth.cpp ../source/backend/plugin/CarlaPluginFluidSynth.cpp
../source/backend/plugin/CarlaPluginJuce.cpp
../source/backend/plugin/CarlaPluginJSFX.cpp ../source/backend/plugin/CarlaPluginJSFX.cpp
../source/backend/plugin/CarlaPluginLADSPADSSI.cpp ../source/backend/plugin/CarlaPluginLADSPADSSI.cpp
../source/backend/plugin/CarlaPluginLV2.cpp ../source/backend/plugin/CarlaPluginLV2.cpp
@@ -1021,7 +1020,6 @@ target_sources(carla-host-plugin
../source/backend/plugin/CarlaPluginAU.cpp ../source/backend/plugin/CarlaPluginAU.cpp
../source/backend/plugin/CarlaPluginCLAP.cpp ../source/backend/plugin/CarlaPluginCLAP.cpp
../source/backend/plugin/CarlaPluginFluidSynth.cpp ../source/backend/plugin/CarlaPluginFluidSynth.cpp
../source/backend/plugin/CarlaPluginJuce.cpp
../source/backend/plugin/CarlaPluginJSFX.cpp ../source/backend/plugin/CarlaPluginJSFX.cpp
../source/backend/plugin/CarlaPluginLADSPADSSI.cpp ../source/backend/plugin/CarlaPluginLADSPADSSI.cpp
../source/backend/plugin/CarlaPluginLV2.cpp ../source/backend/plugin/CarlaPluginLV2.cpp
@@ -1122,7 +1120,6 @@ if(APPLE)
-Wl,-exported_symbol,_carla_host_handle_free -Wl,-exported_symbol,_carla_host_handle_free
-Wl,-exported_symbol,_carla_get_native_plugin_engine -Wl,-exported_symbol,_carla_get_native_plugin_engine
-Wl,-exported_symbol,_carla_get_complete_license_text -Wl,-exported_symbol,_carla_get_complete_license_text
-Wl,-exported_symbol,_carla_get_juce_version
-Wl,-exported_symbol,_carla_get_supported_file_extensions -Wl,-exported_symbol,_carla_get_supported_file_extensions
-Wl,-exported_symbol,_carla_get_supported_features -Wl,-exported_symbol,_carla_get_supported_features
-Wl,-exported_symbol,_carla_get_library_filename -Wl,-exported_symbol,_carla_get_library_filename
@@ -1132,7 +1129,7 @@ elseif(EMSCRIPTEN)
target_link_options(carla-native-plugin target_link_options(carla-native-plugin
PRIVATE PRIVATE
-sSIDE_MODULE=2 -sSIDE_MODULE=2
-sEXPORTED_FUNCTIONS="['carla_get_native_rack_plugin','carla_get_native_patchbay_plugin','carla_get_native_patchbay16_plugin','carla_get_native_patchbay32_plugin','carla_get_native_patchbay64_plugin','carla_get_native_patchbay_cv_plugin','carla_get_native_patchbay_cv8_plugin','carla_get_native_patchbay_cv32_plugin','carla_get_native_patchbay_obs_plugin','carla_create_native_plugin_host_handle','carla_host_handle_free','carla_get_native_plugin_engine','carla_get_complete_license_text','carla_get_juce_version','carla_get_supported_file_extensions','carla_get_supported_features','carla_get_library_filename','carla_get_library_folder']"
-sEXPORTED_FUNCTIONS="['carla_get_native_rack_plugin','carla_get_native_patchbay_plugin','carla_get_native_patchbay16_plugin','carla_get_native_patchbay32_plugin','carla_get_native_patchbay64_plugin','carla_get_native_patchbay_cv_plugin','carla_get_native_patchbay_cv8_plugin','carla_get_native_patchbay_cv32_plugin','carla_get_native_patchbay_obs_plugin','carla_create_native_plugin_host_handle','carla_host_handle_free','carla_get_native_plugin_engine','carla_get_complete_license_text','carla_get_supported_file_extensions','carla_get_supported_features','carla_get_library_filename','carla_get_library_folder']"
) )
elseif(MSVC) elseif(MSVC)
target_link_options(carla-native-plugin target_link_options(carla-native-plugin
@@ -1189,7 +1186,6 @@ target_sources(carla-native-plugin
../source/backend/plugin/CarlaPluginAU.cpp ../source/backend/plugin/CarlaPluginAU.cpp
../source/backend/plugin/CarlaPluginCLAP.cpp ../source/backend/plugin/CarlaPluginCLAP.cpp
../source/backend/plugin/CarlaPluginFluidSynth.cpp ../source/backend/plugin/CarlaPluginFluidSynth.cpp
../source/backend/plugin/CarlaPluginJuce.cpp
../source/backend/plugin/CarlaPluginJSFX.cpp ../source/backend/plugin/CarlaPluginJSFX.cpp
../source/backend/plugin/CarlaPluginLADSPADSSI.cpp ../source/backend/plugin/CarlaPluginLADSPADSSI.cpp
../source/backend/plugin/CarlaPluginLV2.cpp ../source/backend/plugin/CarlaPluginLV2.cpp
@@ -1321,7 +1317,6 @@ target_sources(carla-standalone
../source/backend/plugin/CarlaPluginAU.cpp ../source/backend/plugin/CarlaPluginAU.cpp
../source/backend/plugin/CarlaPluginCLAP.cpp ../source/backend/plugin/CarlaPluginCLAP.cpp
../source/backend/plugin/CarlaPluginFluidSynth.cpp ../source/backend/plugin/CarlaPluginFluidSynth.cpp
../source/backend/plugin/CarlaPluginJuce.cpp
../source/backend/plugin/CarlaPluginJSFX.cpp ../source/backend/plugin/CarlaPluginJSFX.cpp
../source/backend/plugin/CarlaPluginLADSPADSSI.cpp ../source/backend/plugin/CarlaPluginLADSPADSSI.cpp
../source/backend/plugin/CarlaPluginLV2.cpp ../source/backend/plugin/CarlaPluginLV2.cpp
@@ -1440,7 +1435,6 @@ target_sources(carla-utils
../source/backend/utils/CachedPlugins.cpp ../source/backend/utils/CachedPlugins.cpp
../source/backend/utils/CarlaUtils.cpp ../source/backend/utils/CarlaUtils.cpp
../source/backend/utils/Information.cpp ../source/backend/utils/Information.cpp
../source/backend/utils/JUCE.cpp
../source/backend/utils/PipeClient.cpp ../source/backend/utils/PipeClient.cpp
../source/backend/utils/PluginDiscovery.cpp ../source/backend/utils/PluginDiscovery.cpp
../source/backend/utils/System.cpp ../source/backend/utils/System.cpp
@@ -1516,6 +1510,7 @@ if(APPLE)
set_source_files_properties( set_source_files_properties(
../source/backend/CarlaStandalone.cpp ../source/backend/CarlaStandalone.cpp
../source/backend/engine/CarlaEngineNative.cpp ../source/backend/engine/CarlaEngineNative.cpp
../source/backend/plugin/CarlaPluginAU.cpp
../source/backend/plugin/CarlaPluginCLAP.cpp ../source/backend/plugin/CarlaPluginCLAP.cpp
../source/backend/plugin/CarlaPluginVST2.cpp ../source/backend/plugin/CarlaPluginVST2.cpp
../source/backend/plugin/CarlaPluginVST3.cpp ../source/backend/plugin/CarlaPluginVST3.cpp


+ 6
- 0
data/docker/.dockerignore View File

@@ -0,0 +1,6 @@
# binary files
*.dll
*.so

# this script
build.sh

+ 46
- 0
data/docker/Dockerfile View File

@@ -0,0 +1,46 @@
FROM ubuntu:20.04
LABEL maintainer="falkTX <falktx@falktx.com>"
ENV DEBIAN_FRONTEND noninteractive

# enable i386
RUN dpkg --add-architecture i386

# update system
RUN apt-get update -qq && apt-get upgrade -qqy && apt-get clean

# install packages needed for build
RUN apt-get install -qqy --no-install-recommends ca-certificates g++-multilib git libgl-dev make openssl pkg-config wget && \
apt-get clean

# install newer wine
RUN mkdir -pm755 /etc/apt/keyrings && \
wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key && \
wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/focal/winehq-focal.sources

RUN apt-get update -qq && \
apt-get install -qqy --no-install-recommends winehq-stable wine-stable-dev && \
apt-get clean

# fetch Carla
RUN git clone --recursive https://github.com/falkTX/Carla.git --depth=1 # v4
WORKDIR /Carla

# build plugin-wine 32bit
RUN apt-get install -yqq --no-install-recommends libx11-dev:i386 && apt-get clean
RUN CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 make plugin plugin-wine
RUN mkdir bin32
RUN mv bin/CarlaVst*ShellBridged.dll* bin32
RUN make distclean

# build plugin-wine 64bit
RUN apt-get install -yqq --no-install-recommends libx11-dev:amd64 && apt-get clean
RUN CFLAGS=-m64 CXXFLAGS=-m64 LDFLAGS=-m64 make plugin plugin-wine
RUN mkdir bin64
RUN mv bin/CarlaVst*ShellBridged.dll* bin64
RUN make distclean

# build Carla wine bridges
RUN make wine32 wine64

# CMD for inspection
CMD ["bash"]

+ 25
- 0
data/docker/build.sh View File

@@ -0,0 +1,25 @@
#!/bin/bash

cd $(dirname $0)

rm -rf bin32 bin64 *.dll

set -e

mkdir bin32 bin64
docker build -t carla-bridge-win .
docker run -v $PWD:/mnt --rm --entrypoint \
cp carla-bridge-win:latest \
/Carla/bin32/CarlaVstShellBridged.dll.so \
/Carla/bin32/CarlaVstFxShellBridged.dll.so \
/mnt/bin32
docker run -v $PWD:/mnt --rm --entrypoint \
cp carla-bridge-win:latest \
/Carla/bin64/CarlaVstShellBridged.dll.so \
/Carla/bin64/CarlaVstFxShellBridged.dll.so \
/mnt/bin64
docker run -v $PWD:/mnt --rm --entrypoint \
cp carla-bridge-win:latest \
/Carla/bin/jackbridge-wine32.dll \
/Carla/bin/jackbridge-wine64.dll \
/mnt

+ 0
- 9
resources/ui/carla_host.ui View File

@@ -574,7 +574,6 @@
<string>&amp;Help</string> <string>&amp;Help</string>
</property> </property>
<addaction name="act_help_about"/> <addaction name="act_help_about"/>
<addaction name="act_help_about_juce"/>
<addaction name="act_help_about_qt"/> <addaction name="act_help_about_qt"/>
</widget> </widget>
<addaction name="menu_File"/> <addaction name="menu_File"/>
@@ -1471,14 +1470,6 @@
<enum>QAction::NoRole</enum> <enum>QAction::NoRole</enum>
</property> </property>
</action> </action>
<action name="act_help_about_juce">
<property name="text">
<string>About &amp;JUCE</string>
</property>
<property name="menuRole">
<enum>QAction::NoRole</enum>
</property>
</action>
<action name="act_help_about_qt"> <action name="act_help_about_qt">
<property name="text"> <property name="text">
<string>About &amp;Qt</string> <string>About &amp;Qt</string>


+ 1
- 1
resources/ui/carla_settings.ui View File

@@ -1008,7 +1008,7 @@
<string>Maximum number of parameters to allow in the built-in 'Edit' dialog</string> <string>Maximum number of parameters to allow in the built-in 'Edit' dialog</string>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>1000</number>
<number>2000</number>
</property> </property>
</widget> </widget>
</item> </item>


+ 96
- 75
source/Makefile.deps.mk View File

@@ -214,6 +214,9 @@ HAVE_QT4 = $(shell $(PKG_CONFIG) --exists QtCore QtGui && echo true)
HAVE_QT5 = $(shell $(PKG_CONFIG) --exists Qt5Core Qt5Gui Qt5Widgets && \ HAVE_QT5 = $(shell $(PKG_CONFIG) --exists Qt5Core Qt5Gui Qt5Widgets && \
$(PKG_CONFIG) --variable=qt_config Qt5Core | grep -q -v "static" && echo true) $(PKG_CONFIG) --variable=qt_config Qt5Core | grep -q -v "static" && echo true)
HAVE_QT5PKG = $(shell $(PKG_CONFIG) --silence-errors --variable=prefix Qt5OpenGLExtensions 1>/dev/null && echo true) HAVE_QT5PKG = $(shell $(PKG_CONFIG) --silence-errors --variable=prefix Qt5OpenGLExtensions 1>/dev/null && echo true)
HAVE_QT5BREW = $(shell test -e /usr/local/opt/qt5/bin/uic && echo true)
HAVE_QT6 = $(shell $(PKG_CONFIG) --exists Qt6Core Qt6Gui Qt6Widgets && echo true)
HAVE_QT6BREW = $(shell test -e /opt/homebrew/opt/qt6/share/qt/libexec/uic && echo true)
HAVE_SNDFILE = $(shell $(PKG_CONFIG) --exists sndfile && echo true) HAVE_SNDFILE = $(shell $(PKG_CONFIG) --exists sndfile && echo true)


ifeq ($(HAVE_FLUIDSYNTH),true) ifeq ($(HAVE_FLUIDSYNTH),true)
@@ -259,29 +262,65 @@ endif
endif endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Set Qt tools
# Set Qt tools, part1


ifeq ($(HAVE_QT4),true) ifeq ($(HAVE_QT4),true)
MOC_QT4 ?= $(shell $(PKG_CONFIG) --variable=moc_location QtCore) MOC_QT4 ?= $(shell $(PKG_CONFIG) --variable=moc_location QtCore)
RCC_QT4 ?= $(shell $(PKG_CONFIG) --variable=rcc_location QtCore) RCC_QT4 ?= $(shell $(PKG_CONFIG) --variable=rcc_location QtCore)
ifeq (,$(wildcard $(MOC_QT4)))
HAVE_QT4 = false
endif
ifeq (,$(wildcard $(RCC_QT4)))
HAVE_QT4 = false
endif
QT4_CXX_FLAGS = $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags QtCore QtGui)
QT4_LINK_FLAGS = $(NON_STATIC_LINK_FLAGS) $(shell pkg-config --libs QtCore QtGui)
QT4_STYLES_DIR = $(shell pkg-config --variable=libdir QtCore)/qt4/plugins/styles
endif endif


ifeq ($(HAVE_QT5),true) ifeq ($(HAVE_QT5),true)
QT5_HOSTBINS = $(shell $(PKG_CONFIG) --variable=host_bins Qt5Core)
QT5_HOSTBINS = $(shell $(PKG_CONFIG) --variable=host_bins Qt5Core)
QT5_PREFIX = $(shell $(PKG_CONFIG) --variable=prefix Qt5Core)
QT5_CXX_FLAGS = $(shell $(PKG_CONFIG) --cflags Qt5Core Qt5Gui Qt5Widgets)
QT5_LINK_FLAGS = -Wl,-rpath,$(QT5_PREFIX)/lib $(shell $(PKG_CONFIG) --libs Qt5Core Qt5Gui Qt5Widgets)
QT5_STYLES_DIR = $(shell pkg-config --variable=libdir Qt5Core)/qt5/plugins/styles
else ifeq ($(HAVE_QT5PKG),true) else ifeq ($(HAVE_QT5PKG),true)
QT5_HOSTBINS = $(shell $(PKG_CONFIG) --variable=prefix Qt5OpenGLExtensions)/bin
QT5_HOSTBINS = $(shell $(PKG_CONFIG) --variable=prefix Qt5OpenGLExtensions)/bin
QT5_PREFIX = $(shell $(PKG_CONFIG) --variable=prefix Qt5OpenGLExtensions)
QT5_CXX_FLAGS = -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -I $(QT5_PREFIX)/include/qt5
QT5_LINK_FLAGS = -Wl,-rpath,$(QT5_PREFIX)/lib -F $(QT5_PREFIX)/lib -framework QtCore -framework QtGui -framework QtWidgets
QT5_STYLES_DIR = $(QT5_PREFIX)/lib/qt5/plugins/styles
else ifeq ($(HAVE_QT5BREW),true)
QT5_HOSTBINS = /usr/local/opt/qt5/bin
QT5_PREFIX = /usr/local/opt/qt5
QT5_CXX_FLAGS = -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -I $(QT5_PREFIX)/include
QT5_LINK_FLAGS = -Wl,-rpath,$(QT5_PREFIX)/lib -F $(QT5_PREFIX)/lib -framework QtCore -framework QtGui -framework QtWidgets
QT5_STYLES_DIR = $(QT5_PREFIX)/plugins/styles
endif

ifeq ($(HAVE_QT6),true)
QT6_HOSTBINS = $(shell $(PKG_CONFIG) --variable=libexecdir Qt6Core)
QT6_PREFIX = $(shell $(PKG_CONFIG) --variable=prefix Qt6Core)
QT6_CXX_FLAGS = $(shell $(PKG_CONFIG) --cflags Qt6Core Qt6Gui Qt6Widgets) -std=gnu++17
QT6_LINK_FLAGS = -Wl,-rpath,$(QT6_PREFIX)/lib $(shell $(PKG_CONFIG) --libs Qt6Core Qt6Gui Qt6Widgets)
QT6_STYLES_DIR = $(shell pkg-config --variable=libdir Qt6Core)/qt6/plugins/styles
else ifeq ($(HAVE_QT6BREW),true)
QT6_HOSTBINS = /opt/homebrew/opt/qt6/share/qt/libexec
QT6_PREFIX = /opt/homebrew/opt/qt6
QT6_CXX_FLAGS = -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -I $(QT6_PREFIX)/include -std=gnu++17
QT6_LINK_FLAGS = -Wl,-rpath,$(QT6_PREFIX)/lib -F $(QT6_PREFIX)/lib -framework QtCore -framework QtGui -framework QtWidgets
QT6_STYLES_DIR = $(QT6_PREFIX)/share/qt/plugins/styles
endif endif


MOC_QT5 ?= $(QT5_HOSTBINS)/moc MOC_QT5 ?= $(QT5_HOSTBINS)/moc
RCC_QT5 ?= $(QT5_HOSTBINS)/rcc RCC_QT5 ?= $(QT5_HOSTBINS)/rcc
UIC_QT5 ?= $(QT5_HOSTBINS)/uic UIC_QT5 ?= $(QT5_HOSTBINS)/uic


MOC_QT6 ?= $(QT6_HOSTBINS)/moc
RCC_QT6 ?= $(QT6_HOSTBINS)/rcc
UIC_QT6 ?= $(QT6_HOSTBINS)/uic

ifeq (,$(wildcard $(MOC_QT4)))
HAVE_QT4 = false
endif
ifeq (,$(wildcard $(RCC_QT4)))
HAVE_QT4 = false
endif

ifeq (,$(wildcard $(MOC_QT5))) ifeq (,$(wildcard $(MOC_QT5)))
HAVE_QT5 = false HAVE_QT5 = false
endif endif
@@ -292,17 +331,14 @@ ifeq (,$(wildcard $(UIC_QT5)))
HAVE_QT5 = false HAVE_QT5 = false
endif endif


ifeq ($(HAVE_QT4),true)
HAVE_QT = true
else ifeq ($(HAVE_QT5),true)
HAVE_QT = true
# FIXME
else ifeq ($(WINDOWS),true)
HAVE_QT = true
ifeq (,$(wildcard $(MOC_QT6)))
HAVE_QT6 = false
endif endif

ifneq (,$(findstring true,$(HAVE_QT5)$(HAVE_QT5PKG)))
HAVE_THEME = true
ifeq (,$(wildcard $(RCC_QT6)))
HAVE_QT6 = false
endif
ifeq (,$(wildcard $(UIC_QT6)))
HAVE_QT6 = false
endif endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
@@ -311,27 +347,49 @@ endif
PYRCC5 ?= $(shell which pyrcc5 2>/dev/null) PYRCC5 ?= $(shell which pyrcc5 2>/dev/null)
PYUIC5 ?= $(shell which pyuic5 2>/dev/null) PYUIC5 ?= $(shell which pyuic5 2>/dev/null)


ifneq ($(PYUIC5),)
ifneq ($(PYRCC5),)
HAVE_PYQT = true
ifneq (,$(findstring true,$(HAVE_QT5)$(HAVE_QT5PKG)))
PYUIC6 ?= $(shell which pyuic6 2>/dev/null)
ifneq (,$(findstring true,$(HAVE_QT6)$(HAVE_QT6BREW)))
ifneq ($(PYUIC6),)
HAVE_FRONTEND = true HAVE_FRONTEND = true
HAVE_PYQT = true
FRONTEND_TYPE = 6
endif endif
endif endif

ifneq (,$(findstring true,$(HAVE_QT5)$(HAVE_QT5PKG)$(HAVE_QT5BREW)))
ifneq ($(PYUIC5)$(PYRCC5),)
HAVE_FRONTEND = true
HAVE_PYQT = true
FRONTEND_TYPE = 5
endif
endif endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Set PyQt tools, part2
# Set Qt tools, part2

ifneq (,$(findstring true,$(HAVE_QT4)$(HAVE_QT5)$(HAVE_QT5PKG)$(HAVE_QT5BREW)$(HAVE_QT6)$(HAVE_QT6BREW)))
HAVE_QT = true
endif


ifeq ($(FRONTEND_TYPE),5)
MOC = $(MOC_QT5)
RCC = $(RCC_QT5)
UIC = $(UIC_QT5)
PYRCC ?= $(PYRCC5) PYRCC ?= $(PYRCC5)
PYUIC ?= $(PYUIC5) PYUIC ?= $(PYUIC5)

# ---------------------------------------------------------------------------------------------------------------------
# Set USING_JUCE

ifeq ($(MACOS_OR_WINDOWS),true)
USING_JUCE = true
USING_JUCE_AUDIO_DEVICES = true
HAVE_THEME = $(HAVE_QT5)
QT_CXX_FLAGS = $(QT5_CXX_FLAGS)
QT_LINK_FLAGS = $(QT5_LINK_FLAGS)
else ifeq ($(FRONTEND_TYPE),6)
MOC = $(MOC_QT6)
RCC = $(RCC_QT6)
UIC = $(UIC_QT6)
PYRCC ?= $(RCC_QT6) -g python
PYUIC ?= $(PYUIC6)
HAVE_THEME = $(HAVE_QT6)
QT_CXX_FLAGS = $(QT6_CXX_FLAGS)
QT_LINK_FLAGS = $(QT6_LINK_FLAGS)
endif endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
@@ -339,11 +397,9 @@ endif


ifneq ($(HAIKU),true) ifneq ($(HAIKU),true)
ifneq ($(WASM),true) ifneq ($(WASM),true)
ifneq ($(USING_JUCE_AUDIO_DEVICES),true)
USING_RTAUDIO = true USING_RTAUDIO = true
endif endif
endif endif
endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Disable features for static plugin target # Disable features for static plugin target
@@ -360,11 +416,11 @@ HAVE_PYQT = false
HAVE_QT4 = false HAVE_QT4 = false
HAVE_QT5 = false HAVE_QT5 = false
HAVE_QT5PKG = false HAVE_QT5PKG = false
HAVE_QT5BREW = false
HAVE_QT6 = false
HAVE_SDL = false HAVE_SDL = false
HAVE_SDL1 = false HAVE_SDL1 = false
HAVE_SDL2 = false HAVE_SDL2 = false
USING_JUCE = false
USING_JUCE_AUDIO_DEVICES = false
USING_RTAUDIO = false USING_RTAUDIO = false
endif endif


@@ -401,6 +457,11 @@ QT5_FLAGS = $(shell $(PKG_CONFIG) --cflags Qt5Core Qt5Gui Qt5Widgets)
QT5_LIBS = $(shell $(PKG_CONFIG) --libs Qt5Core Qt5Gui Qt5Widgets) QT5_LIBS = $(shell $(PKG_CONFIG) --libs Qt5Core Qt5Gui Qt5Widgets)
endif endif


ifeq ($(HAVE_QT6),true)
QT6_FLAGS = $(shell $(PKG_CONFIG) --cflags Qt6Core Qt6Gui Qt6Widgets)
QT6_LIBS = $(shell $(PKG_CONFIG) --libs Qt6Core Qt6Gui Qt6Widgets)
endif

ifeq ($(WASM),true) ifeq ($(WASM),true)
HAVE_SDL = true HAVE_SDL = true
SDL_FLAGS = -sUSE_SDL=2 SDL_FLAGS = -sUSE_SDL=2
@@ -488,35 +549,6 @@ endif


endif endif


# ---------------------------------------------------------------------------------------------------------------------
# Set libs stuff (juce)

ifeq ($(USING_JUCE),true)

ifeq ($(MACOS),true)
JUCE_AUDIO_BASICS_LIBS = -framework Accelerate
JUCE_AUDIO_DEVICES_LIBS = -framework AppKit -framework AudioToolbox -framework CoreAudio -framework CoreMIDI
JUCE_AUDIO_FORMATS_LIBS = -framework AudioToolbox -framework CoreFoundation
JUCE_AUDIO_PROCESSORS_LIBS = -framework AudioToolbox -framework AudioUnit -framework CoreAudio -framework CoreAudioKit -framework Cocoa
JUCE_CORE_LIBS = -framework AppKit
JUCE_EVENTS_LIBS = -framework AppKit
JUCE_GRAPHICS_LIBS = -framework Cocoa -framework QuartzCore
JUCE_GUI_BASICS_LIBS = -framework Cocoa
JUCE_GUI_EXTRA_LIBS = -framework IOKit
else ifeq ($(WINDOWS),true)
JUCE_AUDIO_BASICS_LIBS =
JUCE_AUDIO_DEVICES_LIBS = -lwinmm -lole32
JUCE_AUDIO_FORMATS_LIBS =
JUCE_AUDIO_PROCESSORS_LIBS =
JUCE_CORE_LIBS = -luuid -lwsock32 -lwininet -lversion -lole32 -lws2_32 -loleaut32 -limm32 -lcomdlg32 -lshlwapi -lrpcrt4 -lwinmm
JUCE_EVENTS_LIBS = -lole32
JUCE_GRAPHICS_LIBS = -lgdi32
JUCE_GUI_BASICS_LIBS = -lgdi32 -limm32 -lcomdlg32 -lole32
JUCE_GUI_EXTRA_LIBS =
endif

endif

# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Set libs stuff (rtaudio) # Set libs stuff (rtaudio)


@@ -650,17 +682,6 @@ STATIC_CARLA_PLUGIN_LIBS += $(RTMEMPOOL_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(WATER_LIBS) STATIC_CARLA_PLUGIN_LIBS += $(WATER_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(YSFX_LIBS) STATIC_CARLA_PLUGIN_LIBS += $(YSFX_LIBS)


ifeq ($(USING_JUCE),true)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_AUDIO_BASICS_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_AUDIO_FORMATS_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_AUDIO_PROCESSORS_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_CORE_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_EVENTS_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_GRAPHICS_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_GUI_BASICS_LIBS)
STATIC_CARLA_PLUGIN_LIBS += $(JUCE_GUI_EXTRA_LIBS)
endif

ifeq ($(EXTERNAL_PLUGINS),true) ifeq ($(EXTERNAL_PLUGINS),true)
ifneq ($(DEBUG),true) ifneq ($(DEBUG),true)
ifneq ($(TESTBUILD),true) ifneq ($(TESTBUILD),true)


+ 6
- 16
source/Makefile.mk View File

@@ -175,10 +175,7 @@ BASE_FLAGS += -DHAVE_DGL
BASE_FLAGS += -DHAVE_OPENGL BASE_FLAGS += -DHAVE_OPENGL
BASE_FLAGS += -DDGL_OPENGL BASE_FLAGS += -DDGL_OPENGL
BASE_FLAGS += -DDONT_SET_USING_DGL_NAMESPACE BASE_FLAGS += -DDONT_SET_USING_DGL_NAMESPACE
ifneq ($(USING_CUSTOM_DPF),true)
BASE_FLAGS += -DDGL_FILE_BROWSER_DISABLED
BASE_FLAGS += -DDGL_NO_SHARED_RESOURCES
else
ifeq ($(USING_CUSTOM_DPF),true)
BASE_FLAGS += -DDISTRHO_UI_FILE_BROWSER=0 BASE_FLAGS += -DDISTRHO_UI_FILE_BROWSER=0
endif endif
ifneq ($(DGL_NAMESPACE),) ifneq ($(DGL_NAMESPACE),)
@@ -188,6 +185,11 @@ BASE_FLAGS += -DDGL_NAMESPACE=CarlaDGL
endif endif
endif endif


ifneq ($(USING_CUSTOM_DPF),true)
BASE_FLAGS += -DDGL_FILE_BROWSER_DISABLED
BASE_FLAGS += -DDGL_NO_SHARED_RESOURCES
endif

ifeq ($(HAVE_FLUIDSYNTH),true) ifeq ($(HAVE_FLUIDSYNTH),true)
BASE_FLAGS += -DHAVE_FLUIDSYNTH BASE_FLAGS += -DHAVE_FLUIDSYNTH
ifeq ($(HAVE_FLUIDSYNTH_INSTPATCH),true) ifeq ($(HAVE_FLUIDSYNTH_INSTPATCH),true)
@@ -237,18 +239,6 @@ ifeq ($(HAVE_YSFX),true)
BASE_FLAGS += -DHAVE_YSFX BASE_FLAGS += -DHAVE_YSFX
endif endif


ifeq ($(USING_JUCE),true)
BASE_FLAGS += -DUSING_JUCE
BASE_FLAGS += -DJUCE_APP_CONFIG_HEADER='"AppConfig.h"'
ifeq ($(WINDOWS),true)
BASE_FLAGS += -D_WIN32_WINNT=0x0600
endif
endif

ifeq ($(USING_JUCE_AUDIO_DEVICES),true)
BASE_FLAGS += -DUSING_JUCE_AUDIO_DEVICES
endif

ifeq ($(USING_RTAUDIO),true) ifeq ($(USING_RTAUDIO),true)
BASE_FLAGS += -DUSING_RTAUDIO BASE_FLAGS += -DUSING_RTAUDIO
endif endif


+ 7
- 26
source/backend/CarlaEngine.hpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef CARLA_ENGINE_HPP_INCLUDED #ifndef CARLA_ENGINE_HPP_INCLUDED
#define CARLA_ENGINE_HPP_INCLUDED #define CARLA_ENGINE_HPP_INCLUDED
@@ -52,35 +38,30 @@ enum EngineType {
*/ */
kEngineTypeJack = 1, kEngineTypeJack = 1,


/*!
* JUCE engine type, used to provide Native Audio and MIDI support.
*/
kEngineTypeJuce = 2,

/*! /*!
* RtAudio engine type, used to provide Native Audio and MIDI support. * RtAudio engine type, used to provide Native Audio and MIDI support.
*/ */
kEngineTypeRtAudio = 3,
kEngineTypeRtAudio = 2,


/*! /*!
* SDL engine type, used to provide Native Audio support. * SDL engine type, used to provide Native Audio support.
*/ */
kEngineTypeSDL = 4,
kEngineTypeSDL = 3,


/*! /*!
* Plugin engine type, used to export the engine as a plugin. * Plugin engine type, used to export the engine as a plugin.
*/ */
kEngineTypePlugin = 5,
kEngineTypePlugin = 4,


/*! /*!
* Bridge engine type, used in BridgePlugin class. * Bridge engine type, used in BridgePlugin class.
*/ */
kEngineTypeBridge = 6,
kEngineTypeBridge = 5,


/*! /*!
* Dummy engine type, does not send audio or MIDI anywhere. * Dummy engine type, does not send audio or MIDI anywhere.
*/ */
kEngineTypeDummy = 7
kEngineTypeDummy = 6
}; };


/*! /*!


+ 2
- 24
source/backend/CarlaEngineInit.hpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef CARLA_ENGINE_INIT_HPP_INCLUDED #ifndef CARLA_ENGINE_INIT_HPP_INCLUDED
#define CARLA_ENGINE_INIT_HPP_INCLUDED #define CARLA_ENGINE_INIT_HPP_INCLUDED
@@ -60,14 +46,6 @@ CarlaEngine* newBridge(const char* audioPoolBaseName,
const char* nonRtClientBaseName, const char* nonRtClientBaseName,
const char* nonRtServerBaseName); const char* nonRtServerBaseName);


// Juce
CarlaEngine* newJuce(AudioApi api);
uint getJuceApiCount();
const char* getJuceApiName(uint index);
const char* const* getJuceApiDeviceNames(uint index);
const EngineDriverDeviceInfo* getJuceDeviceInfo(uint index, const char* deviceName);
bool showJuceDeviceControlPanel(uint index, const char* deviceName);

// RtAudio // RtAudio
CarlaEngine* newRtAudio(AudioApi api); CarlaEngine* newRtAudio(AudioApi api);
uint getRtAudioApiCount(); uint getRtAudioApiCount();


+ 2
- 21
source/backend/CarlaHost.h View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef CARLA_HOST_H_INCLUDED #ifndef CARLA_HOST_H_INCLUDED
#define CARLA_HOST_H_INCLUDED #define CARLA_HOST_H_INCLUDED
@@ -1173,11 +1159,6 @@ CARLA_API_EXPORT void carla_nsm_ready(CarlaHostHandle handle, NsmCallbackOpcode
*/ */
CARLA_API_EXPORT const char* carla_get_complete_license_text(void); CARLA_API_EXPORT const char* carla_get_complete_license_text(void);


/*!
* Get the juce version used in the current Carla build.
*/
CARLA_API_EXPORT const char* carla_get_juce_version(void);

/*! /*!
* Get the list of supported file extensions in carla_load_file(). * Get the list of supported file extensions in carla_load_file().
*/ */


+ 3
- 19
source/backend/CarlaPlugin.hpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef CARLA_PLUGIN_HPP_INCLUDED #ifndef CARLA_PLUGIN_HPP_INCLUDED
#define CARLA_PLUGIN_HPP_INCLUDED #define CARLA_PLUGIN_HPP_INCLUDED
@@ -24,7 +10,6 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Avoid including extra libs here // Avoid including extra libs here


typedef void* lo_message;
typedef struct _NativePluginDescriptor NativePluginDescriptor; typedef struct _NativePluginDescriptor NativePluginDescriptor;
struct LADSPA_RDF_Descriptor; struct LADSPA_RDF_Descriptor;


@@ -778,7 +763,7 @@ public:
int argc, int argc,
const void* argv, const void* argv,
const char* types, const char* types,
lo_message msg);
void* msg);


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// MIDI events // MIDI events
@@ -987,7 +972,6 @@ public:
static CarlaPluginPtr newJSFX(const Initializer& init); static CarlaPluginPtr newJSFX(const Initializer& init);
static CarlaPluginPtr newCLAP(const Initializer& init); static CarlaPluginPtr newCLAP(const Initializer& init);


static CarlaPluginPtr newJuce(const Initializer& init, const char* format);
static CarlaPluginPtr newFluidSynth(const Initializer& init, PluginType ptype, bool use16Outs); static CarlaPluginPtr newFluidSynth(const Initializer& init, PluginType ptype, bool use16Outs);
static CarlaPluginPtr newSFZero(const Initializer& init); static CarlaPluginPtr newSFZero(const Initializer& init);




+ 2
- 35
source/backend/CarlaStandalone.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Standalone
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


// TODO: // TODO:
// Check carla_stderr2("Engine is not running"); <= prepend func name and args // Check carla_stderr2("Engine is not running"); <= prepend func name and args
@@ -30,10 +16,6 @@


#include "water/files/File.h" #include "water/files/File.h"


#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
# include "carla_juce/carla_juce.h"
#endif

#define CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(cond, msg, ret) \ #define CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(cond, msg, ret) \
if (! (cond)) { \ if (! (cond)) { \
carla_stderr2("%s: " msg, __FUNCTION__); \ carla_stderr2("%s: " msg, __FUNCTION__); \
@@ -404,10 +386,6 @@ bool carla_engine_init(CarlaHostHandle handle, const char* driverName, const cha
carla_setenv("WINEASIO_CLIENT_NAME", clientName); carla_setenv("WINEASIO_CLIENT_NAME", clientName);
#endif #endif


#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
CarlaJUCE::initialiseJuce_GUI();
#endif

CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle); CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);


CarlaEngine* const engine = CarlaEngine::newDriverByName(driverName); CarlaEngine* const engine = CarlaEngine::newDriverByName(driverName);
@@ -454,9 +432,6 @@ bool carla_engine_init(CarlaHostHandle handle, const char* driverName, const cha
shandle.lastError = engine->getLastError(); shandle.lastError = engine->getLastError();
shandle.engine = nullptr; shandle.engine = nullptr;
delete engine; delete engine;
#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
CarlaJUCE::shutdownJuce_GUI();
#endif
return false; return false;
} }
} }
@@ -534,9 +509,6 @@ bool carla_engine_close(CarlaHostHandle handle)
shandle.engine = nullptr; shandle.engine = nullptr;
delete engine; delete engine;


#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
CarlaJUCE::shutdownJuce_GUI();
#endif
return closed; return closed;
} }


@@ -545,11 +517,6 @@ void carla_engine_idle(CarlaHostHandle handle)
CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->isStandalone,); CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->isStandalone,);


handle->engine->idle(); handle->engine->idle();

#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
if (handle->isStandalone)
CarlaJUCE::idleJuce_GUI();
#endif
} }


bool carla_is_engine_running(CarlaHostHandle handle) bool carla_is_engine_running(CarlaHostHandle handle)


+ 3
- 19
source/backend/CarlaStandaloneNSM.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Standalone
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaHostImpl.hpp" #include "CarlaHostImpl.hpp"


@@ -318,9 +304,7 @@ protected:
fProjectPath = projectPath; fProjectPath = projectPath;
fProjectPath += ".carxp"; fProjectPath += ".carxp";


const String jfilename = String(CharPointer_UTF8(fProjectPath));

if (File(jfilename).existsAsFile())
if (File(fProjectPath).existsAsFile())
carla_load_project(handle, fProjectPath); carla_load_project(handle, fProjectPath);
} }




+ 3
- 52
source/backend/CarlaUtils.h View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef CARLA_UTILS_H_INCLUDED #ifndef CARLA_UTILS_H_INCLUDED
#define CARLA_UTILS_H_INCLUDED #define CARLA_UTILS_H_INCLUDED
@@ -341,19 +327,13 @@ typedef struct _CarlaCachedPluginInfo {


/*! /*!
* Get how many cached plugins are available. * Get how many cached plugins are available.
* Internal and LV2 plugin formats are cached and need to be discovered via this function.
* Internal, LV2 and SFZ plugin formats are cached and can be discovered via this function.
* Do not call this for any other plugin formats. * Do not call this for any other plugin formats.
*
* @note if this carla build uses JUCE, then you must call carla_juce_init beforehand
* @note for AU plugins, you cannot call this outside the main thread
*/ */
CARLA_PLUGIN_EXPORT uint carla_get_cached_plugin_count(PluginType ptype, const char* pluginPath); CARLA_PLUGIN_EXPORT uint carla_get_cached_plugin_count(PluginType ptype, const char* pluginPath);


/*! /*!
* Get information about a cached plugin. * Get information about a cached plugin.
*
* @note if this carla build uses JUCE, then you must call carla_juce_init beforehand
* @note for AU plugins, you cannot call this outside the main thread
*/ */
CARLA_PLUGIN_EXPORT const CarlaCachedPluginInfo* carla_get_cached_plugin_info(PluginType ptype, uint index); CARLA_PLUGIN_EXPORT const CarlaCachedPluginInfo* carla_get_cached_plugin_info(PluginType ptype, uint index);


@@ -367,11 +347,6 @@ CARLA_PLUGIN_EXPORT const CarlaCachedPluginInfo* carla_get_cached_plugin_info(Pl
*/ */
CARLA_PLUGIN_EXPORT const char* carla_get_complete_license_text(void); CARLA_PLUGIN_EXPORT const char* carla_get_complete_license_text(void);


/*!
* Get the juce version used in the current Carla build.
*/
CARLA_PLUGIN_EXPORT const char* carla_get_juce_version(void);

/*! /*!
* Get the list of supported file extensions in carla_load_file(). * Get the list of supported file extensions in carla_load_file().
*/ */
@@ -393,30 +368,6 @@ CARLA_PLUGIN_EXPORT const char* carla_get_library_filename(void);
CARLA_PLUGIN_EXPORT const char* carla_get_library_folder(void); CARLA_PLUGIN_EXPORT const char* carla_get_library_folder(void);
#endif #endif


/* --------------------------------------------------------------------------------------------------------------------
* JUCE */

/*!
* Initialize data structures and GUI support for JUCE.
* This is only needed when carla builds use JUCE and you call cached-plugin related APIs.
*
* Idle must then be called at somewhat regular intervals, though in practice there is no reason for it yet.
*
* Make sure to call carla_juce_cleanup after you are done with APIs that need JUCE.
*/
CARLA_PLUGIN_EXPORT void carla_juce_init(void);

/*!
* Give idle time to JUCE stuff.
* Currently only used for Linux.
*/
CARLA_PLUGIN_EXPORT void carla_juce_idle(void);

/*!
* Cleanup the JUCE stuff that was initialized by carla_juce_init.
*/
CARLA_PLUGIN_EXPORT void carla_juce_cleanup(void);

/* -------------------------------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------------------------------
* pipes */ * pipes */




+ 0
- 29
source/backend/Makefile View File

@@ -54,21 +54,6 @@ ifeq ($(HAVE_YSFX),true)
STANDALONE_LIBS += $(MODULEDIR)/ysfx.a STANDALONE_LIBS += $(MODULEDIR)/ysfx.a
endif endif


ifeq ($(USING_JUCE),true)
STANDALONE_LIBS += $(MODULEDIR)/carla_juce.a
STANDALONE_LIBS += $(MODULEDIR)/juce_audio_basics.a
ifeq ($(USING_JUCE_AUDIO_DEVICES),true)
STANDALONE_LIBS += $(MODULEDIR)/juce_audio_devices.a
endif
STANDALONE_LIBS += $(MODULEDIR)/juce_audio_processors.a
STANDALONE_LIBS += $(MODULEDIR)/juce_core.a
STANDALONE_LIBS += $(MODULEDIR)/juce_data_structures.a
STANDALONE_LIBS += $(MODULEDIR)/juce_events.a
STANDALONE_LIBS += $(MODULEDIR)/juce_graphics.a
STANDALONE_LIBS += $(MODULEDIR)/juce_gui_basics.a
STANDALONE_LIBS += $(MODULEDIR)/juce_gui_extra.a
endif

ifeq ($(USING_RTAUDIO),true) ifeq ($(USING_RTAUDIO),true)
STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a
STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a
@@ -93,20 +78,6 @@ ifeq ($(HAVE_YSFX),true)
STANDALONE_LINK_FLAGS += $(YSFX_GRAPHICS_LIBS) STANDALONE_LINK_FLAGS += $(YSFX_GRAPHICS_LIBS)
endif endif


ifeq ($(USING_JUCE),true)
STANDALONE_LINK_FLAGS += $(JUCE_AUDIO_BASICS_LIBS)
ifeq ($(USING_JUCE_AUDIO_DEVICES),true)
STANDALONE_LINK_FLAGS += $(JUCE_AUDIO_DEVICES_LIBS)
endif
STANDALONE_LINK_FLAGS += $(JUCE_AUDIO_PROCESSORS_LIBS)
STANDALONE_LINK_FLAGS += $(JUCE_CORE_LIBS)
STANDALONE_LINK_FLAGS += $(JUCE_DATA_STRUCTURES_LIBS)
STANDALONE_LINK_FLAGS += $(JUCE_EVENTS_LIBS)
STANDALONE_LINK_FLAGS += $(JUCE_GRAPHICS_LIBS)
STANDALONE_LINK_FLAGS += $(JUCE_GUI_BASICS_LIBS)
STANDALONE_LINK_FLAGS += $(JUCE_GUI_EXTRA_LIBS)
endif

ifeq ($(USING_RTAUDIO),true) ifeq ($(USING_RTAUDIO),true)
STANDALONE_LINK_FLAGS += $(RTAUDIO_LIBS) STANDALONE_LINK_FLAGS += $(RTAUDIO_LIBS)
STANDALONE_LINK_FLAGS += $(RTMIDI_LIBS) STANDALONE_LINK_FLAGS += $(RTMIDI_LIBS)


+ 0
- 7
source/backend/Makefile.mk View File

@@ -10,13 +10,6 @@ endif


include $(CWD)/Makefile.mk include $(CWD)/Makefile.mk


# Workaround GCC bug
ifeq ($(TESTBUILD),true)
ifeq ($(USING_JUCE),true)
BUILD_CXX_FLAGS += -Wno-undef
endif
endif

# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


BINDIR := $(CWD)/../bin BINDIR := $(CWD)/../bin


+ 21
- 98
source/backend/engine/CarlaEngine.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


/* TODO: /* TODO:
* - complete processRack(): carefully add to input, sorted events * - complete processRack(): carefully add to input, sorted events
@@ -100,10 +86,6 @@ uint CarlaEngine::getDriverCount()
++count; ++count;
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
count += getJuceApiCount();
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
count += getRtAudioApiCount(); count += getRtAudioApiCount();
#endif #endif
@@ -131,15 +113,6 @@ const char* CarlaEngine::getDriverName(const uint index)
} }
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
if (const uint count = getJuceApiCount())
{
if (index2 < count)
return getJuceApiName(index2);
index2 -= count;
}
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
if (const uint count = getRtAudioApiCount()) if (const uint count = getRtAudioApiCount())
{ {
@@ -178,15 +151,6 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index)
} }
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
if (const uint count = getJuceApiCount())
{
if (index2 < count)
return getJuceApiDeviceNames(index2);
index2 -= count;
}
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
if (const uint count = getRtAudioApiCount()) if (const uint count = getRtAudioApiCount())
{ {
@@ -228,15 +192,6 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index,
} }
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
if (const uint count = getJuceApiCount())
{
if (index2 < count)
return getJuceDeviceInfo(index2, deviceName);
index2 -= count;
}
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
if (const uint count = getRtAudioApiCount()) if (const uint count = getRtAudioApiCount())
{ {
@@ -280,15 +235,6 @@ bool CarlaEngine::showDriverDeviceControlPanel(const uint index, const char* con
} }
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
if (const uint count = getJuceApiCount())
{
if (index2 < count)
return showJuceDeviceControlPanel(index2, deviceName);
index2 -= count;
}
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
if (const uint count = getRtAudioApiCount()) if (const uint count = getRtAudioApiCount())
{ {
@@ -324,30 +270,6 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)
return newDummy(); return newDummy();
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
// -------------------------------------------------------------------
// linux

if (std::strcmp(driverName, "ALSA") == 0)
return newJuce(AUDIO_API_ALSA);

// -------------------------------------------------------------------
// macos

if (std::strcmp(driverName, "CoreAudio") == 0)
return newJuce(AUDIO_API_COREAUDIO);

// -------------------------------------------------------------------
// windows

if (std::strcmp(driverName, "ASIO") == 0)
return newJuce(AUDIO_API_ASIO);
if (std::strcmp(driverName, "DirectSound") == 0)
return newJuce(AUDIO_API_DIRECTSOUND);
if (std::strcmp(driverName, "WASAPI") == 0 || std::strcmp(driverName, "Windows Audio") == 0)
return newJuce(AUDIO_API_WASAPI);
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// common // common
@@ -782,14 +704,14 @@ bool CarlaEngine::addPlugin(const BinaryType btype,
plugin = CarlaPlugin::newVST3(initializer); plugin = CarlaPlugin::newVST3(initializer);
break; break;


case PLUGIN_AU:
plugin = CarlaPlugin::newAU(initializer);
break;

case PLUGIN_CLAP: case PLUGIN_CLAP:
plugin = CarlaPlugin::newCLAP(initializer); plugin = CarlaPlugin::newCLAP(initializer);
break; break;


case PLUGIN_AU:
plugin = CarlaPlugin::newAU(initializer);
break;

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
case PLUGIN_INTERNAL: case PLUGIN_INTERNAL:
plugin = CarlaPlugin::newNative(initializer); plugin = CarlaPlugin::newNative(initializer);
@@ -1298,8 +1220,7 @@ bool CarlaEngine::loadFile(const char* const filename)
CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename"); CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename");
carla_debug("CarlaEngine::loadFile(\"%s\")", filename); carla_debug("CarlaEngine::loadFile(\"%s\")", filename);


const String jfilename = String(CharPointer_UTF8(filename));
File file(jfilename);
File file(filename);
CARLA_SAFE_ASSERT_RETURN_ERR(file.exists(), "Requested file does not exist or is not a readable"); CARLA_SAFE_ASSERT_RETURN_ERR(file.exists(), "Requested file does not exist or is not a readable");


CarlaString baseName(file.getFileNameWithoutExtension().toRawUTF8()); CarlaString baseName(file.getFileNameWithoutExtension().toRawUTF8());
@@ -1442,6 +1363,9 @@ bool CarlaEngine::loadFile(const char* const filename)
// Direct plugin binaries // Direct plugin binaries


#ifdef CARLA_OS_MAC #ifdef CARLA_OS_MAC
if (extension == "component")
return addPlugin(PLUGIN_AU, filename, nullptr, nullptr, 0, nullptr);

if (extension == "vst") if (extension == "vst")
return addPlugin(PLUGIN_VST2, filename, nullptr, nullptr, 0, nullptr); return addPlugin(PLUGIN_VST2, filename, nullptr, nullptr, 0, nullptr);
#else #else
@@ -1467,8 +1391,7 @@ bool CarlaEngine::loadProject(const char* const filename, const bool setAsCurren
CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename"); CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename");
carla_debug("CarlaEngine::loadProject(\"%s\")", filename); carla_debug("CarlaEngine::loadProject(\"%s\")", filename);


const String jfilename = String(CharPointer_UTF8(filename));
const File file(jfilename);
const File file(filename);
CARLA_SAFE_ASSERT_RETURN_ERR(file.existsAsFile(), "Requested file does not exist or is not a readable file"); CARLA_SAFE_ASSERT_RETURN_ERR(file.existsAsFile(), "Requested file does not exist or is not a readable file");


if (setAsCurrentProject) if (setAsCurrentProject)
@@ -1529,8 +1452,7 @@ bool CarlaEngine::saveProject(const char* const filename, const bool setAsCurren
MemoryOutputStream out; MemoryOutputStream out;
saveProjectInternal(out); saveProjectInternal(out);


const String jfilename = String(CharPointer_UTF8(filename));
File file(jfilename);
File file(filename);


if (file.replaceWithData(out.getData(), out.getDataSize())) if (file.replaceWithData(out.getData(), out.getDataSize()))
return true; return true;
@@ -2679,7 +2601,7 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c
jbinary = jbinary.substring(2).replaceCharacter('\\', '/'); jbinary = jbinary.substring(2).replaceCharacter('\\', '/');
#endif #endif


String filename = File(jbinary).getFileName();
String filename = File(jbinary.toRawUTF8()).getFileName();


int searchFlags = File::findFiles|File::ignoreHiddenFiles; int searchFlags = File::findFiles|File::ignoreHiddenFiles;


@@ -2693,10 +2615,10 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c
std::vector<File> results; std::vector<File> results;
for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it)
{ {
const File path(*it);
const File path(it->toRawUTF8());


results.clear(); results.clear();
path.findChildFiles(results, searchFlags, true, filename);
path.findChildFiles(results, searchFlags, true, filename.toRawUTF8());


if (!results.empty()) if (!results.empty())
return results.front().getFullPathName(); return results.front().getFullPathName();
@@ -2705,23 +2627,23 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c
// try changing extension // try changing extension
#if defined(CARLA_OS_MAC) #if defined(CARLA_OS_MAC)
if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".so")) if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".so"))
filename = File(jbinary).getFileNameWithoutExtension() + ".dylib";
filename = File(jbinary.toRawUTF8()).getFileNameWithoutExtension() + ".dylib";
#elif defined(CARLA_OS_WIN) #elif defined(CARLA_OS_WIN)
if (filename.endsWithIgnoreCase(".dylib") || filename.endsWithIgnoreCase(".so")) if (filename.endsWithIgnoreCase(".dylib") || filename.endsWithIgnoreCase(".so"))
filename = File(jbinary).getFileNameWithoutExtension() + ".dll";
filename = File(jbinary.toRawUTF8()).getFileNameWithoutExtension() + ".dll";
#else #else
if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".dylib")) if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".dylib"))
filename = File(jbinary).getFileNameWithoutExtension() + ".so";
filename = File(jbinary.toRawUTF8()).getFileNameWithoutExtension() + ".so";
#endif #endif
else else
return String(); return String();


for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it)
{ {
const File path(*it);
const File path(it->toRawUTF8());


results.clear(); results.clear();
path.findChildFiles(results, searchFlags, true, filename);
path.findChildFiles(results, searchFlags, true, filename.toRawUTF8());


if (!results.empty()) if (!results.empty())
return results.front().getFullPathName(); return results.front().getFullPathName();
@@ -3174,6 +3096,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
case PLUGIN_VST2: case PLUGIN_VST2:
case PLUGIN_VST3: case PLUGIN_VST3:
case PLUGIN_CLAP: case PLUGIN_CLAP:
case PLUGIN_AU:
btype = getBinaryTypeFromFile(stateSave.binary); btype = getBinaryTypeFromFile(stateSave.binary);
break; break;
default: default:


+ 7
- 21
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
# error This file should not be compiled if not building bridge # error This file should not be compiled if not building bridge
@@ -934,7 +920,7 @@ public:
{ {
if (valueSize > maxLocalValueLen) if (valueSize > maxLocalValueLen)
{ {
const BridgeTextReader bigValueFilePathTry(fShmNonRtClientControl, valueSize);
const BridgeTextReader bigValueFilePathTry(fShmNonRtClientControl);


CARLA_SAFE_ASSERT_BREAK(bigValueFilePathTry.text[0] != '\0'); CARLA_SAFE_ASSERT_BREAK(bigValueFilePathTry.text[0] != '\0');
if (! plugin->isEnabled()) break; if (! plugin->isEnabled()) break;
@@ -947,7 +933,7 @@ public:
bigValueFilePath = bigValueFilePath.replaceSection(0, 1, "Z:\\").replace("/", "\\"); bigValueFilePath = bigValueFilePath.replaceSection(0, 1, "Z:\\").replace("/", "\\");
#endif #endif


File bigValueFile(bigValueFilePath);
File bigValueFile(bigValueFilePath.toRawUTF8());
CARLA_SAFE_ASSERT_BREAK(bigValueFile.existsAsFile()); CARLA_SAFE_ASSERT_BREAK(bigValueFile.existsAsFile());


plugin->setCustomData(type.text, key.text, bigValueFile.loadFileAsString().toRawUTF8(), true); plugin->setCustomData(type.text, key.text, bigValueFile.loadFileAsString().toRawUTF8(), true);
@@ -988,7 +974,7 @@ public:
chunkFilePath = chunkFilePath.replaceSection(0, 1, "Z:\\").replace("/", "\\"); chunkFilePath = chunkFilePath.replaceSection(0, 1, "Z:\\").replace("/", "\\");
#endif #endif


File chunkFile(chunkFilePath);
File chunkFile(chunkFilePath.toRawUTF8());
CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile()); CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile());


String chunkDataBase64(chunkFile.loadFileAsString()); String chunkDataBase64(chunkFile.loadFileAsString());
@@ -1122,7 +1108,7 @@ public:
filePath += CARLA_OS_SEP_STR ".CarlaCustomData_"; filePath += CARLA_OS_SEP_STR ".CarlaCustomData_";
filePath += fShmAudioPool.getFilenameSuffix(); filePath += fShmAudioPool.getFilenameSuffix();


if (File(filePath).replaceWithText(cdata.value))
if (File(filePath.toRawUTF8()).replaceWithText(cdata.value))
{ {
const uint32_t ulength(static_cast<uint32_t>(filePath.length())); const uint32_t ulength(static_cast<uint32_t>(filePath.length()));


@@ -1160,7 +1146,7 @@ public:
filePath += CARLA_OS_SEP_STR ".CarlaChunk_"; filePath += CARLA_OS_SEP_STR ".CarlaChunk_";
filePath += fShmAudioPool.getFilenameSuffix(); filePath += fShmAudioPool.getFilenameSuffix();


if (File(filePath).replaceWithText(dataBase64.buffer()))
if (File(filePath.toRawUTF8()).replaceWithText(dataBase64.buffer()))
{ {
const uint32_t ulength(static_cast<uint32_t>(filePath.length())); const uint32_t ulength(static_cast<uint32_t>(filePath.length()));




+ 3
- 31
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaEngineClient.hpp" #include "CarlaEngineClient.hpp"
#include "CarlaEngineInit.hpp" #include "CarlaEngineInit.hpp"
@@ -29,10 +15,6 @@


#include "jackey.h" #include "jackey.h"


#ifdef USING_JUCE
# include "carla_juce/carla_juce.h"
#endif

#ifdef __SSE2_MATH__ #ifdef __SSE2_MATH__
# include <xmmintrin.h> # include <xmmintrin.h>
#endif #endif
@@ -4535,10 +4517,6 @@ int jack_initialize(jack_client_t* const client, const char* const load_init)
else else
mode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS; mode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;


#ifdef USING_JUCE
CarlaJUCE::initialiseJuce_GUI();
#endif

CarlaEngineJack* const engine = new CarlaEngineJack(); CarlaEngineJack* const engine = new CarlaEngineJack();


engine->setOption(ENGINE_OPTION_FORCE_STEREO, 1, nullptr); engine->setOption(ENGINE_OPTION_FORCE_STEREO, 1, nullptr);
@@ -4564,9 +4542,7 @@ int jack_initialize(jack_client_t* const client, const char* const load_init)
return 0; return 0;


delete engine; delete engine;
#ifdef USING_JUCE
CarlaJUCE::shutdownJuce_GUI();
#endif

return 1; return 1;
} }


@@ -4582,10 +4558,6 @@ void jack_finish(void *arg)
engine->removeAllPlugins(); engine->removeAllPlugins();
engine->close(); engine->close();
delete engine; delete engine;

#ifdef USING_JUCE
CarlaJUCE::shutdownJuce_GUI();
#endif
} }


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


+ 0
- 1142
source/backend/engine/CarlaEngineJuce.cpp
File diff suppressed because it is too large
View File


+ 21
- 101
source/backend/engine/CarlaEngineNative.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaDefines.h" #include "CarlaDefines.h"


@@ -49,10 +35,6 @@
# include <direct.h> # include <direct.h>
#endif #endif


#ifdef USING_JUCE
# include "carla_juce/carla_juce.h"
#endif

using water::File; using water::File;
using water::MemoryOutputStream; using water::MemoryOutputStream;
using water::String; using water::String;
@@ -111,13 +93,6 @@ public:
const uint32_t cvIns = 0, const uint32_t cvOuts = 0) const uint32_t cvIns = 0, const uint32_t cvOuts = 0)
: CarlaEngine(), : CarlaEngine(),
pHost(host), pHost(host),
#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
// if not running inside Carla, we will have to run event loop ourselves
kNeedsJuceEvents(host->dispatcher(pHost->handle,
NATIVE_HOST_OPCODE_INTERNAL_PLUGIN, 0, 0, nullptr, 0.0f) == 0),
fJuceMsgMgr(),
fJuceMsgMutex(),
#endif
kIsPatchbay(isPatchbay), kIsPatchbay(isPatchbay),
kHasMidiIn(withMidiIn), kHasMidiIn(withMidiIn),
kHasMidiOut(withMidiOut), kHasMidiOut(withMidiOut),
@@ -136,11 +111,6 @@ public:


carla_zeroFloats(fParameters, kNumInParams+kNumOutParams); carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);


#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
if (kNeedsJuceEvents)
fJuceMsgMgr.incRef();
#endif

pData->bufferSize = pHost->get_buffer_size(pHost->handle); pData->bufferSize = pHost->get_buffer_size(pHost->handle);
pData->sampleRate = pHost->get_sample_rate(pHost->handle); pData->sampleRate = pHost->get_sample_rate(pHost->handle);
pData->initTime(nullptr); pData->initTime(nullptr);
@@ -198,21 +168,11 @@ public:
pData->aboutToClose = true; pData->aboutToClose = true;
fIsRunning = false; fIsRunning = false;


{
#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
const ScopedJuceMessageThreadRunner sjmtr(*this, true);
#endif
removeAllPlugins();
//runPendingRtEvents();
close();

pData->graph.destroy();
}
removeAllPlugins();
//runPendingRtEvents();
close();


#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
if (kNeedsJuceEvents)
fJuceMsgMgr.decRef();
#endif
pData->graph.destroy();


carla_debug("CarlaEngineNative::~CarlaEngineNative() - END"); carla_debug("CarlaEngineNative::~CarlaEngineNative() - END");
} }
@@ -351,6 +311,14 @@ public:
pHost->ui_closed(pHost->handle); pHost->ui_closed(pHost->handle);
break; break;


case ENGINE_CALLBACK_EMBED_UI_RESIZED:
if (sendHost && fUsesEmbed)
pHost->dispatcher(pHost->handle,
NATIVE_HOST_OPCODE_UI_RESIZE,
value1, value2,
nullptr, 0.0f);
break;

default: default:
break; break;
} }
@@ -1345,13 +1313,6 @@ protected:


void uiIdle() void uiIdle()
{ {
#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
const ScopedJuceMessageThreadRunner sjmtr(*this, false);

if (kNeedsJuceEvents && ! sjmtr.wasLocked)
return;
#endif

for (uint i=0; i < pData->curPluginCount; ++i) for (uint i=0; i < pData->curPluginCount; ++i)
{ {
if (const CarlaPluginPtr plugin = pData->plugins[i].plugin) if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
@@ -1391,11 +1352,13 @@ protected:
if (carla_isNotEqual(fLastScaleFactor, pData->options.uiScale)) if (carla_isNotEqual(fLastScaleFactor, pData->options.uiScale))
{ {
fLastScaleFactor = pData->options.uiScale; fLastScaleFactor = pData->options.uiScale;
pHost->dispatcher(pHost->handle,
NATIVE_HOST_OPCODE_UI_RESIZE,
static_cast<int>(kUiWidth * fLastScaleFactor + 0.5f),
static_cast<int>(kUiHeight * fLastScaleFactor + 0.5f),
nullptr, 0.0f);

if (! fUsesEmbed)
pHost->dispatcher(pHost->handle,
NATIVE_HOST_OPCODE_UI_RESIZE,
static_cast<int>(kUiWidth * fLastScaleFactor + 0.5f),
static_cast<int>(kUiHeight * fLastScaleFactor + 0.5f),
nullptr, 0.0f);
} }


{ {
@@ -1537,10 +1500,6 @@ protected:


void setState(const char* const data) void setState(const char* const data)
{ {
#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
const ScopedJuceMessageThreadRunner sjmtr(*this, true);
#endif

// remove all plugins from UI side // remove all plugins from UI side
for (uint i=0, count=pData->curPluginCount; i < count; ++i) for (uint i=0, count=pData->curPluginCount; i < count; ++i)
CarlaEngine::callback(true, true, ENGINE_CALLBACK_PLUGIN_REMOVED, count-i-1, 0, 0, 0, 0.0f, nullptr); CarlaEngine::callback(true, true, ENGINE_CALLBACK_PLUGIN_REMOVED, count-i-1, 0, 0, 0, 0.0f, nullptr);
@@ -1750,36 +1709,6 @@ public:
private: private:
const NativeHostDescriptor* const pHost; const NativeHostDescriptor* const pHost;


#ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
const bool kNeedsJuceEvents;
const CarlaJUCE::ReferenceCountedJuceMessageMessager fJuceMsgMgr;
CarlaMutex fJuceMsgMutex;

struct ScopedJuceMessageThreadRunner {
const CarlaMutexTryLocker cmtl;
const bool wasLocked;

ScopedJuceMessageThreadRunner(CarlaEngineNative& self, const bool forceLock) noexcept
: cmtl(self.fJuceMsgMutex, forceLock),
wasLocked(cmtl.wasLocked())
{
if (! self.kNeedsJuceEvents)
return;
if (! wasLocked)
return;

CarlaJUCE::setMessageManagerForThisThread();
}

~ScopedJuceMessageThreadRunner()
{
CarlaJUCE::dispatchMessageManagerMessages();
}

CARLA_DECLARE_NON_COPYABLE(ScopedJuceMessageThreadRunner)
};
#endif

const bool kIsPatchbay; // rack if false const bool kIsPatchbay; // rack if false
const bool kHasMidiIn; const bool kHasMidiIn;
const bool kHasMidiOut; const bool kHasMidiOut;
@@ -3112,15 +3041,6 @@ namespace EngineInit {
CarlaEngine* newJack() { return nullptr; } CarlaEngine* newJack() { return nullptr; }
#endif #endif


#ifdef USING_JUCE_AUDIO_DEVICES
CarlaEngine* newJuce(const AudioApi) { return nullptr; }
uint getJuceApiCount() { return 0; }
const char* getJuceApiName(const uint) { return nullptr; }
const char* const* getJuceApiDeviceNames(const uint) { return nullptr; }
const EngineDriverDeviceInfo* getJuceDeviceInfo(const uint, const char* const) { return nullptr; }
bool showJuceDeviceControlPanel(const uint, const char* const) { return false; }
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
CarlaEngine* newRtAudio(const AudioApi) { return nullptr; } CarlaEngine* newRtAudio(const AudioApi) { return nullptr; }
uint getRtAudioApiCount() { return 0; } uint getRtAudioApiCount() { return 0; }


+ 1
- 1
source/backend/engine/CarlaEngineOsc.hpp View File

@@ -139,7 +139,7 @@ private:
int argc, const lo_arg* const* argv, const char* types, lo_message msg); int argc, const lo_arg* const* argv, const char* types, lo_message msg);


int handleMsgRegister(bool isTCP, int argc, const lo_arg* const* argv, const char* types, lo_address source); int handleMsgRegister(bool isTCP, int argc, const lo_arg* const* argv, const char* types, lo_address source);
int handleMsgUnregister(bool isTCP, int argc, const lo_arg* const* argv, const char* types);
int handleMsgUnregister(bool isTCP, int argc, const lo_arg* const* argv, const char* types, lo_address source);
int handleMsgControl(const char* method, int handleMsgControl(const char* method,
int argc, const lo_arg* const* argv, const char* types); int argc, const lo_arg* const* argv, const char* types);




+ 18
- 7
source/backend/engine/CarlaEngineOscHandlers.cpp View File

@@ -61,7 +61,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path,
return handleMsgRegister(isTCP, argc, argv, types, source); return handleMsgRegister(isTCP, argc, argv, types, source);


if (std::strcmp(path, "/unregister") == 0) if (std::strcmp(path, "/unregister") == 0)
return handleMsgUnregister(isTCP, argc, argv, types);
return handleMsgUnregister(isTCP, argc, argv, types, source);


if (std::strncmp(path, "/ctrl/", 6) == 0) if (std::strncmp(path, "/ctrl/", 6) == 0)
{ {
@@ -284,7 +284,8 @@ int CarlaEngineOsc::handleMsgRegister(const bool isTCP,
} }


int CarlaEngineOsc::handleMsgUnregister(const bool isTCP, int CarlaEngineOsc::handleMsgUnregister(const bool isTCP,
const int argc, const lo_arg* const* const argv, const char* const types)
const int argc, const lo_arg* const* const argv, const char* const types,
const lo_address source)
{ {
carla_debug("CarlaEngineOsc::handleMsgUnregister()"); carla_debug("CarlaEngineOsc::handleMsgUnregister()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");
@@ -297,16 +298,26 @@ int CarlaEngineOsc::handleMsgUnregister(const bool isTCP,
return 0; return 0;
} }


const char* const url = &argv[0]->s;
const char* const url = &argv[0]->s;
const char* const host = lo_address_get_hostname(source);
const char* const path = lo_url_get_path(url);

if (std::strcmp(oscData.owner, host) != 0)
{
carla_stderr("OSC backend unregister failed, current owner host %s does not match requested %s",
oscData.owner, host);
return 0;
}


if (std::strcmp(oscData.owner, url) == 0)
if (std::strcmp(oscData.path, path) != 0)
{ {
carla_stdout("OSC client %s unregistered", url);
oscData.clear();
carla_stderr("OSC backend unregister failed, current owner path %s does not match requested %s",
oscData.path, path);
return 0; return 0;
} }


carla_stderr("OSC backend unregister failed, current owner %s does not match requested %s", oscData.owner, url);
carla_stdout("OSC client %s unregistered", url);
oscData.clear();
return 0; return 0;
} }




+ 6
- 17
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaEngineGraph.hpp" #include "CarlaEngineGraph.hpp"
#include "CarlaEngineInit.hpp" #include "CarlaEngineInit.hpp"
@@ -290,7 +276,10 @@ public:
} }


RtAudio::StreamOptions rtOptions; RtAudio::StreamOptions rtOptions;
rtOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME;
rtOptions.flags = RTAUDIO_SCHEDULE_REALTIME;
#ifndef CARLA_OS_MAC
rtOptions.flags |= RTAUDIO_MINIMIZE_LATENCY;
#endif
rtOptions.numberOfBuffers = pData->options.audioTripleBuffer ? 3 : 2; rtOptions.numberOfBuffers = pData->options.audioTripleBuffer ? 3 : 2;
rtOptions.streamName = clientName; rtOptions.streamName = clientName;
rtOptions.priority = 85; rtOptions.priority = 85;


+ 0
- 19
source/backend/engine/Makefile View File

@@ -7,13 +7,6 @@
CWD=../.. CWD=../..
include ../Makefile.mk include ../Makefile.mk


# Workaround GCC bug
ifeq ($(TESTBUILD),true)
ifeq ($(USING_JUCE_AUDIO_DEVICES),true)
BUILD_CXX_FLAGS += -Wno-undef
endif
endif

BUILD_CXX_FLAGS += $(MAGIC_FLAGS) BUILD_CXX_FLAGS += $(MAGIC_FLAGS)


ifneq ($(HAIKU),true) ifneq ($(HAIKU),true)
@@ -48,11 +41,6 @@ endif
OBJSa = $(OBJS) \ OBJSa = $(OBJS) \
$(OBJDIR)/CarlaEngineNative.cpp.o $(OBJDIR)/CarlaEngineNative.cpp.o


ifeq ($(USING_JUCE_AUDIO_DEVICES),true)
OBJSa += \
$(OBJDIR)/CarlaEngineJuce.cpp.o
endif

ifeq ($(USING_RTAUDIO),true) ifeq ($(USING_RTAUDIO),true)
OBJSa += \ OBJSa += \
$(OBJDIR)/CarlaEngineRtAudio.cpp.o $(OBJDIR)/CarlaEngineRtAudio.cpp.o
@@ -132,13 +120,6 @@ $(OBJDIR)/CarlaEngineJack.cpp.o: CarlaEngineJack.cpp
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(JACK_FLAGS) -c -o $@ $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(JACK_FLAGS) -c -o $@
endif endif


ifeq ($(USING_JUCE),true)
$(OBJDIR)/CarlaEngineJuce.cpp.o: CarlaEngineJuce.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -std=gnu++14 -c -o $@
endif

$(OBJDIR)/%.cpp.o: %.cpp $(OBJDIR)/%.cpp.o: %.cpp
-@mkdir -p $(OBJDIR) -@mkdir -p $(OBJDIR)
@echo "Compiling $<" @echo "Compiling $<"


+ 5
- 21
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaPluginInternal.hpp" #include "CarlaPluginInternal.hpp"
#include "CarlaEngine.hpp" #include "CarlaEngine.hpp"
@@ -987,8 +973,7 @@ bool CarlaPlugin::saveStateToFile(const char* const filename)
out << streamState; out << streamState;
out << "</CARLA-PRESET>\n"; out << "</CARLA-PRESET>\n";


const String jfilename = String(CharPointer_UTF8(filename));
File file(jfilename);
File file(filename);


if (file.replaceWithData(out.getData(), out.getDataSize())) if (file.replaceWithData(out.getData(), out.getDataSize()))
return true; return true;
@@ -1004,8 +989,7 @@ bool CarlaPlugin::loadStateFromFile(const char* const filename)
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false); CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
carla_debug("CarlaPlugin::loadStateFromFile(\"%s\")", filename); carla_debug("CarlaPlugin::loadStateFromFile(\"%s\")", filename);


const String jfilename = String(CharPointer_UTF8(filename));
File file(jfilename);
File file(filename);
CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(), false); CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(), false);


XmlDocument xml(file); XmlDocument xml(file);
@@ -2368,7 +2352,7 @@ void CarlaPlugin::clearBuffers() noexcept
// OSC stuff // OSC stuff


// FIXME // FIXME
void CarlaPlugin::handleOscMessage(const char* const, const int, const void* const, const char* const, const lo_message)
void CarlaPlugin::handleOscMessage(const char*, int, const void*, const char*, void*)
{ {
// do nothing // do nothing
} }


+ 1106
- 27
source/backend/plugin/CarlaPluginAU.cpp
File diff suppressed because it is too large
View File


+ 8
- 8
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla Plugin Bridge * Carla Plugin Bridge
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2024 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -60,7 +60,7 @@ static String findWinePrefix(const String filename, const int recursionLimit = 1


const String path(filename.upToLastOccurrenceOf("/", false, false)); const String path(filename.upToLastOccurrenceOf("/", false, false));


if (File(path + "/dosdevices").isDirectory())
if (File(String(path + "/dosdevices").toRawUTF8()).isDirectory())
return path; return path;


return findWinePrefix(path, recursionLimit-1); return findWinePrefix(path, recursionLimit-1);
@@ -204,7 +204,7 @@ protected:


if (fBridgeBinary.endsWithIgnoreCase("64.exe") if (fBridgeBinary.endsWithIgnoreCase("64.exe")
&& options.wine.executable[0] == CARLA_OS_SEP && options.wine.executable[0] == CARLA_OS_SEP
&& File(wineCMD + "64").existsAsFile())
&& File(String(wineCMD + "64").toRawUTF8()).existsAsFile())
wineCMD += "64"; wineCMD += "64";
} }
else else
@@ -996,7 +996,7 @@ public:
filePath += CARLA_OS_SEP_STR ".CarlaCustomData_"; filePath += CARLA_OS_SEP_STR ".CarlaCustomData_";
filePath += fShmAudioPool.getFilenameSuffix(); filePath += fShmAudioPool.getFilenameSuffix();


if (File(filePath).replaceWithText(value))
if (File(filePath.toRawUTF8()).replaceWithText(value))
{ {
const uint32_t ulength = static_cast<uint32_t>(filePath.length()); const uint32_t ulength = static_cast<uint32_t>(filePath.length());


@@ -1034,7 +1034,7 @@ public:
filePath += CARLA_OS_SEP_STR ".CarlaChunk_"; filePath += CARLA_OS_SEP_STR ".CarlaChunk_";
filePath += fShmAudioPool.getFilenameSuffix(); filePath += fShmAudioPool.getFilenameSuffix();


if (File(filePath).replaceWithText(dataBase64.buffer()))
if (File(filePath.toRawUTF8()).replaceWithText(dataBase64.buffer()))
{ {
const uint32_t ulength = static_cast<uint32_t>(filePath.length()); const uint32_t ulength = static_cast<uint32_t>(filePath.length());


@@ -2550,7 +2550,7 @@ public:
} }
#endif #endif


const File bigValueFile(realBigValueFilePath);
const File bigValueFile(realBigValueFilePath.toRawUTF8());
CARLA_SAFE_ASSERT_BREAK(bigValueFile.existsAsFile()); CARLA_SAFE_ASSERT_BREAK(bigValueFile.existsAsFile());


CarlaPlugin::setCustomData(type.text, key.text, bigValueFile.loadFileAsString().toRawUTF8(), false); CarlaPlugin::setCustomData(type.text, key.text, bigValueFile.loadFileAsString().toRawUTF8(), false);
@@ -2591,7 +2591,7 @@ public:
} }
#endif #endif


const File chunkFile(realChunkFilePath);
const File chunkFile(realChunkFilePath.toRawUTF8());
CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile()); CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile());


fInfo.chunk = carla_getChunkFromBase64String(chunkFile.loadFileAsString().toRawUTF8()); fInfo.chunk = carla_getChunkFromBase64String(chunkFile.loadFileAsString().toRawUTF8());
@@ -3245,7 +3245,7 @@ private:
filePath += CARLA_OS_SEP_STR ".CarlaChunk_"; filePath += CARLA_OS_SEP_STR ".CarlaChunk_";
filePath += fShmAudioPool.getFilenameSuffix(); filePath += fShmAudioPool.getFilenameSuffix();


if (File(filePath).replaceWithText(dataBase64.buffer()))
if (File(filePath.toRawUTF8()).replaceWithText(dataBase64.buffer()))
{ {
const uint32_t ulength(static_cast<uint32_t>(filePath.length())); const uint32_t ulength(static_cast<uint32_t>(filePath.length()));




+ 10
- 10
source/backend/plugin/CarlaPluginJSFX.cpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla JSFX Plugin * Carla JSFX Plugin
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2024 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -224,7 +224,7 @@ public:


bool getLabel(char* const strBuf) const noexcept override bool getLabel(char* const strBuf) const noexcept override
{ {
std::strncpy(strBuf, fUnit.getFileId().toRawUTF8(), STR_MAX);
std::strncpy(strBuf, fUnit.getFileId(), STR_MAX);
return true; return true;
} }


@@ -943,7 +943,7 @@ public:
// find which engine search path we're in, and use this as the root // find which engine search path we're in, and use this as the root
for (int i = 0; i < splitPaths.size() && !fUnit; ++i) for (int i = 0; i < splitPaths.size() && !fUnit; ++i)
{ {
const File currentPath(splitPaths[i]);
const File currentPath(splitPaths[i].toRawUTF8());
if (file.isAChildOf(currentPath)) if (file.isAChildOf(currentPath))
fUnit = CarlaJsfxUnit(currentPath, file); fUnit = CarlaJsfxUnit(currentPath, file);
} }
@@ -957,7 +957,7 @@ public:
// search a matching file in plugin paths // search a matching file in plugin paths
for (int i = 0; i < splitPaths.size() && !fUnit; ++i) for (int i = 0; i < splitPaths.size() && !fUnit; ++i)
{ {
const File currentPath(splitPaths[i]);
const File currentPath(splitPaths[i].toRawUTF8());
const File currentFile = currentPath.getChildFile(CharPointer_UTF8(label)); const File currentFile = currentPath.getChildFile(CharPointer_UTF8(label));
const CarlaJsfxUnit currentUnit(currentPath, currentFile); const CarlaJsfxUnit currentUnit(currentPath, currentFile);
if (File(currentUnit.getFilePath()).existsAsFile()) if (File(currentUnit.getFilePath()).existsAsFile())
@@ -977,12 +977,12 @@ public:
ysfx_config_u config(ysfx_config_new()); ysfx_config_u config(ysfx_config_new());
CARLA_SAFE_ASSERT_RETURN(config != nullptr, false); CARLA_SAFE_ASSERT_RETURN(config != nullptr, false);


const water::String rootPath = fUnit.getRootPath();
const water::String filePath = fUnit.getFilePath();
const CarlaString rootPath = fUnit.getRootPath();
const CarlaString filePath = fUnit.getFilePath();


ysfx_register_builtin_audio_formats(config.get()); ysfx_register_builtin_audio_formats(config.get());
ysfx_set_import_root(config.get(), rootPath.toRawUTF8());
ysfx_guess_file_roots(config.get(), filePath.toRawUTF8());
ysfx_set_import_root(config.get(), rootPath);
ysfx_guess_file_roots(config.get(), filePath);
ysfx_set_log_reporter(config.get(), &CarlaJsfxLogging::logAll); ysfx_set_log_reporter(config.get(), &CarlaJsfxLogging::logAll);
ysfx_set_user_data(config.get(), (intptr_t)this); ysfx_set_user_data(config.get(), (intptr_t)this);


@@ -993,7 +993,7 @@ public:
// get info // get info


{ {
if (! ysfx_load_file(fEffect, filePath.toRawUTF8(), 0))
if (! ysfx_load_file(fEffect, filePath, 0))
{ {
pData->engine->setLastError("Failed to load JSFX"); pData->engine->setLastError("Failed to load JSFX");
return false; return false;
@@ -1021,7 +1021,7 @@ public:
pData->name = carla_strdup(ysfx_get_name(fEffect)); pData->name = carla_strdup(ysfx_get_name(fEffect));
} }


pData->filename = carla_strdup(filePath.toRawUTF8());
pData->filename = filePath.dup();


// --------------------------------------------------------------- // ---------------------------------------------------------------
// register client // register client


+ 4
- 18
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin JACK
* Copyright (C) 2016-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaPluginInternal.hpp" #include "CarlaPluginInternal.hpp"
#include "CarlaEngine.hpp" #include "CarlaEngine.hpp"
@@ -499,7 +485,7 @@ private:
CARLA_SAFE_ASSERT_RETURN(uniqueCodeID != nullptr && uniqueCodeID[0] != '\0', false); CARLA_SAFE_ASSERT_RETURN(uniqueCodeID != nullptr && uniqueCodeID[0] != '\0', false);
CARLA_SAFE_ASSERT_RETURN(appName.isNotEmpty(), false); CARLA_SAFE_ASSERT_RETURN(appName.isNotEmpty(), false);


String child(pluginName);
CarlaString child(pluginName);
child += "."; child += ".";
child += uniqueCodeID; child += uniqueCodeID;


@@ -1886,7 +1872,7 @@ private:
char code[6]; char code[6];
code[5] = '\0'; code[5] = '\0';


String child;
CarlaString child;


for (;;) for (;;)
{ {


+ 0
- 1920
source/backend/plugin/CarlaPluginJuce.cpp
File diff suppressed because it is too large
View File


+ 3
- 3
source/backend/plugin/CarlaPluginLADSPADSSI.cpp View File

@@ -2404,9 +2404,9 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// OSC stuff // OSC stuff


void handleOscMessage(const char* const method, const int argc, const void* const argvx, const char* const types, const lo_message msg) override
void handleOscMessage(const char* const method, const int argc, const void* const argvx, const char* const types, void* const msg) override
{ {
const lo_address source(lo_message_get_source(msg));
const lo_address source = lo_message_get_source(static_cast<lo_message>(msg));
CARLA_SAFE_ASSERT_RETURN(source != nullptr,); CARLA_SAFE_ASSERT_RETURN(source != nullptr,);


// protocol for DSSI UIs *must* be UDP // protocol for DSSI UIs *must* be UDP
@@ -2441,7 +2441,7 @@ public:
if (std::strcmp(method, "midi") == 0) if (std::strcmp(method, "midi") == 0)
return handleOscMessageMIDI(argc, argv, types); return handleOscMessageMIDI(argc, argv, types);
if (std::strcmp(method, "update") == 0) if (std::strcmp(method, "update") == 0)
return handleOscMessageUpdate(argc, argv, types, lo_message_get_source(msg));
return handleOscMessageUpdate(argc, argv, types, source);
if (std::strcmp(method, "exiting") == 0) if (std::strcmp(method, "exiting") == 0)
return handleOscMessageExiting(); return handleOscMessageExiting();




+ 6
- 20
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla LV2 Plugin
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


// testing macros // testing macros
// #define LV2_UIS_ONLY_BRIDGES // #define LV2_UIS_ONLY_BRIDGES
@@ -5853,7 +5839,7 @@ public:
return nullptr; return nullptr;
} }


water::String basedir(pData->engine->getName());
CarlaString basedir(pData->engine->getName());


if (temporary) if (temporary)
basedir += ".tmp"; basedir += ".tmp";
@@ -5881,7 +5867,7 @@ public:
{ {
// seems like a normal save, let's be nice and put a symlink // seems like a normal save, let's be nice and put a symlink
const water::String abstractFilename(wabsolutePath.getFileName()); const water::String abstractFilename(wabsolutePath.getFileName());
const File targetPath(targetDir.getChildFile(abstractFilename));
const File targetPath(targetDir.getChildFile(abstractFilename.toRawUTF8()));


wabsolutePath.createSymbolicLink(targetPath, true); wabsolutePath.createSymbolicLink(targetPath, true);


@@ -5916,7 +5902,7 @@ public:
return File(); return File();
} }


water::String basedir(pData->engine->getName());
CarlaString basedir(pData->engine->getName());


if (temporary) if (temporary)
basedir += ".tmp"; basedir += ".tmp";
@@ -5930,7 +5916,7 @@ public:
if (File::isAbsolutePath(abstractPath)) if (File::isAbsolutePath(abstractPath))
{ {
File wabstractPath(abstractPath); File wabstractPath(abstractPath);
targetPath = targetDir.getChildFile(wabstractPath.getFileName());
targetPath = targetDir.getChildFile(wabstractPath.getFileName().toRawUTF8());


if (symlinkIfNeeded) if (symlinkIfNeeded)
{ {


+ 1
- 1
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -1068,7 +1068,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,); CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,);
carla_debug("CarlaPluginNative::reload() - start"); carla_debug("CarlaPluginNative::reload() - start");


const EngineProcessMode processMode(pData->engine->getProccessMode());
const EngineProcessMode processMode = pData->engine->getProccessMode();


// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler sd(this); const ScopedDisabler sd(this);


+ 2
- 26
source/backend/plugin/CarlaPluginVST2.cpp View File

@@ -1,27 +1,8 @@
/*
* Carla VST2 Plugin
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaPluginInternal.hpp" #include "CarlaPluginInternal.hpp"
#include "CarlaEngine.hpp" #include "CarlaEngine.hpp"
#include "AppConfig.h"

#if defined(USING_JUCE) && JUCE_PLUGINHOST_VST
# define USE_JUCE_FOR_VST2
#endif


#include "CarlaBackendUtils.hpp" #include "CarlaBackendUtils.hpp"
#include "CarlaMathUtils.hpp" #include "CarlaMathUtils.hpp"
@@ -2970,11 +2951,6 @@ CarlaPluginPtr CarlaPlugin::newVST2(const Initializer& init)
carla_debug("CarlaPlugin::newVST2({%p, \"%s\", \"%s\", " P_INT64 "})", carla_debug("CarlaPlugin::newVST2({%p, \"%s\", \"%s\", " P_INT64 "})",
init.engine, init.filename, init.name, init.uniqueId); init.engine, init.filename, init.name, init.uniqueId);


#ifdef USE_JUCE_FOR_VST2
if (std::getenv("CARLA_DO_NOT_USE_JUCE_FOR_VST2") == nullptr)
return newJuce(init, "VST2");
#endif

std::shared_ptr<CarlaPluginVST2> plugin(new CarlaPluginVST2(init.engine, init.id)); std::shared_ptr<CarlaPluginVST2> plugin(new CarlaPluginVST2(init.engine, init.id));


if (! plugin->init(plugin, init.filename, init.name, init.uniqueId, init.options)) if (! plugin->init(plugin, init.filename, init.name, init.uniqueId, init.options))


+ 175
- 57
source/backend/plugin/CarlaPluginVST3.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla VST3 Plugin
* Copyright (C) 2014-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


/* TODO list /* TODO list
* noexcept safe calls * noexcept safe calls
@@ -21,11 +7,6 @@
*/ */
#include "CarlaPluginInternal.hpp" #include "CarlaPluginInternal.hpp"
#include "CarlaEngine.hpp" #include "CarlaEngine.hpp"
#include "AppConfig.h"

#if defined(USING_JUCE) && JUCE_PLUGINHOST_VST3
# define USE_JUCE_FOR_VST3
#endif


#include "CarlaBackendUtils.hpp" #include "CarlaBackendUtils.hpp"
#include "CarlaVst3Utils.hpp" #include "CarlaVst3Utils.hpp"
@@ -1406,9 +1387,7 @@ public:
options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE; options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
options |= PLUGIN_OPTION_SEND_PITCHBEND; options |= PLUGIN_OPTION_SEND_PITCHBEND;
/* TODO
options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
*/
options |= PLUGIN_OPTION_SKIP_SENDING_NOTES; options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
} }


@@ -2390,6 +2369,9 @@ public:
} }
} }


if (fEvents.paramInputs != nullptr && fV3.midiMapping != nullptr)
fMidiControllerAssignments.init(fV3.midiMapping, numEventInputBuses);

bufferSizeChanged(pData->engine->getBufferSize()); bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true); reloadPrograms(true);


@@ -2460,7 +2442,32 @@ public:


if (pData->needsReset) if (pData->needsReset)
{ {
if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS && fEvents.eventInputs != nullptr)
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
for (uint8_t c=0; c<MAX_MIDI_CHANNELS; ++c)
{
v3_param_id paramId;
if (fMidiControllerAssignments.get(0, c, MIDI_CONTROL_ALL_NOTES_OFF, paramId))
{
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i)
{
if (static_cast<v3_param_id>(pData->param.data[i].rindex) == paramId)
{
index = i;
break;
}
}

if (index == UINT32_MAX)
break;

fEvents.paramInputs->setParamValueRT(index, 0, 0.f);
}
}
}
else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS && fEvents.eventInputs != nullptr)
{ {
fEvents.eventInputs->numEvents = MAX_MIDI_NOTE; fEvents.eventInputs->numEvents = MAX_MIDI_NOTE;


@@ -2588,6 +2595,9 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Event Input (System) // Event Input (System)


#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
bool allNotesOffSent = false;
#endif
bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;


uint32_t startTime = 0; uint32_t startTime = 0;
@@ -2718,13 +2728,10 @@ public:


if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE) if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
{ {
v3_param_id paramId = 0;
if (v3_cpp_obj(fV3.midiMapping)->get_midi_controller_assignment(fV3.midiMapping,
0,
event.channel,
ctrlEvent.param,
&paramId) == V3_OK)
v3_param_id paramId;
if (fMidiControllerAssignments.get(0, event.channel, ctrlEvent.param, paramId))
{ {
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX; uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i) for (uint32_t i=0; i < pData->param.count; ++i)
{ {
@@ -2764,8 +2771,61 @@ public:
break; break;


case kEngineControlEventTypeAllSoundOff: case kEngineControlEventTypeAllSoundOff:
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
v3_param_id paramId;
if (fMidiControllerAssignments.get(0, event.channel, MIDI_CONTROL_ALL_SOUND_OFF, paramId))
{
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i)
{
if (static_cast<v3_param_id>(pData->param.data[i].rindex) == paramId)
{
index = i;
break;
}
}

if (index == UINT32_MAX)
break;

fEvents.paramInputs->setParamValueRT(index, event.time, 0.f);
}
}
break;

case kEngineControlEventTypeAllNotesOff: case kEngineControlEventTypeAllNotesOff:
// TODO map to CC
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
postponeRtAllNotesOff();
}
#endif

v3_param_id paramId;
if (fMidiControllerAssignments.get(0, event.channel, MIDI_CONTROL_ALL_NOTES_OFF, paramId))
{
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i)
{
if (static_cast<v3_param_id>(pData->param.data[i].rindex) == paramId)
{
index = i;
break;
}
}

if (index == UINT32_MAX)
break;

fEvents.paramInputs->setParamValueRT(index, event.time, 0.f);
}
}
break; break;
} // switch (ctrlEvent.type) } // switch (ctrlEvent.type)
break; break;
@@ -2854,13 +2914,10 @@ public:
const uint8_t control = midiEvent.data[1]; const uint8_t control = midiEvent.data[1];
const uint8_t value = midiEvent.data[2]; const uint8_t value = midiEvent.data[2];


v3_param_id paramId = 0;
if (v3_cpp_obj(fV3.midiMapping)->get_midi_controller_assignment(fV3.midiMapping,
midiEvent.port,
event.channel,
control,
&paramId) == V3_OK)
v3_param_id paramId;
if (fMidiControllerAssignments.get(midiEvent.port, event.channel, control, paramId))
{ {
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX; uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i) for (uint32_t i=0; i < pData->param.count; ++i)
{ {
@@ -2885,13 +2942,10 @@ public:
{ {
const uint8_t pressure = midiEvent.data[1]; const uint8_t pressure = midiEvent.data[1];


v3_param_id paramId = 0;
if (v3_cpp_obj(fV3.midiMapping)->get_midi_controller_assignment(fV3.midiMapping,
midiEvent.port,
event.channel,
128,
&paramId) == V3_OK)
v3_param_id paramId;
if (fMidiControllerAssignments.get(midiEvent.port, event.channel, 128, paramId))
{ {
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX; uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i) for (uint32_t i=0; i < pData->param.count; ++i)
{ {
@@ -2916,13 +2970,10 @@ public:
{ {
const uint16_t pitchbend = (midiEvent.data[2] << 7) | midiEvent.data[1]; const uint16_t pitchbend = (midiEvent.data[2] << 7) | midiEvent.data[1];


v3_param_id paramId = 0;
if (v3_cpp_obj(fV3.midiMapping)->get_midi_controller_assignment(fV3.midiMapping,
midiEvent.port,
event.channel,
129,
&paramId) == V3_OK)
v3_param_id paramId;
if (fMidiControllerAssignments.get(midiEvent.port, event.channel, 129, paramId))
{ {
// TODO create mapping between paramId -> index
uint32_t index = UINT32_MAX; uint32_t index = UINT32_MAX;
for (uint32_t i=0; i < pData->param.count; ++i) for (uint32_t i=0; i < pData->param.count; ++i)
{ {
@@ -3407,7 +3458,7 @@ public:
binaryfilename += ".so"; binaryfilename += ".so";
#endif #endif


if (! water::File(binaryfilename).existsAsFile())
if (! water::File(binaryfilename.toRawUTF8()).existsAsFile())
{ {
pData->engine->setLastError("Failed to find a suitable VST3 bundle binary"); pData->engine->setLastError("Failed to find a suitable VST3 bundle binary");
return false; return false;
@@ -3544,10 +3595,8 @@ public:
pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND)) if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
pData->options |= PLUGIN_OPTION_SEND_PITCHBEND; pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
/* TODO
if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF)) if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
*/
if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES)) if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES; pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
} }
@@ -4133,6 +4182,80 @@ private:
CARLA_DECLARE_NON_COPYABLE(Events) CARLA_DECLARE_NON_COPYABLE(Events)
} fEvents; } fEvents;


struct MidiControllerAssignments {
v3_param_id* mappings;
bool* used;

MidiControllerAssignments() noexcept
: mappings(nullptr),
used(nullptr) {}

~MidiControllerAssignments() noexcept
{
clear();
}

void init(v3_midi_mapping** const midiMapping, const uint32_t numPorts)
{
clear();

if (numPorts == 0)
return;

const uint32_t dataPoints = numPorts * MAX_MIDI_CHANNELS * 130;

mappings = new v3_param_id[dataPoints];
used = new bool[dataPoints];

carla_zeroStructs(mappings, dataPoints);
carla_zeroStructs(used, dataPoints);

v3_param_id paramId;
for (uint32_t p=0; p<numPorts; ++p)
{
for (uint8_t ch=0; ch<MAX_MIDI_CHANNELS; ++ch)
{
for (uint16_t cc=0; cc<130; ++cc)
{
if (v3_cpp_obj(midiMapping)->get_midi_controller_assignment(midiMapping, p,
ch, cc, &paramId) == V3_OK)
{
const uint32_t index = p * (130 + MAX_MIDI_CHANNELS) + cc * MAX_MIDI_CHANNELS + ch;
mappings[index] = paramId;
used[index] = true;
}
}
}
}
}

void clear() noexcept
{
delete[] mappings;
delete[] used;
mappings = nullptr;
used = nullptr;
}

bool get(const uint8_t port, const uint8_t channel, const uint8_t cc, v3_param_id& paramId) noexcept
{
CARLA_SAFE_ASSERT_UINT_RETURN(channel < MAX_MIDI_CHANNELS, channel, false);
CARLA_SAFE_ASSERT_UINT_RETURN(cc < 130, cc, false);

if (used == nullptr)
return false;

const uint32_t index = port * (130 + MAX_MIDI_CHANNELS) + cc * MAX_MIDI_CHANNELS + channel;
if (used[index])
{
paramId = mappings[index];
return true;
}

return false;
}
} fMidiControllerAssignments;

#ifdef V3_VIEW_PLATFORM_TYPE_NATIVE #ifdef V3_VIEW_PLATFORM_TYPE_NATIVE
struct UI { struct UI {
bool isAttached; bool isAttached;
@@ -4180,11 +4303,6 @@ CarlaPluginPtr CarlaPlugin::newVST3(const Initializer& init)
carla_debug("CarlaPlugin::newVST3({%p, \"%s\", \"%s\", \"%s\"})", carla_debug("CarlaPlugin::newVST3({%p, \"%s\", \"%s\", \"%s\"})",
init.engine, init.filename, init.name, init.label); init.engine, init.filename, init.name, init.label);


#ifdef USE_JUCE_FOR_VST3
if (std::getenv("CARLA_DO_NOT_USE_JUCE_FOR_VST3") == nullptr)
return newJuce(init, "VST3");
#endif

std::shared_ptr<CarlaPluginVST3> plugin(new CarlaPluginVST3(init.engine, init.id)); std::shared_ptr<CarlaPluginVST3> plugin(new CarlaPluginVST3(init.engine, init.id));


if (! plugin->init(plugin, init.filename, init.name, init.label, init.options)) if (! plugin->init(plugin, init.filename, init.name, init.label, init.options))


+ 4
- 33
source/backend/plugin/Makefile View File

@@ -7,13 +7,6 @@
CWD=../.. CWD=../..
include ../Makefile.mk include ../Makefile.mk


# Workaround GCC bug
ifeq ($(TESTBUILD),true)
ifeq ($(USING_JUCE),true)
BUILD_CXX_FLAGS += -Wno-undef
endif
endif

BUILD_CXX_FLAGS += $(MAGIC_FLAGS) BUILD_CXX_FLAGS += $(MAGIC_FLAGS)


ifneq ($(HAIKU),true) ifneq ($(HAIKU),true)
@@ -35,7 +28,6 @@ OBJS = \
$(OBJDIR)/CarlaPluginVST3.cpp.o \ $(OBJDIR)/CarlaPluginVST3.cpp.o \
$(OBJDIR)/CarlaPluginAU.cpp.o \ $(OBJDIR)/CarlaPluginAU.cpp.o \
$(OBJDIR)/CarlaPluginJSFX.cpp.o \ $(OBJDIR)/CarlaPluginJSFX.cpp.o \
$(OBJDIR)/CarlaPluginJuce.cpp.o \
$(OBJDIR)/CarlaPluginFluidSynth.cpp.o \ $(OBJDIR)/CarlaPluginFluidSynth.cpp.o \
$(OBJDIR)/CarlaPluginSFZero.cpp.o $(OBJDIR)/CarlaPluginSFZero.cpp.o


@@ -83,34 +75,13 @@ $(OBJDIR)/CarlaPluginJSFX.cpp.o: CarlaPluginJSFX.cpp
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(YSFX_FLAGS) -c -o $@ $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(YSFX_FLAGS) -c -o $@


ifeq ($(MACOS),true) ifeq ($(MACOS),true)
$(OBJDIR)/CarlaPluginVST2.cpp.o: CarlaPluginVST2.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@
$(OBJDIR)/CarlaPluginAU.cpp.o: BUILD_CXX_FLAGS += -ObjC++


$(OBJDIR)/CarlaPluginVST3.cpp.o: CarlaPluginVST3.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@
$(OBJDIR)/CarlaPluginCLAP.cpp.o: BUILD_CXX_FLAGS += -ObjC++


$(OBJDIR)/CarlaPluginCLAP.cpp.o: CarlaPluginCLAP.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@
endif
$(OBJDIR)/CarlaPluginVST2.cpp.o: BUILD_CXX_FLAGS += -ObjC++


ifeq ($(USING_JUCE),true)
ifeq ($(MACOS),true)
$(OBJDIR)/CarlaPluginJuce.cpp.o: CarlaPluginJuce.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -std=gnu++14 -c -o $@
else
$(OBJDIR)/CarlaPluginJuce.cpp.o: CarlaPluginJuce.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -std=gnu++14 -c -o $@
endif
$(OBJDIR)/CarlaPluginVST3.cpp.o: BUILD_CXX_FLAGS += -ObjC++
endif endif


$(OBJDIR)/%.cpp.o: %.cpp $(OBJDIR)/%.cpp.o: %.cpp


+ 11
- 103
source/backend/utils/CachedPlugins.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaUtils.h" #include "CarlaUtils.h"


@@ -22,11 +8,6 @@
#include "CarlaBackendUtils.hpp" #include "CarlaBackendUtils.hpp"
#include "CarlaLv2Utils.hpp" #include "CarlaLv2Utils.hpp"


#if defined(USING_JUCE) && defined(CARLA_OS_MAC)
# include "AppConfig.h"
# include "juce_audio_processors/juce_audio_processors.h"
#endif

#ifndef STATIC_PLUGIN_TARGET #ifndef STATIC_PLUGIN_TARGET
# define HAVE_SFZ # define HAVE_SFZ
# include "water/containers/Array.h" # include "water/containers/Array.h"
@@ -98,7 +79,7 @@ static void findSFZs(const char* const sfzPaths)
{ {
std::vector<water::File> results; std::vector<water::File> results;


if (water::File(*it).findChildFiles(results, water::File::findFiles|water::File::ignoreHiddenFiles, true, "*.sfz") > 0)
if (water::File(it->toRawUTF8()).findChildFiles(results, water::File::findFiles|water::File::ignoreHiddenFiles, true, "*.sfz") > 0)
{ {
gSFZs.reserve(gSFZs.size() + results.size()); gSFZs.reserve(gSFZs.size() + results.size());
gSFZs.insert(gSFZs.end(), results.begin(), results.end()); gSFZs.insert(gSFZs.end(), results.begin(), results.end());
@@ -126,7 +107,7 @@ static void findJSFXs(const char* const jsfxPaths)
for (water::String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) for (water::String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
{ {
std::vector<water::File> results; std::vector<water::File> results;
const water::File path(*it);
const water::File path(it->toRawUTF8());


if (path.findChildFiles(results, water::File::findFiles|water::File::ignoreHiddenFiles, true, "*") > 0) if (path.findChildFiles(results, water::File::findFiles|water::File::ignoreHiddenFiles, true, "*") > 0)
{ {
@@ -603,67 +584,6 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl


// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------


#if defined(USING_JUCE) && defined(CARLA_OS_MAC)
static juce::StringArray gCachedAuPluginResults;

static void findAUs()
{
if (gCachedAuPluginResults.size() != 0)
return;

juce::AudioUnitPluginFormat auFormat;
gCachedAuPluginResults = auFormat.searchPathsForPlugins(juce::FileSearchPath(), false, false);
}

static const CarlaCachedPluginInfo* get_cached_plugin_au(const juce::String pluginId)
{
static CarlaCachedPluginInfo info;
static CarlaString sname, slabel, smaker;

info.valid = false;

juce::AudioUnitPluginFormat auFormat;
juce::OwnedArray<juce::PluginDescription> results;
auFormat.findAllTypesForFile(results, pluginId);
CARLA_SAFE_ASSERT_RETURN(results.size() > 0, &info);
CARLA_SAFE_ASSERT(results.size() == 1);

juce::PluginDescription* const desc(results[0]);
CARLA_SAFE_ASSERT_RETURN(desc != nullptr, &info);

info.category = CB::getPluginCategoryFromName(desc->category.toRawUTF8());
info.hints = 0x0;
info.valid = true;

if (desc->isInstrument)
info.hints |= CB::PLUGIN_IS_SYNTH;
if (true)
info.hints |= CB::PLUGIN_HAS_CUSTOM_UI;

info.audioIns = static_cast<uint32_t>(desc->numInputChannels);
info.audioOuts = static_cast<uint32_t>(desc->numOutputChannels);
info.cvIns = 0;
info.cvOuts = 0;
info.midiIns = desc->isInstrument ? 1 : 0;
info.midiOuts = 0;
info.parameterIns = 0;
info.parameterOuts = 0;

sname = desc->name.toRawUTF8();
slabel = desc->fileOrIdentifier.toRawUTF8();
smaker = desc->manufacturerName.toRawUTF8();

info.name = sname;
info.label = slabel;
info.maker = smaker;
info.copyright = gCachedPluginsNullCharPtr;

return &info;
}
#endif

// -------------------------------------------------------------------------------------------------------------------

#ifdef HAVE_SFZ #ifdef HAVE_SFZ
static const CarlaCachedPluginInfo* get_cached_plugin_sfz(const water::File& file) static const CarlaCachedPluginInfo* get_cached_plugin_sfz(const water::File& file)
{ {
@@ -707,17 +627,17 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CB::CarlaJsfxUn


ysfx_config_u config(ysfx_config_new()); ysfx_config_u config(ysfx_config_new());


const water::String rootPath = unit.getRootPath();
const water::String filePath = unit.getFilePath();
const CarlaString rootPath = unit.getRootPath();
const CarlaString filePath = unit.getFilePath();


ysfx_register_builtin_audio_formats(config.get()); ysfx_register_builtin_audio_formats(config.get());
ysfx_set_import_root(config.get(), rootPath.toRawUTF8());
ysfx_guess_file_roots(config.get(), filePath.toRawUTF8());
ysfx_set_import_root(config.get(), rootPath);
ysfx_guess_file_roots(config.get(), filePath);
ysfx_set_log_reporter(config.get(), &CB::CarlaJsfxLogging::logErrorsOnly); ysfx_set_log_reporter(config.get(), &CB::CarlaJsfxLogging::logErrorsOnly);


ysfx_u effect(ysfx_new(config.get())); ysfx_u effect(ysfx_new(config.get()));


if (! ysfx_load_file(effect.get(), filePath.toRawUTF8(), 0))
if (! ysfx_load_file(effect.get(), filePath, 0))
{ {
info.valid = false; info.valid = false;
return &info; return &info;
@@ -734,11 +654,11 @@ static const CarlaCachedPluginInfo* get_cached_plugin_jsfx(const CB::CarlaJsfxUn
} }


static CarlaString name, label, maker; static CarlaString name, label, maker;
label = unit.getFileId().toRawUTF8();
label = unit.getFileId();
name = ysfx_get_name(effect.get()); name = ysfx_get_name(effect.get());
maker = ysfx_get_author(effect.get()); maker = ysfx_get_author(effect.get());


info.valid = true;
info.valid = true;


info.category = CB::CarlaJsfxCategories::getFromEffect(effect.get()); info.category = CB::CarlaJsfxCategories::getFromEffect(effect.get());


@@ -796,12 +716,6 @@ uint carla_get_cached_plugin_count(CB::PluginType ptype, const char* pluginPath)
return lv2World.getPluginCount(); return lv2World.getPluginCount();
} }


#if defined(USING_JUCE) && defined(CARLA_OS_MAC)
case CB::PLUGIN_AU:
findAUs();
return static_cast<uint>(gCachedAuPluginResults.size());
#endif

#ifdef HAVE_SFZ #ifdef HAVE_SFZ
case CB::PLUGIN_SFZ: case CB::PLUGIN_SFZ:
findSFZs(pluginPath); findSFZs(pluginPath);
@@ -847,12 +761,6 @@ const CarlaCachedPluginInfo* carla_get_cached_plugin_info(CB::PluginType ptype,
return get_cached_plugin_lv2(lv2World, lilvPlugin); return get_cached_plugin_lv2(lv2World, lilvPlugin);
} }


#if defined(USING_JUCE) && defined(CARLA_OS_MAC)
case CB::PLUGIN_AU:
CARLA_SAFE_ASSERT_BREAK(index < static_cast<uint>(gCachedAuPluginResults.size()));
return get_cached_plugin_au(gCachedAuPluginResults.strings.getUnchecked(static_cast<int>(index)));
#endif

#ifdef HAVE_SFZ #ifdef HAVE_SFZ
case CB::PLUGIN_SFZ: case CB::PLUGIN_SFZ:
CARLA_SAFE_ASSERT_BREAK(index < gSFZs.size()); CARLA_SAFE_ASSERT_BREAK(index < gSFZs.size());


+ 4
- 55
source/backend/utils/Information.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaUtils.h" #include "CarlaUtils.h"
#include "CarlaString.hpp" #include "CarlaString.hpp"
@@ -31,10 +17,6 @@
# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif #endif


#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
# include "carla_juce/carla_juce.h"
#endif

#ifdef USING_RTAUDIO #ifdef USING_RTAUDIO
# include "rtaudio/RtAudio.h" # include "rtaudio/RtAudio.h"
# include "rtmidi/RtMidi.h" # include "rtmidi/RtMidi.h"
@@ -64,18 +46,10 @@ const char* carla_get_complete_license_text()
"<li>LADSPA plugin support</li>" "<li>LADSPA plugin support</li>"
"<li>DSSI plugin support</li>" "<li>DSSI plugin support</li>"
"<li>LV2 plugin support</li>" "<li>LV2 plugin support</li>"
#if defined(USING_JUCE) && JUCE_PLUGINHOST_VST
"<li>VST2 plugin support (using JUCE)</li>"
#else
"<li>VST2 plugin support (using VeSTige header by Javier Serrano Polo)</li>" "<li>VST2 plugin support (using VeSTige header by Javier Serrano Polo)</li>"
#endif
#if defined(USING_JUCE) && JUCE_PLUGINHOST_VST3
"<li>VST3 plugin support (using JUCE)</li>"
#else
"<li>VST3 plugin support (using Travesty header files)</li>" "<li>VST3 plugin support (using Travesty header files)</li>"
#endif
#if defined(USING_JUCE) && JUCE_PLUGINHOST_AU
"<li>AU plugin support (using JUCE)</li>"
#ifdef CARLA_OS_MAC
"<li>AU plugin support (discovery only)</li>"
#endif #endif
#ifdef HAVE_YSFX #ifdef HAVE_YSFX
"<li>JSFX plugin support (using ysfx)</li>" "<li>JSFX plugin support (using ysfx)</li>"
@@ -122,25 +96,6 @@ const char* carla_get_complete_license_text()
return retText; return retText;
} }


const char* carla_get_juce_version()
{
carla_debug("carla_get_juce_version()");

static CarlaString retVersion;

#if defined(USING_JUCE) && !defined(BUILD_BRIDGE)
if (retVersion.isEmpty())
{
if (const char* const version = CarlaJUCE::getVersion())
retVersion = version+6;
else
retVersion = "Unknown";
}
#endif

return retVersion;
}

const char* const* carla_get_supported_file_extensions() const char* const* carla_get_supported_file_extensions()
{ {
carla_debug("carla_get_supported_file_extensions()"); carla_debug("carla_get_supported_file_extensions()");
@@ -229,12 +184,6 @@ const char* const* carla_get_supported_features()
#ifdef HAVE_YSFX #ifdef HAVE_YSFX
"jsfx", "jsfx",
#endif #endif
#ifdef USING_JUCE
"juce",
#if defined(CARLA_OS_MAC)
"au",
#endif
#endif
nullptr nullptr
}; };




+ 0
- 47
source/backend/utils/JUCE.cpp View File

@@ -1,47 +0,0 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaUtils.h"

#ifdef USING_JUCE
# include "carla_juce/carla_juce.h"
#endif

// -------------------------------------------------------------------------------------------------------------------

void carla_juce_init()
{
#ifdef USING_JUCE
CarlaJUCE::initialiseJuce_GUI();
#endif
}

void carla_juce_idle()
{
#ifdef USING_JUCE
CarlaJUCE::idleJuce_GUI();
#endif
}

void carla_juce_cleanup()
{
#ifdef USING_JUCE
CarlaJUCE::shutdownJuce_GUI();
#endif
}

// -------------------------------------------------------------------------------------------------------------------

+ 3
- 28
source/backend/utils/Makefile View File

@@ -10,7 +10,7 @@ include ../Makefile.mk
# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


BUILD_CXX_FLAGS += $(FLUIDSYNTH_FLAGS) BUILD_CXX_FLAGS += $(FLUIDSYNTH_FLAGS)
BUILD_CXX_FLAGS += $(MAGIC_LIBS)
BUILD_CXX_FLAGS += $(MAGIC_FLAGS)
BUILD_CXX_FLAGS += $(YSFX_FLAGS) BUILD_CXX_FLAGS += $(YSFX_FLAGS)


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
@@ -19,7 +19,6 @@ OBJS = \
$(OBJDIR)/CachedPlugins.cpp.o \ $(OBJDIR)/CachedPlugins.cpp.o \
$(OBJDIR)/CarlaUtils.cpp.o \ $(OBJDIR)/CarlaUtils.cpp.o \
$(OBJDIR)/Information.cpp.o \ $(OBJDIR)/Information.cpp.o \
$(OBJDIR)/JUCE.cpp.o \
$(OBJDIR)/PipeClient.cpp.o \ $(OBJDIR)/PipeClient.cpp.o \
$(OBJDIR)/PluginDiscovery.cpp.o \ $(OBJDIR)/PluginDiscovery.cpp.o \
$(OBJDIR)/System.cpp.o \ $(OBJDIR)/System.cpp.o \
@@ -37,20 +36,9 @@ ifeq ($(HAVE_YSFX),true)
LIBS += $(MODULEDIR)/ysfx.a LIBS += $(MODULEDIR)/ysfx.a
endif endif


ifeq ($(USING_JUCE),true)
LIBS += $(MODULEDIR)/carla_juce.a
LIBS += $(MODULEDIR)/juce_audio_basics.a
LIBS += $(MODULEDIR)/juce_audio_processors.a
LIBS += $(MODULEDIR)/juce_core.a
LIBS += $(MODULEDIR)/juce_data_structures.a
LIBS += $(MODULEDIR)/juce_events.a
LIBS += $(MODULEDIR)/juce_graphics.a
LIBS += $(MODULEDIR)/juce_gui_basics.a
LIBS += $(MODULEDIR)/juce_gui_extra.a
endif

LINK_FLAGS += $(JACKBRIDGE_LIBS) LINK_FLAGS += $(JACKBRIDGE_LIBS)
LINK_FLAGS += $(LILV_LIBS) LINK_FLAGS += $(LILV_LIBS)
LINK_FLAGS += $(MAGIC_LIBS)
LINK_FLAGS += $(WATER_LIBS) LINK_FLAGS += $(WATER_LIBS)


ifeq ($(HAVE_X11),true) ifeq ($(HAVE_X11),true)
@@ -67,17 +55,6 @@ LINK_FLAGS += -pthread
endif endif
endif endif


ifeq ($(USING_JUCE),true)
LINK_FLAGS += $(JUCE_AUDIO_BASICS_LIBS)
LINK_FLAGS += $(JUCE_AUDIO_PROCESSORS_LIBS)
LINK_FLAGS += $(JUCE_CORE_LIBS)
LINK_FLAGS += $(JUCE_DATA_STRUCTURES_LIBS)
LINK_FLAGS += $(JUCE_EVENTS_LIBS)
LINK_FLAGS += $(JUCE_GRAPHICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_BASICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_EXTRA_LIBS)
endif

# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


all: $(TARGETS) all: $(TARGETS)
@@ -100,12 +77,10 @@ $(BINDIR)/libcarla_utils$(LIB_EXT): $(OBJS) $(LIBS)
# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


ifeq ($(MACOS),true) ifeq ($(MACOS),true)
ifeq ($(USING_JUCE),true)
$(OBJDIR)/CachedPlugins.cpp.o: BUILD_CXX_FLAGS += -std=gnu++14
endif
$(OBJDIR)/CarlaUtils.cpp.o: BUILD_CXX_FLAGS += -ObjC++ $(OBJDIR)/CarlaUtils.cpp.o: BUILD_CXX_FLAGS += -ObjC++


$(OBJDIR)/Windows.cpp.o: BUILD_CXX_FLAGS += -ObjC++ $(OBJDIR)/Windows.cpp.o: BUILD_CXX_FLAGS += -ObjC++

endif endif


$(OBJDIR)/%.cpp.o: %.cpp $(OBJDIR)/%.cpp.o: %.cpp


+ 105
- 30
source/backend/utils/PluginDiscovery.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#include "CarlaUtils.h" #include "CarlaUtils.h"


@@ -41,7 +27,7 @@ static water::String findWinePrefix(const water::String filename, const int recu


const water::String path(filename.upToLastOccurrenceOf("/", false, false)); const water::String path(filename.upToLastOccurrenceOf("/", false, false));


if (water::File(path + "/dosdevices").isDirectory())
if (water::File(water::String(path + "/dosdevices").toRawUTF8()).isDirectory())
return path; return path;


return findWinePrefix(path, recursionLimit-1); return findWinePrefix(path, recursionLimit-1);
@@ -111,6 +97,7 @@ public:
fDiscoveryCallback(discoveryCb), fDiscoveryCallback(discoveryCb),
fCheckCacheCallback(checkCacheCb), fCheckCacheCallback(checkCacheCb),
fCallbackPtr(callbackPtr), fCallbackPtr(callbackPtr),
fPluginPath(nullptr),
fPluginsFoundInBinary(false), fPluginsFoundInBinary(false),
fBinaryIndex(0), fBinaryIndex(0),
fBinaryCount(static_cast<uint>(binaries.size())), fBinaryCount(static_cast<uint>(binaries.size())),
@@ -129,12 +116,14 @@ public:
const PluginType ptype, const PluginType ptype,
const CarlaPluginDiscoveryCallback discoveryCb, const CarlaPluginDiscoveryCallback discoveryCb,
const CarlaPluginCheckCacheCallback checkCacheCb, const CarlaPluginCheckCacheCallback checkCacheCb,
void* const callbackPtr)
void* const callbackPtr,
const char* const pluginPath = nullptr)
: fBinaryType(btype), : fBinaryType(btype),
fPluginType(ptype), fPluginType(ptype),
fDiscoveryCallback(discoveryCb), fDiscoveryCallback(discoveryCb),
fCheckCacheCallback(checkCacheCb), fCheckCacheCallback(checkCacheCb),
fCallbackPtr(callbackPtr), fCallbackPtr(callbackPtr),
fPluginPath(pluginPath != nullptr ? carla_strdup_safe(pluginPath) : nullptr),
fPluginsFoundInBinary(false), fPluginsFoundInBinary(false),
fBinaryIndex(0), fBinaryIndex(0),
fBinaryCount(1), fBinaryCount(1),
@@ -153,6 +142,7 @@ public:
std::free(fNextLabel); std::free(fNextLabel);
std::free(fNextMaker); std::free(fNextMaker);
std::free(fNextName); std::free(fNextName);
delete[] fPluginPath;
} }


bool idle() bool idle()
@@ -385,6 +375,7 @@ private:
const CarlaPluginDiscoveryCallback fDiscoveryCallback; const CarlaPluginDiscoveryCallback fDiscoveryCallback;
const CarlaPluginCheckCacheCallback fCheckCacheCallback; const CarlaPluginCheckCacheCallback fCheckCacheCallback;
void* const fCallbackPtr; void* const fCallbackPtr;
const char* fPluginPath;


bool fPluginsFoundInBinary; bool fPluginsFoundInBinary;
uint fBinaryIndex; uint fBinaryIndex;
@@ -428,7 +419,7 @@ private:
{ {
helperTool = options.wine.executable.buffer(); helperTool = options.wine.executable.buffer();


if (helperTool[0] == CARLA_OS_SEP && File(helperTool + "64").existsAsFile())
if (helperTool.isNotEmpty() && helperTool[0] == CARLA_OS_SEP && File(String(helperTool + "64").toRawUTF8()).existsAsFile())
helperTool += "64"; helperTool += "64";
} }
else else
@@ -457,7 +448,7 @@ private:


if (envWinePrefix != nullptr && envWinePrefix[0] != '\0') if (envWinePrefix != nullptr && envWinePrefix[0] != '\0')
winePrefix = envWinePrefix; winePrefix = envWinePrefix;
else if (options.wine.fallbackPrefix != nullptr && options.wine.fallbackPrefix[0] != '\0')
else if (options.wine.fallbackPrefix.isNotEmpty())
winePrefix = options.wine.fallbackPrefix.buffer(); winePrefix = options.wine.fallbackPrefix.buffer();
else else
winePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine"; winePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine";
@@ -467,14 +458,76 @@ private:
const CarlaScopedEnvVar sev2("WINEPREFIX", winePrefix.toRawUTF8()); const CarlaScopedEnvVar sev2("WINEPREFIX", winePrefix.toRawUTF8());
#endif #endif


const CarlaScopedEnvVar sev3("CARLA_DISCOVERY_NO_PROCESSING_CHECKS", "1");

if (fBinaries.empty()) if (fBinaries.empty())
{ {
if (fBinaryType == CB::BINARY_NATIVE)
{
switch (fPluginType)
{
default:
break;
case CB::PLUGIN_INTERNAL:
case CB::PLUGIN_LV2:
case CB::PLUGIN_JSFX:
case CB::PLUGIN_SFZ:
if (const uint count = carla_get_cached_plugin_count(fPluginType, fPluginPath))
{
for (uint i=0; i<count; ++i)
{
const CarlaCachedPluginInfo* const pinfo = carla_get_cached_plugin_info(fPluginType, i);

if (pinfo == nullptr || !pinfo->valid)
continue;

char* filename = nullptr;
CarlaPluginDiscoveryInfo info = {};
info.btype = CB::BINARY_NATIVE;
info.ptype = fPluginType;
info.metadata.name = pinfo->name;
info.metadata.maker = pinfo->maker;
info.metadata.category = pinfo->category;
info.metadata.hints = pinfo->hints;
info.io.audioIns = pinfo->audioIns;
info.io.audioOuts = pinfo->audioOuts;
info.io.cvIns = pinfo->cvIns;
info.io.cvOuts = pinfo->cvOuts;
info.io.midiIns = pinfo->midiIns;
info.io.midiOuts = pinfo->midiOuts;
info.io.parameterIns = pinfo->parameterIns;
info.io.parameterOuts = pinfo->parameterOuts;

if (fPluginType == CB::PLUGIN_LV2)
{
const char* const slash = std::strchr(pinfo->label, CARLA_OS_SEP);
CARLA_SAFE_ASSERT_BREAK(slash != nullptr);
filename = strdup(pinfo->label);
filename[slash - pinfo->label] = '\0';
info.filename = filename;
info.label = slash + 1;
}
else
{
info.filename = gPluginsDiscoveryNullCharPtr;
info.label = pinfo->label;
}

fDiscoveryCallback(fCallbackPtr, &info, nullptr);

std::free(filename);
}
}
return;
}
}

#ifndef CARLA_OS_WIN #ifndef CARLA_OS_WIN
if (helperTool.isNotEmpty()) if (helperTool.isNotEmpty())
startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all");
startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all", -1, 2000);
else else
#endif #endif
startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all");
startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all", -1, 2000);
} }
else else
{ {
@@ -497,10 +550,10 @@ private:


#ifndef CARLA_OS_WIN #ifndef CARLA_OS_WIN
if (helperTool.isNotEmpty()) if (helperTool.isNotEmpty())
startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8());
startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8(), -1, 2000);
else else
#endif #endif
startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8());
startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8(), -1, 2000);
} }
} }


@@ -553,7 +606,7 @@ static bool findDirectories(std::vector<water::File>& files, const char* const p


for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
{ {
const File dir(*it);
const File dir(it->toRawUTF8());
std::vector<File> results; std::vector<File> results;


if (dir.findChildFiles(results, File::findDirectories|File::ignoreHiddenFiles, true, wildcard) > 0) if (dir.findChildFiles(results, File::findDirectories|File::ignoreHiddenFiles, true, wildcard) > 0)
@@ -585,7 +638,7 @@ static bool findFiles(std::vector<water::File>& files,


for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
{ {
const File dir(*it);
const File dir(it->toRawUTF8());
std::vector<File> results; std::vector<File> results;


if (dir.findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard) > 0) if (dir.findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard) > 0)
@@ -628,7 +681,7 @@ static bool findVST3s(std::vector<water::File>& files,


for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it) for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
{ {
const File dir(*it);
const File dir(it->toRawUTF8());
std::vector<File> results; std::vector<File> results;


if (dir.findChildFiles(results, flags|File::ignoreHiddenFiles, true, "*.vst3") > 0) if (dir.findChildFiles(results, flags|File::ignoreHiddenFiles, true, "*.vst3") > 0)
@@ -660,10 +713,28 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov
CARLA_SAFE_ASSERT_RETURN(ptype != CB::PLUGIN_NONE, nullptr); CARLA_SAFE_ASSERT_RETURN(ptype != CB::PLUGIN_NONE, nullptr);
CARLA_SAFE_ASSERT_RETURN(discoveryTool != nullptr && discoveryTool[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(discoveryTool != nullptr && discoveryTool[0] != '\0', nullptr);
CARLA_SAFE_ASSERT_RETURN(discoveryCb != nullptr, nullptr); CARLA_SAFE_ASSERT_RETURN(discoveryCb != nullptr, nullptr);
carla_debug("carla_plugin_discovery_start(%s, %d:%s, %d:%s, %s, %p, %p, %p)",
discoveryTool, btype, BinaryType2Str(btype), ptype, PluginType2Str(ptype), pluginPath,
discoveryCb, checkCacheCb, callbackPtr);


bool directories = false; bool directories = false;
const char* wildcard = nullptr; const char* wildcard = nullptr;


switch (ptype)
{
case CB::PLUGIN_INTERNAL:
case CB::PLUGIN_LV2:
case CB::PLUGIN_SFZ:
case CB::PLUGIN_JSFX:
case CB::PLUGIN_DLS:
case CB::PLUGIN_GIG:
case CB::PLUGIN_SF2:
CARLA_SAFE_ASSERT_UINT_RETURN(btype == CB::BINARY_NATIVE, btype, nullptr);
break;
default:
break;
}

switch (ptype) switch (ptype)
{ {
case CB::PLUGIN_NONE: case CB::PLUGIN_NONE:
@@ -671,16 +742,15 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov
case CB::PLUGIN_TYPE_COUNT: case CB::PLUGIN_TYPE_COUNT:
return nullptr; return nullptr;


case CB::PLUGIN_LV2:
case CB::PLUGIN_SFZ: case CB::PLUGIN_SFZ:
case CB::PLUGIN_JSFX: case CB::PLUGIN_JSFX:
{ {
const CarlaScopedEnvVar csev("CARLA_DISCOVERY_PATH", pluginPath); const CarlaScopedEnvVar csev("CARLA_DISCOVERY_PATH", pluginPath);
return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr);
return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr, pluginPath);
} }


case CB::PLUGIN_INTERNAL: case CB::PLUGIN_INTERNAL:
case CB::PLUGIN_LV2:
case CB::PLUGIN_AU:
return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr); return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr);


case CB::PLUGIN_LADSPA: case CB::PLUGIN_LADSPA:
@@ -728,6 +798,11 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov
wildcard = "*.vst3"; wildcard = "*.vst3";
break; break;


case CB::PLUGIN_AU:
directories = true;
wildcard = "*.component";
break;

case CB::PLUGIN_CLAP: case CB::PLUGIN_CLAP:
wildcard = "*.clap"; wildcard = "*.clap";
#ifdef CARLA_OS_MAC #ifdef CARLA_OS_MAC


+ 15
- 22
source/bridges-plugin/CarlaBridgePlugin.cpp View File

@@ -1,19 +1,5 @@
/*
* Carla Bridge Plugin
* Copyright (C) 2012-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
# error This file should not be compiled if not building bridge # error This file should not be compiled if not building bridge
@@ -84,6 +70,11 @@ static void saveSignalHandler(int) noexcept
gSaveNow = true; gSaveNow = true;
} }
#elif defined(CARLA_OS_WIN) #elif defined(CARLA_OS_WIN)
static LONG WINAPI winExceptionFilter(_EXCEPTION_POINTERS*)
{
return EXCEPTION_EXECUTE_HANDLER;
}

static BOOL WINAPI winSignalHandler(DWORD dwCtrlType) noexcept static BOOL WINAPI winSignalHandler(DWORD dwCtrlType) noexcept
{ {
if (dwCtrlType == CTRL_C_EVENT) if (dwCtrlType == CTRL_C_EVENT)
@@ -113,13 +104,15 @@ static void initSignalHandler()
sigaction(SIGUSR1, &sig, nullptr); sigaction(SIGUSR1, &sig, nullptr);
#elif defined(CARLA_OS_WIN) #elif defined(CARLA_OS_WIN)
SetConsoleCtrlHandler(winSignalHandler, TRUE); SetConsoleCtrlHandler(winSignalHandler, TRUE);
SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(winExceptionFilter);
#endif #endif
} }


// ------------------------------------------------------------------------- // -------------------------------------------------------------------------


static String gProjectFilename;
static CarlaHostHandle gHostHandle; static CarlaHostHandle gHostHandle;
static CarlaString gProjectFilename;


static void gIdle() static void gIdle()
{ {
@@ -131,7 +124,7 @@ static void gIdle()


if (gProjectFilename.isNotEmpty()) if (gProjectFilename.isNotEmpty())
{ {
if (! carla_save_plugin_state(gHostHandle, 0, gProjectFilename.toRawUTF8()))
if (! carla_save_plugin_state(gHostHandle, 0, gProjectFilename))
carla_stderr("Plugin preset save failed, error was:\n%s", carla_get_last_error(gHostHandle)); carla_stderr("Plugin preset save failed, error was:\n%s", carla_get_last_error(gHostHandle));
} }
} }
@@ -202,15 +195,15 @@ public:
const CarlaPluginInfo* const pInfo = carla_get_plugin_info(gHostHandle, 0); const CarlaPluginInfo* const pInfo = carla_get_plugin_info(gHostHandle, 0);
CARLA_SAFE_ASSERT_RETURN(pInfo != nullptr,); CARLA_SAFE_ASSERT_RETURN(pInfo != nullptr,);


gProjectFilename = CharPointer_UTF8(pInfo->name);
gProjectFilename = pInfo->name;
gProjectFilename += ".carxs"; gProjectFilename += ".carxs";


if (! File::isAbsolutePath(gProjectFilename)) if (! File::isAbsolutePath(gProjectFilename))
gProjectFilename = File::getCurrentWorkingDirectory().getChildFile(gProjectFilename).getFullPathName();
gProjectFilename = File::getCurrentWorkingDirectory().getChildFile(gProjectFilename).getFullPathName().toRawUTF8();


if (File(gProjectFilename).existsAsFile()) if (File(gProjectFilename).existsAsFile())
{ {
if (carla_load_plugin_state(gHostHandle, 0, gProjectFilename.toRawUTF8()))
if (carla_load_plugin_state(gHostHandle, 0, gProjectFilename))
carla_stdout("Plugin state loaded successfully"); carla_stdout("Plugin state loaded successfully");
else else
carla_stderr("Plugin state load failed, error was:\n%s", carla_get_last_error(gHostHandle)); carla_stderr("Plugin state load failed, error was:\n%s", carla_get_last_error(gHostHandle));
@@ -218,7 +211,7 @@ public:
else else
{ {
carla_stdout("Previous plugin state in '%s' is non-existent, will start from default state", carla_stdout("Previous plugin state in '%s' is non-existent, will start from default state",
gProjectFilename.toRawUTF8());
gProjectFilename.buffer());
} }
} }




+ 1
- 12
source/bridges-plugin/CarlaBridgeSingleLV2.cpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla LV2 Single Plugin * Carla LV2 Single Plugin
* Copyright (C) 2017-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2017-2024 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -29,10 +29,6 @@


#include "water/files/File.h" #include "water/files/File.h"


#ifdef USING_JUCE
# include "carla_juce/carla_juce.h"
#endif

template<> template<>
void Lv2PluginBaseClass<CARLA_BACKEND_NAMESPACE::EngineTimeInfo>::clearTimeData() noexcept void Lv2PluginBaseClass<CARLA_BACKEND_NAMESPACE::EngineTimeInfo>::clearTimeData() noexcept
{ {
@@ -53,9 +49,6 @@ public:
const LV2_Feature* const* const features) const LV2_Feature* const* const features)
: Lv2PluginBaseClass<EngineTimeInfo>(sampleRate, features), : Lv2PluginBaseClass<EngineTimeInfo>(sampleRate, features),
fPlugin(nullptr) fPlugin(nullptr)
#ifdef USING_JUCE
, fJuceInitialiser()
#endif
{ {
CARLA_SAFE_ASSERT_RETURN(pData->curPluginCount == 0,) CARLA_SAFE_ASSERT_RETURN(pData->curPluginCount == 0,)
CARLA_SAFE_ASSERT_RETURN(pData->plugins == nullptr,); CARLA_SAFE_ASSERT_RETURN(pData->plugins == nullptr,);
@@ -490,10 +483,6 @@ protected:
private: private:
CarlaPluginPtr fPlugin; CarlaPluginPtr fPlugin;


#ifdef USING_JUCE
CarlaJUCE::ScopedJuceInitialiser_GUI fJuceInitialiser;
#endif

void updateParameterOutputs() noexcept void updateParameterOutputs() noexcept
{ {
float value; float value;


+ 3
- 36
source/bridges-plugin/Makefile View File

@@ -8,15 +8,6 @@ CWD=..
MODULENAME=carla-bridge MODULENAME=carla-bridge
include $(CWD)/Makefile.mk include $(CWD)/Makefile.mk


# Workaround GCC bug
ifeq ($(TESTBUILD),true)
ifeq ($(USING_JUCE),true)
BUILD_CXX_FLAGS += -Wno-undef
# FIXME
BUILD_CXX_FLAGS += -Wno-deprecated-declarations
endif
endif

ifneq ($(HAIKU),true) ifneq ($(HAIKU),true)
ifneq ($(WASM),true) ifneq ($(WASM),true)
BUILD_CXX_FLAGS += -pthread BUILD_CXX_FLAGS += -pthread
@@ -41,7 +32,6 @@ BUILD_CXX_FLAGS += -DBUILD_BRIDGE -I. -I$(CWD) -I$(CWD)/backend -I$(CWD)/include
BUILD_CXX_FLAGS += -I$(CWD)/backend/engine -I$(CWD)/backend/plugin BUILD_CXX_FLAGS += -I$(CWD)/backend/engine -I$(CWD)/backend/plugin


BUILD_CXX_FLAGS += -UHAVE_SDL BUILD_CXX_FLAGS += -UHAVE_SDL
BUILD_CXX_FLAGS += -UUSING_JUCE_AUDIO_DEVICES
BUILD_CXX_FLAGS += -UUSING_RTAUDIO BUILD_CXX_FLAGS += -UUSING_RTAUDIO


32BIT_FLAGS += -DBUILD_BRIDGE_ALTERNATIVE_ARCH 32BIT_FLAGS += -DBUILD_BRIDGE_ALTERNATIVE_ARCH
@@ -92,27 +82,6 @@ LIBS_native += $(MODULEDIR)/ysfx.a
LINK_FLAGS += $(YSFX_GRAPHICS_LIBS) LINK_FLAGS += $(YSFX_GRAPHICS_LIBS)
endif endif


ifeq ($(USING_JUCE),true)
LIBS_native += $(MODULEDIR)/carla_juce.a
LIBS_native += $(MODULEDIR)/juce_audio_basics.a
LIBS_native += $(MODULEDIR)/juce_audio_processors.a
LIBS_native += $(MODULEDIR)/juce_core.a
LIBS_native += $(MODULEDIR)/juce_data_structures.a
LIBS_native += $(MODULEDIR)/juce_events.a
LIBS_native += $(MODULEDIR)/juce_graphics.a
LIBS_native += $(MODULEDIR)/juce_gui_basics.a
LIBS_native += $(MODULEDIR)/juce_gui_extra.a

LINK_FLAGS += $(JUCE_AUDIO_BASICS_LIBS)
LINK_FLAGS += $(JUCE_AUDIO_PROCESSORS_LIBS)
LINK_FLAGS += $(JUCE_CORE_LIBS)
LINK_FLAGS += $(JUCE_DATA_STRUCTURES_LIBS)
LINK_FLAGS += $(JUCE_EVENTS_LIBS)
LINK_FLAGS += $(JUCE_GRAPHICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_BASICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_EXTRA_LIBS)
endif

ifeq ($(JACKBRIDGE_DIRECT),true) ifeq ($(JACKBRIDGE_DIRECT),true)
LINK_FLAGS += $(JACK_LIBS) LINK_FLAGS += $(JACK_LIBS)
endif endif
@@ -130,6 +99,7 @@ NATIVE_LINK_FLAGS += $(LIBLO_LIBS)
NATIVE_BUILD_FLAGS += $(FLUIDSYNTH_FLAGS) NATIVE_BUILD_FLAGS += $(FLUIDSYNTH_FLAGS)
NATIVE_LINK_FLAGS += $(FLUIDSYNTH_LIBS) NATIVE_LINK_FLAGS += $(FLUIDSYNTH_LIBS)


NATIVE_BUILD_FLAGS += $(MAGIC_FLAGS)
NATIVE_LINK_FLAGS += $(MAGIC_LIBS) NATIVE_LINK_FLAGS += $(MAGIC_LIBS)


LIBS_native += $(MODULEDIR)/audio_decoder.a LIBS_native += $(MODULEDIR)/audio_decoder.a
@@ -179,7 +149,6 @@ OBJS_native = \
$(OBJDIR)/CarlaPluginVST3.cpp.o \ $(OBJDIR)/CarlaPluginVST3.cpp.o \
$(OBJDIR)/CarlaPluginAU.cpp.o \ $(OBJDIR)/CarlaPluginAU.cpp.o \
$(OBJDIR)/CarlaPluginJSFX.cpp.o \ $(OBJDIR)/CarlaPluginJSFX.cpp.o \
$(OBJDIR)/CarlaPluginJuce.cpp.o \
$(OBJDIR)/CarlaPluginFluidSynth.cpp.o \ $(OBJDIR)/CarlaPluginFluidSynth.cpp.o \
$(OBJDIR)/CarlaPluginSFZero.cpp.o \ $(OBJDIR)/CarlaPluginSFZero.cpp.o \
$(OBJDIR)/CarlaStandalone.cpp.o $(OBJDIR)/CarlaStandalone.cpp.o
@@ -307,12 +276,10 @@ $(OBJDIR)/CarlaEng%.cpp.o: $(CWD)/backend/engine/CarlaEng%.cpp


$(OBJDIR)/CarlaPluginJSFX.cpp.o: BUILD_CXX_FLAGS += $(YSFX_FLAGS) $(OBJDIR)/CarlaPluginJSFX.cpp.o: BUILD_CXX_FLAGS += $(YSFX_FLAGS)


$(OBJDIR)/CarlaPluginJuce.cpp.o: BUILD_CXX_FLAGS += -std=gnu++14

ifeq ($(MACOS),true) ifeq ($(MACOS),true)
$(OBJDIR)/CarlaPluginCLAP.cpp.o: BUILD_CXX_FLAGS += -ObjC++
$(OBJDIR)/CarlaPluginAU.cpp.o: BUILD_CXX_FLAGS += -ObjC++


$(OBJDIR)/CarlaPluginJuce.cpp.o: BUILD_CXX_FLAGS += -ObjC++
$(OBJDIR)/CarlaPluginCLAP.cpp.o: BUILD_CXX_FLAGS += -ObjC++


$(OBJDIR)/CarlaPluginVST2.cpp.o: BUILD_CXX_FLAGS += -ObjC++ $(OBJDIR)/CarlaPluginVST2.cpp.o: BUILD_CXX_FLAGS += -ObjC++




+ 1
- 1
source/carla.kdev4 View File

@@ -3,7 +3,7 @@ Manager=KDevGenericManager
Name=Carla Name=Carla


[Filters] [Filters]
Excludes=*/.*,*/*~,*/*.pyc,*/ui_*.py,*/__pycache__/,external,juce_*
Excludes=*/.*,*/*~,*/*.pyc,*/ui_*.py,*/__pycache__/,external


[Project] [Project]
VersionControlSupport=kdevgit VersionControlSupport=kdevgit

+ 0
- 32
source/discovery/Makefile View File

@@ -8,13 +8,6 @@ CWD=..
MODULENAME=carla-discovery MODULENAME=carla-discovery
include $(CWD)/Makefile.mk include $(CWD)/Makefile.mk


# Workaround GCC bug
ifeq ($(TESTBUILD),true)
ifeq ($(USING_JUCE),true)
BUILD_CXX_FLAGS += -Wno-undef
endif
endif

# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


BINDIR := $(CWD)/../bin BINDIR := $(CWD)/../bin
@@ -46,10 +39,6 @@ BUILD_CXX_FLAGS += -pthread
LINK_FLAGS += -pthread LINK_FLAGS += -pthread
endif endif


ifeq ($(USING_JUCE),true)
BUILD_CXX_FLAGS += -std=gnu++14
endif

32BIT_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH 32BIT_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH
64BIT_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH 64BIT_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH
ARM32_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH ARM32_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_ALTERNATIVE_ARCH
@@ -97,27 +86,6 @@ LIBS_win32 += $(MODULEDIR)/jackbridge.win32e.a
LIBS_win64 += $(MODULEDIR)/jackbridge.win64e.a LIBS_win64 += $(MODULEDIR)/jackbridge.win64e.a
endif endif


ifeq ($(USING_JUCE),true)
LIBS_native += $(MODULEDIR)/carla_juce.a
LIBS_native += $(MODULEDIR)/juce_audio_basics.a
LIBS_native += $(MODULEDIR)/juce_audio_processors.a
LIBS_native += $(MODULEDIR)/juce_core.a
LIBS_native += $(MODULEDIR)/juce_data_structures.a
LIBS_native += $(MODULEDIR)/juce_events.a
LIBS_native += $(MODULEDIR)/juce_graphics.a
LIBS_native += $(MODULEDIR)/juce_gui_basics.a
LIBS_native += $(MODULEDIR)/juce_gui_extra.a

LINK_FLAGS += $(JUCE_AUDIO_BASICS_LIBS)
LINK_FLAGS += $(JUCE_AUDIO_PROCESSORS_LIBS)
LINK_FLAGS += $(JUCE_CORE_LIBS)
LINK_FLAGS += $(JUCE_DATA_STRUCTURES_LIBS)
LINK_FLAGS += $(JUCE_EVENTS_LIBS)
LINK_FLAGS += $(JUCE_GRAPHICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_BASICS_LIBS)
LINK_FLAGS += $(JUCE_GUI_EXTRA_LIBS)
endif # USING_JUCE

# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


OBJS_native = $(OBJDIR)/$(MODULENAME).cpp.o OBJS_native = $(OBJDIR)/$(MODULENAME).cpp.o


+ 488
- 259
source/discovery/carla-discovery.cpp
File diff suppressed because it is too large
View File


+ 6
- 19
source/frontend/CarlaFrontend.h View File

@@ -1,19 +1,5 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/
// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
// SPDX-License-Identifier: GPL-2.0-or-later


#pragma once #pragma once


@@ -61,13 +47,14 @@ typedef struct {
uint parameterOuts; uint parameterOuts;
} PluginListDialogResults; } PluginListDialogResults;


#ifdef __cplusplus
class PluginListDialog;
#else
struct PluginListDialog; struct PluginListDialog;
#endif


// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------


CARLA_PLUGIN_EXPORT void
carla_frontend_createAndExecAboutJuceDialog(void* parent);

CARLA_PLUGIN_EXPORT const JackAppDialogResults* CARLA_PLUGIN_EXPORT const JackAppDialogResults*
carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilename); carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilename);




+ 29
- 30
source/frontend/Makefile View File

@@ -21,7 +21,6 @@ endif
# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


BUILD_CXX_FLAGS += -I. -Iutils BUILD_CXX_FLAGS += -I. -Iutils

BUILD_CXX_FLAGS += -I../backend BUILD_CXX_FLAGS += -I../backend
BUILD_CXX_FLAGS += -I../includes BUILD_CXX_FLAGS += -I../includes
BUILD_CXX_FLAGS += -I../modules BUILD_CXX_FLAGS += -I../modules
@@ -30,34 +29,22 @@ BUILD_CXX_FLAGS += -I../utils
# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


ifeq ($(WINDOWS),true) ifeq ($(WINDOWS),true)
QT5_LINK_FLAGS = $(shell echo $(LINK_FLAGS) | awk 'sub(" -static","")')
NON_STATIC_LINK_FLAGS = $(shell echo $(LINK_FLAGS) | awk 'sub(" -static","")') -static-libgcc
else else
QT5_LINK_FLAGS = $(LINK_FLAGS)
endif

ifeq ($(HAVE_QT5),true)
QT5_PREFIX = $(shell $(PKG_CONFIG) --variable=prefix Qt5Core)
BUILD_CXX_FLAGS += $(shell $(PKG_CONFIG) --cflags Qt5Core Qt5Gui Qt5Widgets)
QT5_LINK_FLAGS += -Wl,-rpath,$(QT5_PREFIX)/lib $(shell $(PKG_CONFIG) --libs Qt5Core Qt5Gui Qt5Widgets)
else ifeq ($(HAVE_QT5PKG),true)
QT5_PREFIX = $(shell $(PKG_CONFIG) --variable=prefix Qt5OpenGLExtensions)
BUILD_CXX_FLAGS += -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -I $(QT5_PREFIX)/include/qt5
QT5_LINK_FLAGS += -Wl,-rpath,$(QT5_PREFIX)/lib -F $(QT5_PREFIX)/lib -framework QtCore -framework QtGui -framework QtWidgets
else
$(error Trying to build frontend without Qt5, cannot continue)
NON_STATIC_LINK_FLAGS = $(LINK_FLAGS)
endif endif


ifeq ($(WINDOWS),true) ifeq ($(WINDOWS),true)
QT5_LINK_FLAGS += -L$(BINDIR) $(BINDIR)/libcarla_utils.dll
QT_LINK_FLAGS += -L$(BINDIR) $(BINDIR)/libcarla_utils.dll
else else
QT5_LINK_FLAGS += -L$(BINDIR) -lcarla_utils
QT_LINK_FLAGS += -L$(BINDIR) -lcarla_utils
endif endif


ifeq ($(MACOS),true) ifeq ($(MACOS),true)
QT5_LINK_FLAGS += -install_name @rpath/libcarla_frontend.dylib
QT_LINK_FLAGS += -install_name @rpath/libcarla_frontend.dylib
# FIXME this does not work: -Wl,-rpath,@loader_path # FIXME this does not work: -Wl,-rpath,@loader_path
else else
QT5_LINK_FLAGS += -Wl,-rpath,'$${ORIGIN}'
QT_LINK_FLAGS += -Wl,-rpath,'$${ORIGIN}'
endif endif


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
@@ -71,7 +58,6 @@ QMs = $(patsubst %,translations/carla_%.qm,$(I18N_LANGUAGES))


CPP_FILES = \ CPP_FILES = \
carla_frontend.cpp \ carla_frontend.cpp \
dialogs/aboutjucedialog.cpp \
dialogs/jackappdialog.cpp \ dialogs/jackappdialog.cpp \
pluginlist/pluginlistdialog.cpp pluginlist/pluginlistdialog.cpp


@@ -81,6 +67,7 @@ OBJS = $(CPP_FILES:%=$(OBJDIR)/%.o)
# Resources # Resources


RES = \ RES = \
qt_config.py \
resources_rc.py \ resources_rc.py \
$(BINDIR)/resources/modgui \ $(BINDIR)/resources/modgui \
$(BINDIR)/resources/patchcanvas \ $(BINDIR)/resources/patchcanvas \
@@ -163,24 +150,37 @@ all: $(BINDIR)/libcarla_frontend$(LIB_EXT) $(QMs) $(RES) $(UIs)


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------


dialogs/ui_%.h: dialogs/%.ui
$(UIC_QT5) $< -o $@
dialogs/ui_%.h: dialogs/%.ui qt_config.py
$(UIC) $< -o $@


pluginlist/ui_%.h: pluginlist/%.ui
$(UIC_QT5) $< -o $@
pluginlist/ui_%.h: pluginlist/%.ui qt_config.py
$(UIC) $< -o $@


%_ui.py: %.ui
%_ui.py: %.ui qt_config.py
$(PYUIC) $< -o $@ $(PYUIC) $< -o $@


ui_%.py: $(RESDIR)/ui/%.ui
ui_%.py: $(RESDIR)/ui/%.ui qt_config.py
$(PYUIC) $< -o $@ $(PYUIC) $< -o $@


qt_config.py:
ifneq (,$(FRONTEND_TYPE))
echo "#!/usr/bin/env python3" > $@
echo "qt = $(FRONTEND_TYPE)" >> $@
else
@echo Error: Trying to build frontend without Qt and/or PyQt, cannot continue
@false
endif

resources_rc.py: $(RESDIR)/resources.qrc $(RESDIR)/*/*.png $(RESDIR)/*/*.svg $(RESDIR)/*/*.svgz resources_rc.py: $(RESDIR)/resources.qrc $(RESDIR)/*/*.png $(RESDIR)/*/*.svg $(RESDIR)/*/*.svgz
ifeq ($(FRONTEND_TYPE),6)
$(PYRCC) $< | sed -e 's/PySide6/PyQt6/' > $@
else
$(PYRCC) $< -o $@ $(PYRCC) $< -o $@
endif


test: $(OBJS) $(LIBS) test.cpp test: $(OBJS) $(LIBS) test.cpp
@echo "Linking test" @echo "Linking test"
$(SILENT)$(CXX) $(OBJS) test.cpp $(BUILD_CXX_FLAGS) -Wl,-rpath,$(abspath $(BINDIR)) $(QT5_LINK_FLAGS) -o $@
$(SILENT)$(CXX) $(OBJS) test.cpp $(BUILD_CXX_FLAGS) $(NON_STATIC_LINK_FLAGS) -Wl,-rpath,$(abspath $(BINDIR)) $(QT_LINK_FLAGS) -o $@


$(BINDIR)/resources/%: % $(BINDIR)/resources/%: %
-@mkdir -p $(BINDIR)/resources -@mkdir -p $(BINDIR)/resources
@@ -199,7 +199,7 @@ $(BINDIR)/resources/zynaddsubfx-ui: ../native-plugins/resources/zynaddsubfx-ui
$(BINDIR)/libcarla_frontend$(LIB_EXT): $(OBJS) $(LIBS) $(BINDIR)/libcarla_frontend$(LIB_EXT): $(OBJS) $(LIBS)
-@mkdir -p $(BINDIR) -@mkdir -p $(BINDIR)
@echo "Linking libcarla_frontend$(LIB_EXT)" @echo "Linking libcarla_frontend$(LIB_EXT)"
$(SILENT)$(CXX) $(OBJS) $(BUILD_CXX_FLAGS) $(QT5_LINK_FLAGS) $(SHARED) -o $@
$(SILENT)$(CXX) $(OBJS) $(BUILD_CXX_FLAGS) $(QT_CXX_FLAGS) $(NON_STATIC_LINK_FLAGS) $(QT_LINK_FLAGS) $(SHARED) -o $@
ifeq ($(MACOS),true) ifeq ($(MACOS),true)
# FIXME this does not work: -Wl,-rpath,@loader_path # FIXME this does not work: -Wl,-rpath,@loader_path
$(SILENT)install_name_tool -change ../../../bin/libcarla_utils.dylib @loader_path/libcarla_utils.dylib $@ $(SILENT)install_name_tool -change ../../../bin/libcarla_utils.dylib @loader_path/libcarla_utils.dylib $@
@@ -208,7 +208,7 @@ endif
$(OBJDIR)/%.cpp.o: %.cpp $(UIs) $(OBJDIR)/%.cpp.o: %.cpp $(UIs)
-@mkdir -p $(shell dirname $@) -@mkdir -p $(shell dirname $@)
@echo "Compiling $<" @echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) $(QT_CXX_FLAGS) -c -o $@


-include $(OBJS:%.o=%.d) -include $(OBJS:%.o=%.d)


@@ -217,7 +217,6 @@ $(OBJDIR)/%.cpp.o: %.cpp $(UIs)
clean: clean:
rm -rf $(BINDIR)/libcarla_frontend$(LIB_EXT) $(UIs) $(RES) $(QMs) __pycache__ *.pyc rm -rf $(BINDIR)/libcarla_frontend$(LIB_EXT) $(UIs) $(RES) $(QMs) __pycache__ *.pyc
# old files # old files
rm -f ui_carla_about_juce.py
rm -f ui_carla_add_jack.py rm -f ui_carla_add_jack.py
rm -f ui_carla_database.py rm -f ui_carla_database.py
rm -f ui_carla_refresh.py rm -f ui_carla_refresh.py


+ 8
- 17
source/frontend/bigmeter-ui View File

@@ -1,25 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla Native Plugins
# Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import Qt
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import Qt
elif qt_config == 6:
from PyQt6.QtCore import Qt


# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 4
- 16
source/frontend/carla View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -38,6 +24,8 @@ from carla_shared import (
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# Read CLI args # Read CLI args




+ 4
- 16
source/frontend/carla-control View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2021 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -36,6 +22,8 @@ import sys
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# Read CLI args # Read CLI args




+ 4
- 16
source/frontend/carla-jack-multi View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -25,6 +11,8 @@ from carla_host import *
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# Read CLI args # Read CLI args




+ 4
- 16
source/frontend/carla-jack-single View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -25,6 +11,8 @@ from carla_host import *
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# Read CLI args # Read CLI args




+ 4
- 16
source/frontend/carla-patchbay View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -25,6 +11,8 @@ from carla_host import *
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# Read CLI args # Read CLI args




+ 12
- 18
source/frontend/carla-plugin View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host (plugin UI)
# Copyright (C) 2013-2020 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the GPL.txt file
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtGui import QKeySequence, QMouseEvent
from PyQt5.QtWidgets import QFrame, QSplitter
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtGui import QKeySequence, QMouseEvent
from PyQt5.QtWidgets import QFrame, QSplitter
elif qt_config == 6:
from PyQt6.QtGui import QKeySequence, QMouseEvent
from PyQt6.QtWidgets import QFrame, QSplitter


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -577,6 +569,8 @@ class CarlaEmbedW(QEmbedWidget):
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------- # -------------------------------------------------------------
# Get details regarding target usage # Get details regarding target usage




+ 4
- 16
source/frontend/carla-rack View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2015 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff) # Imports (Custom Stuff)
@@ -25,6 +11,8 @@ from carla_host import *
# Main # Main


if __name__ == '__main__': if __name__ == '__main__':
import resources_rc

# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# Read CLI args # Read CLI args




+ 18
- 25
source/frontend/carla_app.py View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla application
# Copyright (C) 2013-2020 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)
@@ -28,11 +14,18 @@ import sys
from ctypes import CDLL, RTLD_GLOBAL from ctypes import CDLL, RTLD_GLOBAL


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (PyQt5)
# Imports (PyQt)


from PyQt5.QtCore import QT_VERSION, Qt, QCoreApplication, QLibraryInfo, QLocale, QTranslator
from PyQt5.QtGui import QColor, QIcon, QPalette
from PyQt5.QtWidgets import QApplication
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import QT_VERSION, Qt, QCoreApplication, QLibraryInfo, QLocale, QTranslator
from PyQt5.QtGui import QColor, QIcon, QPalette
from PyQt5.QtWidgets import QApplication
elif qt_config == 6:
from PyQt6.QtCore import QT_VERSION, Qt, QCoreApplication, QLibraryInfo, QLocale, QTranslator
from PyQt6.QtGui import QColor, QIcon, QPalette
from PyQt6.QtWidgets import QApplication


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -137,7 +130,7 @@ class CarlaApplication():
self.createPaletteBlue() self.createPaletteBlue()


def createApp(self, appName): def createApp(self, appName):
if LINUX:
if qt_config == 5 and LINUX:
# AA_X11InitThreads is not available on old PyQt versions # AA_X11InitThreads is not available on old PyQt versions
try: try:
attr = Qt.AA_X11InitThreads attr = Qt.AA_X11InitThreads
@@ -145,13 +138,13 @@ class CarlaApplication():
attr = 10 attr = 10
QApplication.setAttribute(attr) QApplication.setAttribute(attr)


if QT_VERSION >= 0x50600:
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

if MACOS: if MACOS:
QApplication.setAttribute(Qt.AA_DontShowIconsInMenus) QApplication.setAttribute(Qt.AA_DontShowIconsInMenus)


if QT_VERSION >= 0x50600:
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

args = sys.argv[:] args = sys.argv[:]


if WINDOWS: if WINDOWS:


+ 8
- 17
source/frontend/carla_backend_qt.py View File

@@ -1,25 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla Backend code (Qt stuff)
# Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import pyqtSignal, QObject
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSignal, QObject
elif qt_config == 6:
from PyQt6.QtCore import pyqtSignal, QObject


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 7
- 23
source/frontend/carla_frontend.py View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla Backend utils
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)
@@ -28,7 +14,11 @@ from ctypes import (
POINTER POINTER
) )


from sip import unwrapinstance
try:
from sip import unwrapinstance
except ImportError:
def unwrapinstance(_):
return None


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -91,9 +81,6 @@ class CarlaFrontendLib():
def __init__(self, filename): def __init__(self, filename):
self.lib = cdll.LoadLibrary(filename) self.lib = cdll.LoadLibrary(filename)


self.lib.carla_frontend_createAndExecAboutJuceDialog.argtypes = (c_void_p,)
self.lib.carla_frontend_createAndExecAboutJuceDialog.restype = None

self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p) self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p)
self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults) self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults)


@@ -111,9 +98,6 @@ class CarlaFrontendLib():


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------


def createAndExecAboutJuceDialog(self, parent):
self.lib.carla_frontend_createAndExecAboutJuceDialog(unwrapinstance(parent))

def createAndExecJackAppDialog(self, parent, projectFilename): def createAndExecJackAppDialog(self, parent, projectFilename):
return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent),
projectFilename.encode("utf-8"))) projectFilename.encode("utf-8")))


+ 76
- 43
source/frontend/carla_host.py View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla host code
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)
@@ -29,23 +15,78 @@ from ctypes import (
) )


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (PyQt5)
# Imports (PyQt)


# This fails in some configurations, assume >= 5.6.0 in that case
try:
from PyQt5.Qt import PYQT_VERSION
except ImportError:
PYQT_VERSION = 0x50600
from qt_compat import qt_config


from PyQt5.QtCore import (
QT_VERSION, qCritical, QBuffer, QEventLoop, QFileInfo, QIODevice, QMimeData, QModelIndex, QPointF, QTimer, QEvent
)
from PyQt5.QtGui import (
QImage, QImageWriter, QPainter, QPalette, QBrush
)
from PyQt5.QtWidgets import (
QAction, QApplication, QInputDialog, QFileSystemModel, QListWidgetItem, QGraphicsView, QMainWindow
)
if qt_config == 5:
# This fails in some configurations, assume >= 5.6.0 in that case
try:
from PyQt5.Qt import PYQT_VERSION
except ImportError:
PYQT_VERSION = 0x50600

from PyQt5.QtCore import (
QT_VERSION,
qCritical,
QBuffer,
QEvent,
QEventLoop,
QFileInfo,
QIODevice,
QMimeData,
QModelIndex,
QPointF,
QTimer,
)
from PyQt5.QtGui import (
QBrush,
QImage,
QImageWriter,
QPainter,
QPalette,
)
from PyQt5.QtWidgets import (
QAction,
QApplication,
QInputDialog,
QFileSystemModel,
QListWidgetItem,
QGraphicsView,
QMainWindow,
)

elif qt_config == 6:
from PyQt6.QtCore import (
PYQT_VERSION,
QT_VERSION,
qCritical,
QBuffer,
QEvent,
QEventLoop,
QFileInfo,
QIODevice,
QMimeData,
QModelIndex,
QPointF,
QTimer,
)
from PyQt6.QtGui import (
QAction,
QBrush,
QFileSystemModel,
QImage,
QImageWriter,
QPainter,
QPalette,
)
from PyQt6.QtWidgets import (
QApplication,
QInputDialog,
QListWidgetItem,
QGraphicsView,
QMainWindow,
)


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -434,7 +475,6 @@ class HostWindow(QMainWindow):
self.ui.act_file_quit.setMenuRole(QAction.QuitRole) self.ui.act_file_quit.setMenuRole(QAction.QuitRole)
self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole) self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole)
self.ui.act_help_about.setMenuRole(QAction.AboutRole) self.ui.act_help_about.setMenuRole(QAction.AboutRole)
self.ui.act_help_about_juce.setMenuRole(QAction.ApplicationSpecificRole)
self.ui.act_help_about_qt.setMenuRole(QAction.AboutQtRole) self.ui.act_help_about_qt.setMenuRole(QAction.AboutQtRole)
self.ui.menu_Settings.setTitle("Panels") self.ui.menu_Settings.setTitle("Panels")


@@ -526,7 +566,6 @@ class HostWindow(QMainWindow):
self.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) self.ui.act_settings_configure.triggered.connect(self.slot_configureCarla)


self.ui.act_help_about.triggered.connect(self.slot_aboutCarla) self.ui.act_help_about.triggered.connect(self.slot_aboutCarla)
self.ui.act_help_about_juce.triggered.connect(self.slot_aboutJuce)
self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt) self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt)


self.ui.cb_disk.currentIndexChanged.connect(self.slot_diskFolderChanged) self.ui.cb_disk.currentIndexChanged.connect(self.slot_diskFolderChanged)
@@ -630,10 +669,6 @@ class HostWindow(QMainWindow):
self.ui.cb_transport_link.setEnabled(False) self.ui.cb_transport_link.setEnabled(False)
self.ui.cb_transport_link.setVisible(False) self.ui.cb_transport_link.setVisible(False)


if "juce" not in features:
self.ui.act_help_about_juce.setEnabled(False)
self.ui.act_help_about_juce.setVisible(False)

# Plugin needs to have timers always running so it receives messages # Plugin needs to have timers always running so it receives messages
if self.host.isPlugin or self.host.isRemote: if self.host.isPlugin or self.host.isRemote:
self.startTimers() self.startTimers()
@@ -1674,7 +1709,7 @@ class HostWindow(QMainWindow):
self.ui.graphicsView.setRenderHint(QPainter.SmoothPixmapTransform, fullAA) self.ui.graphicsView.setRenderHint(QPainter.SmoothPixmapTransform, fullAA)
self.ui.graphicsView.setRenderHint(QPainter.TextAntialiasing, fullAA) self.ui.graphicsView.setRenderHint(QPainter.TextAntialiasing, fullAA)


if self.fSavedSettings[CARLA_KEY_CANVAS_USE_OPENGL] and hasGL:
if self.fSavedSettings[CARLA_KEY_CANVAS_USE_OPENGL] and hasGL and QPainter.HighQualityAntialiasing is not None:
self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings[CARLA_KEY_CANVAS_HQ_ANTIALIASING]) self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings[CARLA_KEY_CANVAS_HQ_ANTIALIASING])


else: else:
@@ -2255,10 +2290,6 @@ class HostWindow(QMainWindow):
def slot_aboutCarla(self): def slot_aboutCarla(self):
CarlaAboutW(self.fParentOrSelf, self.host).exec_() CarlaAboutW(self.fParentOrSelf, self.host).exec_()


@pyqtSlot()
def slot_aboutJuce(self):
gCarla.felib.createAndExecAboutJuceDialog(self.fParentOrSelf)

@pyqtSlot() @pyqtSlot()
def slot_aboutQt(self): def slot_aboutQt(self):
QApplication.instance().aboutQt() QApplication.instance().aboutQt()
@@ -2884,8 +2915,10 @@ class HostWindow(QMainWindow):
if MACOS: if MACOS:
nsViewPtr = int(self.winId()) nsViewPtr = int(self.winId())
winIdStr = "%x" % gCarla.utils.cocoa_get_window(nsViewPtr) winIdStr = "%x" % gCarla.utils.cocoa_get_window(nsViewPtr)
else:
elif WINDOWS or QApplication.platformName() == "xcb":
winIdStr = "%x" % int(self.winId()) winIdStr = "%x" % int(self.winId())
else:
winIdStr = "0"
self.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr) self.host.set_engine_option(ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr)


def hideEvent(self, event): def hideEvent(self, event):


+ 8
- 17
source/frontend/carla_host_control.py View File

@@ -1,25 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla Backend code (OSC stuff)
# Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import QEventLoop
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import QEventLoop
elif qt_config == 6:
from PyQt6.QtCore import QEventLoop


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 16
- 20
source/frontend/carla_settings.py View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla settings code
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Imports (PyQt5)
# Imports (PyQt)


from PyQt5.QtCore import pyqtSlot, QT_VERSION, Qt
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFileDialog
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSlot, QT_VERSION, Qt
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QFileDialog
elif qt_config == 6:
from PyQt6.QtCore import pyqtSlot, QT_VERSION, Qt
from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QFileDialog


# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -601,6 +593,10 @@ class CarlaSettingsW(QDialog):
# FIXME broken in some Qt5 versions # FIXME broken in some Qt5 versions
self.ui.cb_canvas_eyecandy.setEnabled(QT_VERSION >= 0x50c00) self.ui.cb_canvas_eyecandy.setEnabled(QT_VERSION >= 0x50c00)


# removed in Qt6
if QT_VERSION >= 0x60000:
self.ui.cb_canvas_render_hq_aa.hide()

self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)


if MACOS: if MACOS:
@@ -749,7 +745,7 @@ class CarlaSettingsW(QDialog):
CARLA_DEFAULT_CANVAS_USE_OPENGL, bool)) CARLA_DEFAULT_CANVAS_USE_OPENGL, bool))


self.ui.cb_canvas_render_aa.setCheckState( self.ui.cb_canvas_render_aa.setCheckState(
settings.value(CARLA_KEY_CANVAS_ANTIALIASING, CARLA_DEFAULT_CANVAS_ANTIALIASING, int))
Qt.CheckState(settings.value(CARLA_KEY_CANVAS_ANTIALIASING, CARLA_DEFAULT_CANVAS_ANTIALIASING, int)))


self.ui.cb_canvas_render_hq_aa.setChecked(self.ui.cb_canvas_render_hq_aa.isEnabled() and self.ui.cb_canvas_render_hq_aa.setChecked(self.ui.cb_canvas_render_hq_aa.isEnabled() and
settings.value(CARLA_KEY_CANVAS_HQ_ANTIALIASING, settings.value(CARLA_KEY_CANVAS_HQ_ANTIALIASING,


+ 33
- 33
source/frontend/carla_shared.py View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Common Carla code
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)
@@ -36,17 +22,25 @@ except:
haveSIGUSR1 = False haveSIGUSR1 = False


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (PyQt5)
# Imports (PyQt)


# import changed in PyQt 5.15.8, so try both
try:
from PyQt5.Qt import PYQT_VERSION_STR
except ImportError:
from PyQt5.QtCore import PYQT_VERSION_STR
from qt_compat import qt_config

if qt_config == 5:
# import changed in PyQt 5.15.8, so try both
try:
from PyQt5.Qt import PYQT_VERSION_STR
except ImportError:
from PyQt5.QtCore import PYQT_VERSION_STR


from PyQt5.QtCore import qFatal, QT_VERSION, QT_VERSION_STR, qWarning, QDir, QSettings
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from PyQt5.QtCore import qFatal, QT_VERSION, QT_VERSION_STR, qWarning, QDir, QSettings
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QFileDialog, QMessageBox

elif qt_config == 6:
from PyQt6.QtCore import qFatal, PYQT_VERSION_STR, QT_VERSION, QT_VERSION_STR, qWarning, QDir, QSettings
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QFileDialog, QMessageBox


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -523,15 +517,21 @@ if not WINDOWS:
if not winePrefix: if not winePrefix:
winePrefix = HOME + "/.wine" winePrefix = HOME + "/.wine"


if os.path.exists(winePrefix):
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/VstPlugins"
DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3"
DEFAULT_CLAP_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/VstPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/VSTPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/Steinberg/VstPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/Steinberg/VSTPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST2"
DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3"
DEFAULT_CLAP_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP"


if kIs64bit and os.path.exists(winePrefix + "/drive_c/Program Files (x86)"):
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins"
DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3"
DEFAULT_CLAP_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP"
if kIs64bit:
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VSTPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VstPlugins"
DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VSTPlugins"
DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3"
DEFAULT_CLAP_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP"


del winePrefix del winePrefix




+ 12
- 19
source/frontend/carla_skin.py View File

@@ -1,27 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin/slot skin code
# Copyright (C) 2013-2020 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import Qt, QRectF, QLineF, QTimer
from PyQt5.QtGui import QColor, QFont, QFontDatabase, QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QColorDialog, QFrame, QLineEdit, QPushButton
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import Qt, QRectF, QLineF, QTimer
from PyQt5.QtGui import QColor, QFont, QFontDatabase, QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QColorDialog, QFrame, QLineEdit, QPushButton
elif qt_config == 6:
from PyQt6.QtCore import Qt, QRectF, QLineF, QTimer
from PyQt6.QtGui import QColor, QFont, QFontDatabase, QPainter, QPainterPath, QPen
from PyQt6.QtWidgets import QColorDialog, QFrame, QLineEdit, QPushButton


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 0
- 25
source/frontend/carla_utils.py View File

@@ -262,9 +262,6 @@ class CarlaUtils():
self.lib.carla_get_complete_license_text.argtypes = None self.lib.carla_get_complete_license_text.argtypes = None
self.lib.carla_get_complete_license_text.restype = c_char_p self.lib.carla_get_complete_license_text.restype = c_char_p


self.lib.carla_get_juce_version.argtypes = None
self.lib.carla_get_juce_version.restype = c_char_p

self.lib.carla_get_supported_file_extensions.argtypes = None self.lib.carla_get_supported_file_extensions.argtypes = None
self.lib.carla_get_supported_file_extensions.restype = POINTER(c_char_p) self.lib.carla_get_supported_file_extensions.restype = POINTER(c_char_p)


@@ -328,15 +325,6 @@ class CarlaUtils():
self.lib.carla_pipe_client_destroy.argtypes = [CarlaPipeClientHandle] self.lib.carla_pipe_client_destroy.argtypes = [CarlaPipeClientHandle]
self.lib.carla_pipe_client_destroy.restype = None self.lib.carla_pipe_client_destroy.restype = None


self.lib.carla_juce_init.argtypes = None
self.lib.carla_juce_init.restype = None

self.lib.carla_juce_idle.argtypes = None
self.lib.carla_juce_idle.restype = None

self.lib.carla_juce_cleanup.argtypes = None
self.lib.carla_juce_cleanup.restype = None

self.lib.carla_get_desktop_scale_factor.argtypes = None self.lib.carla_get_desktop_scale_factor.argtypes = None
self.lib.carla_get_desktop_scale_factor.restype = c_double self.lib.carla_get_desktop_scale_factor.restype = c_double


@@ -399,10 +387,6 @@ class CarlaUtils():
def get_complete_license_text(self): def get_complete_license_text(self):
return charPtrToString(self.lib.carla_get_complete_license_text()) return charPtrToString(self.lib.carla_get_complete_license_text())


# Get the juce version used in the current Carla build.
def get_juce_version(self):
return charPtrToString(self.lib.carla_get_juce_version())

# Get the list of supported file extensions in carla_load_file(). # Get the list of supported file extensions in carla_load_file().
def get_supported_file_extensions(self): def get_supported_file_extensions(self):
return charPtrPtrToStringList(self.lib.carla_get_supported_file_extensions()) return charPtrPtrToStringList(self.lib.carla_get_supported_file_extensions())
@@ -484,15 +468,6 @@ class CarlaUtils():
def pipe_client_destroy(self, handle): def pipe_client_destroy(self, handle):
self.lib.carla_pipe_client_destroy(handle) self.lib.carla_pipe_client_destroy(handle)


def juce_init(self):
self.lib.carla_juce_init()

def juce_idle(self):
self.lib.carla_juce_idle()

def juce_cleanup(self):
self.lib.carla_juce_cleanup()

def get_desktop_scale_factor(self): def get_desktop_scale_factor(self):
return float(self.lib.carla_get_desktop_scale_factor()) return float(self.lib.carla_get_desktop_scale_factor())




+ 35
- 31
source/frontend/carla_widgets.py View File

@@ -1,20 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla widgets code
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)
@@ -22,11 +8,36 @@
from abc import abstractmethod from abc import abstractmethod


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (PyQt5)

from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QByteArray
from PyQt5.QtGui import QCursor, QIcon, QPalette, QPixmap
from PyQt5.QtWidgets import QDialog, QFileDialog, QInputDialog, QMenu, QMessageBox, QScrollArea, QVBoxLayout, QWidget
# Imports (PyQt)

from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QByteArray
from PyQt5.QtGui import QCursor, QIcon, QPalette, QPixmap
from PyQt5.QtWidgets import (
QDialog,
QFileDialog,
QInputDialog,
QMenu,
QMessageBox,
QScrollArea,
QVBoxLayout,
QWidget,
)
elif qt_config == 6:
from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QByteArray
from PyQt6.QtGui import QCursor, QIcon, QPalette, QPixmap
from PyQt6.QtWidgets import (
QDialog,
QFileDialog,
QInputDialog,
QMenu,
QMessageBox,
QScrollArea,
QVBoxLayout,
QWidget,
)


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -202,18 +213,11 @@ class CarlaAboutW(QDialog):
"<li>http://ll-plugins.nongnu.org/lv2/ext/miditype</li>" "<li>http://ll-plugins.nongnu.org/lv2/ext/miditype</li>"
"</ul>")) "</ul>"))


usingJuce = "juce" in gCarla.utils.get_supported_features()

if usingJuce and (MACOS or WINDOWS):
self.ui.l_vst2.setText(self.tr("Using JUCE host"))
else:
self.ui.l_vst2.setText(self.tr("About 85&#37; complete (missing vst bank/presets and some minor stuff)"))

if usingJuce:
self.ui.l_vst3.setText(self.tr("Using JUCE host"))
self.ui.l_vst2.setText(self.tr("About 85&#37; complete (missing vst bank/presets and some minor stuff)"))
self.ui.l_vst3.setText(self.tr("About 66&#37; complete"))


if MACOS: if MACOS:
self.ui.l_au.setText(self.tr("Using JUCE host"))
self.ui.l_au.setText(self.tr("About 20&#37; complete"))
else: else:
self.ui.line_vst3.hide() self.ui.line_vst3.hide()
self.ui.l_au.hide() self.ui.l_au.hide()


+ 0
- 1
source/frontend/dialogs/__init__.py View File

@@ -16,5 +16,4 @@
# #
# For a full copy of the GNU General Public License see the doc/GPL.txt file. # For a full copy of the GNU General Public License see the doc/GPL.txt file.


from .aboutjucedialog import AboutJuceDialog
from .jackappdialog import JackAppDialog from .jackappdialog import JackAppDialog

+ 0
- 97
source/frontend/dialogs/aboutjucedialog.cpp View File

@@ -1,97 +0,0 @@
/*
* Carla plugin host
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "aboutjucedialog.hpp"

#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy"
# pragma clang diagnostic ignored "-Wdeprecated-register"
#elif defined(__GNUC__) && __GNUC__ >= 8
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wclass-memaccess"
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
#endif

#include "ui_aboutjucedialog.h"

#ifdef __clang__
# pragma clang diagnostic pop
#elif defined(__GNUC__) && __GNUC__ >= 8
# pragma GCC diagnostic pop
#endif

#include "CarlaFrontend.h"
#include "CarlaUtils.h"

// --------------------------------------------------------------------------------------------------------------------
// Jack Application Dialog

struct AboutJuceDialog::Self {
Ui_AboutJuceDialog ui;

Self() {}

static Self& create()
{
Self* const self = new Self();
return *self;
}
};

AboutJuceDialog::AboutJuceDialog(QWidget* const parent)
: QDialog(parent),
self(Self::create())
{
self.ui.setupUi(this);

// -------------------------------------------------------------------------------------------------------------
// UI setup

self.ui.l_text2->setText(tr("This program uses JUCE version") + " " + carla_get_juce_version() + ".");

adjustSize();
setFixedSize(size());

Qt::WindowFlags flags = windowFlags();
flags &= ~Qt::WindowContextHelpButtonHint;

#ifdef CARLA_OS_WIN
flags |= Qt::MSWindowsFixedSizeDialogHint;
#endif

setWindowFlags(flags);

#ifdef CARLA_OS_MAC
if (parent != nullptr)
setWindowModality(Qt::WindowModal);
#endif
}

AboutJuceDialog::~AboutJuceDialog()
{
delete &self;
}

// --------------------------------------------------------------------------------------------------------------------

void carla_frontend_createAndExecAboutJuceDialog(void* const parent)
{
AboutJuceDialog(reinterpret_cast<QWidget*>(parent)).exec();
}

// --------------------------------------------------------------------------------------------------------------------

+ 0
- 55
source/frontend/dialogs/aboutjucedialog.hpp View File

@@ -1,55 +0,0 @@
/*
* Carla plugin host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#pragma once

#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy"
# pragma clang diagnostic ignored "-Wdeprecated-register"
#elif defined(__GNUC__) && __GNUC__ >= 8
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wclass-memaccess"
# pragma GCC diagnostic ignored "-Wdeprecated-copy"
#endif

#include <QtWidgets/QDialog>

#ifdef __clang__
# pragma clang diagnostic pop
#elif defined(__GNUC__) && __GNUC__ >= 8
# pragma GCC diagnostic pop
#endif

#include "CarlaDefines.h"

// --------------------------------------------------------------------------------------------------------------------
// About JUCE dialog

class AboutJuceDialog : public QDialog
{
struct Self;
Self& self;

// ----------------------------------------------------------------------------------------------------------------

public:
explicit AboutJuceDialog(QWidget* parent);
~AboutJuceDialog() override;
};

// --------------------------------------------------------------------------------------------------------------------

+ 0
- 77
source/frontend/dialogs/aboutjucedialog.py View File

@@ -1,77 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.

# ---------------------------------------------------------------------------------------------------------------------
# Imports (Global)

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog

# ---------------------------------------------------------------------------------------------------------------------
# Imports (Carla)

from common import MACOS, WINDOWS
from carla_shared import gCarla

# ---------------------------------------------------------------------------------------------------------------------
# Imports (Local)

from aboutjucedialog_ui import Ui_AboutJuceDialog

# ------------------------------------------------------------------------------------------------------------
# About JUCE dialog

class AboutJuceDialog(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.ui = Ui_AboutJuceDialog()
self.ui.setupUi(self)

self.ui.l_text2.setText(self.tr("This program uses JUCE version %s." % gCarla.utils.get_juce_version()))

self.adjustSize()
self.setFixedSize(self.size())

flags = self.windowFlags()
flags &= ~Qt.WindowContextHelpButtonHint

if WINDOWS:
flags |= Qt.MSWindowsFixedSizeDialogHint

self.setWindowFlags(flags)

if MACOS:
self.setWindowModality(Qt.WindowModal)

# ---------------------------------------------------------------------------------------------------------------------
# Testing

if __name__ == '__main__':
import sys
# pylint: disable=ungrouped-imports
from PyQt5.QtWidgets import QApplication
# pylint: enable=ungrouped-imports

# from carla_utils import CarlaUtils
# gCarla.utils = CarlaUtils(os.path.dirname(__file__) + "/../../../bin/libcarla_utils.dylib")

_app = QApplication(sys.argv)
_gui = AboutJuceDialog(None)
_gui.exec_()

# ---------------------------------------------------------------------------------------------------------------------

+ 0
- 187
source/frontend/dialogs/aboutjucedialog.ui View File

@@ -1,187 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutJuceDialog</class>
<widget class="QDialog" name="AboutJuceDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>463</width>
<height>244</height>
</rect>
</property>
<property name="windowTitle">
<string>About JUCE</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="icon">
<property name="minimumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../resources.qrc">:/48x48/juce.png</pixmap>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="l_text1">
<property name="text">
<string>&lt;b&gt;About JUCE&lt;/b&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="l_text2">
<property name="text">
<string>This program uses JUCE version 3.x.x.</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="l_text3">
<property name="text">
<string>JUCE is an open-source cross-platform C++ application framework for creating high quality desktop and mobile applications.

The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_core and juce_events) are permissively licensed under the terms of the ISC license.
Other modules are covered by a GNU GPL 3.0 license.

Copyright (C) 2022 Raw Material Software Limited.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../resources.qrc"/>
<include location="../resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AboutJuceDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AboutJuceDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

+ 31
- 28
source/frontend/midipattern-ui View File

@@ -1,28 +1,21 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# A piano roll viewer/editor
# Copyright (C) 2012-2020 Filipe Coelho <falktx@falktx.com>
# Copyright (C) 2014-2015 Perry Nguyen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-FileCopyrightText: 2014-2015 Perry Nguyen
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import pyqtSlot, Qt, QEvent
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import QMainWindow
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSlot, QT_VERSION, Qt, QEvent
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import QMainWindow
elif qt_config == 6:
from PyQt6.QtCore import pyqtSlot, QT_VERSION, Qt, QEvent
from PyQt6.QtGui import QKeyEvent
from PyQt6.QtWidgets import QMainWindow


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -74,15 +67,25 @@ class MidiPatternW(ExternalUI, QMainWindow):
self.ui.piano.modeupdate.connect(self.ui.modeIndicator.changeMode) self.ui.piano.modeupdate.connect(self.ui.modeIndicator.changeMode)
self.ui.piano.modeupdate.connect(self.slot_modeChanged) self.ui.piano.modeupdate.connect(self.slot_modeChanged)


self.ui.timeSigBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.measureBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.defaultLengthBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.quantizeBox.currentIndexChanged[int].connect(self.slot_paramChanged)
if QT_VERSION >= 0x60000:
self.ui.timeSigBox.currentIndexChanged.connect(self.slot_paramChanged)
self.ui.measureBox.currentIndexChanged.connect(self.slot_paramChanged)
self.ui.defaultLengthBox.currentIndexChanged.connect(self.slot_paramChanged)
self.ui.quantizeBox.currentIndexChanged.connect(self.slot_paramChanged)
self.ui.timeSigBox.currentTextChanged.connect(self.slot_setTimeSignature)
self.ui.measureBox.currentTextChanged.connect(self.ui.piano.setMeasures)
self.ui.defaultLengthBox.currentTextChanged.connect(self.ui.piano.setDefaultLength)
self.ui.quantizeBox.currentTextChanged.connect(self.ui.piano.setGridDiv)
else:
self.ui.timeSigBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.measureBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.defaultLengthBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.quantizeBox.currentIndexChanged[int].connect(self.slot_paramChanged)
self.ui.timeSigBox.currentIndexChanged[str].connect(self.slot_setTimeSignature)
self.ui.measureBox.currentIndexChanged[str].connect(self.ui.piano.setMeasures)
self.ui.defaultLengthBox.currentIndexChanged[str].connect(self.ui.piano.setDefaultLength)
self.ui.quantizeBox.currentIndexChanged[str].connect(self.ui.piano.setGridDiv)


self.ui.timeSigBox.currentIndexChanged[str].connect(self.slot_setTimeSignature)
self.ui.measureBox.currentIndexChanged[str].connect(self.ui.piano.setMeasures)
self.ui.defaultLengthBox.currentIndexChanged[str].connect(self.ui.piano.setDefaultLength)
self.ui.quantizeBox.currentIndexChanged[str].connect(self.ui.piano.setGridDiv)
self.ui.hSlider.valueChanged.connect(self.ui.graphicsView.setZoomX) self.ui.hSlider.valueChanged.connect(self.ui.graphicsView.setZoomX)
self.ui.vSlider.valueChanged.connect(self.ui.graphicsView.setZoomY) self.ui.vSlider.valueChanged.connect(self.ui.graphicsView.setZoomY)




+ 10
- 18
source/frontend/notes-ui View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla Native Plugins
# Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget
elif qt_config == 6:
from PyQt6.QtCore import pyqtSlot, Qt
from PyQt6.QtWidgets import QGridLayout, QLabel, QPushButton, QTextEdit, QWidget


# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 10
- 18
source/frontend/patchcanvas/__init__.py View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import QPointF, QRectF
from PyQt5.QtWidgets import QGraphicsItem
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import QPointF, QRectF
from PyQt5.QtWidgets import QGraphicsItem
elif qt_config == 6:
from PyQt6.QtCore import QPointF, QRectF
from PyQt6.QtWidgets import QGraphicsItem


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Theme) # Imports (Theme)


+ 12
- 19
source/frontend/patchcanvas/canvasbezierline.py View File

@@ -1,27 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QColor, QLinearGradient, QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QGraphicsPathItem
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QColor, QLinearGradient, QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QGraphicsPathItem
elif qt_config == 6:
from PyQt6.QtCore import Qt, QPointF
from PyQt6.QtGui import QColor, QLinearGradient, QPainter, QPainterPath, QPen
from PyQt6.QtWidgets import QGraphicsPathItem


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 12
- 19
source/frontend/patchcanvas/canvasbezierlinemov.py View File

@@ -1,27 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import qWarning, Qt, QPointF
from PyQt5.QtGui import QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QGraphicsPathItem
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import qWarning, Qt, QPointF
from PyQt5.QtGui import QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QGraphicsPathItem
elif qt_config == 6:
from PyQt6.QtCore import qWarning, Qt, QPointF
from PyQt6.QtGui import QPainter, QPainterPath, QPen
from PyQt6.QtWidgets import QGraphicsPathItem


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 14
- 19
source/frontend/patchcanvas/canvasbox.py View File

@@ -1,27 +1,22 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2021 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import pyqtSignal, pyqtSlot, qCritical, QT_VERSION, Qt, QPointF, QRectF, QTimer
from PyQt5.QtGui import QCursor, QFont, QFontMetrics, QImage, QLinearGradient, QPainter, QPen
from PyQt5.QtWidgets import QGraphicsItem, QGraphicsObject, QMenu
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSignal, pyqtSlot, qCritical, QT_VERSION, Qt, QPointF, QRectF, QTimer
from PyQt5.QtGui import QCursor, QFont, QFontMetrics, QImage, QLinearGradient, QPainter, QPen
from PyQt5.QtSvg import QGraphicsSvgItem
from PyQt5.QtWidgets import QGraphicsItem, QGraphicsObject, QMenu
elif qt_config == 6:
from PyQt6.QtCore import pyqtSignal, pyqtSlot, qCritical, QT_VERSION, Qt, QPointF, QRectF, QTimer
from PyQt6.QtGui import QCursor, QFont, QFontMetrics, QImage, QLinearGradient, QPainter, QPen
from PyQt6.QtSvgWidgets import QGraphicsSvgItem
from PyQt6.QtWidgets import QGraphicsItem, QGraphicsObject, QMenu


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Backwards-compatible horizontalAdvance/width call, depending on Qt version # Backwards-compatible horizontalAdvance/width call, depending on Qt version


+ 10
- 18
source/frontend/patchcanvas/canvasboxshadow.py View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
elif qt_config == 6:
from PyQt6.QtGui import QColor
from PyQt6.QtWidgets import QGraphicsDropShadowEffect


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 10
- 18
source/frontend/patchcanvas/canvasfadeanimation.py View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import QAbstractAnimation
from PyQt5.QtWidgets import QGraphicsObject
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import QAbstractAnimation
from PyQt5.QtWidgets import QGraphicsObject
elif qt_config == 6:
from PyQt6.QtCore import QAbstractAnimation
from PyQt6.QtWidgets import QGraphicsObject


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 15
- 20
source/frontend/patchcanvas/canvasicon.py View File

@@ -1,28 +1,23 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import qCritical, QRectF
from PyQt5.QtGui import QPainter
from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer
from PyQt5.QtWidgets import QGraphicsColorizeEffect
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import qCritical, QRectF
from PyQt5.QtGui import QPainter
from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer
from PyQt5.QtWidgets import QGraphicsColorizeEffect
elif qt_config == 6:
from PyQt6.QtCore import qCritical, QRectF
from PyQt6.QtGui import QPainter
from PyQt6.QtSvg import QSvgRenderer
from PyQt6.QtSvgWidgets import QGraphicsSvgItem
from PyQt6.QtWidgets import QGraphicsColorizeEffect


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 12
- 19
source/frontend/patchcanvas/canvasline.py View File

@@ -1,27 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import Qt, QLineF
from PyQt5.QtGui import QLinearGradient, QPainter, QPen
from PyQt5.QtWidgets import QGraphicsLineItem
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import Qt, QLineF
from PyQt5.QtGui import QLinearGradient, QPainter, QPen
from PyQt5.QtWidgets import QGraphicsLineItem
elif qt_config == 6:
from PyQt6.QtCore import Qt, QLineF
from PyQt6.QtGui import QLinearGradient, QPainter, QPen
from PyQt6.QtWidgets import QGraphicsLineItem


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 12
- 19
source/frontend/patchcanvas/canvaslinemov.py View File

@@ -1,27 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import qWarning, Qt, QLineF
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtWidgets import QGraphicsLineItem
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import qWarning, Qt, QLineF
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtWidgets import QGraphicsLineItem
elif qt_config == 6:
from PyQt6.QtCore import qWarning, Qt, QLineF
from PyQt6.QtGui import QPainter, QPen
from PyQt6.QtWidgets import QGraphicsLineItem


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 26
- 20
source/frontend/patchcanvas/canvasport.py View File

@@ -1,29 +1,22 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from math import floor from math import floor


from PyQt5.QtCore import qCritical, Qt, QLineF, QPointF, QRectF, QTimer
from PyQt5.QtGui import QCursor, QFont, QFontMetrics, QPainter, QPainterPath, QPen, QPolygonF
from PyQt5.QtWidgets import QGraphicsItem, QMenu
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import qCritical, Qt, QLineF, QPointF, QRectF, QTimer
from PyQt5.QtGui import QCursor, QFont, QFontMetrics, QPainter, QPainterPath, QPen, QPolygonF
from PyQt5.QtWidgets import QGraphicsItem, QMenu
elif qt_config == 6:
from PyQt6.QtCore import qCritical, Qt, QLineF, QPointF, QRectF, QTimer
from PyQt6.QtGui import QCursor, QFont, QFontMetrics, QPainter, QPainterPath, QPen, QPolygonF
from PyQt6.QtWidgets import QGraphicsItem, QMenu


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -120,7 +113,16 @@ class CanvasPort(QGraphicsItem):
self.update() self.update()


def setPortName(self, port_name): def setPortName(self, port_name):
if QFontMetrics(self.m_port_font).width(port_name) < QFontMetrics(self.m_port_font).width(self.m_port_name):
metrics = QFontMetrics(self.m_port_font)

if QT_VERSION >= 0x50b00:
width1 = metrics.horizontalAdvance(port_name)
width2 = metrics.horizontalAdvance(self.m_port_name)
else:
width1 = metrics.width(port_name)
width2 = metrics.width(self.m_port_name)

if width1 < width2:
QTimer.singleShot(0, canvas.scene.update) QTimer.singleShot(0, canvas.scene.update)


self.m_port_name = port_name self.m_port_name = port_name
@@ -376,6 +378,7 @@ class CanvasPort(QGraphicsItem):
conn_pen = QPen(theme.port_parameter_pen_sel) conn_pen = QPen(theme.port_parameter_pen_sel)
else: else:
qCritical("PatchCanvas::CanvasPort.paint() - invalid port type '%s'" % port_type2str(self.m_port_type)) qCritical("PatchCanvas::CanvasPort.paint() - invalid port type '%s'" % port_type2str(self.m_port_type))
painter.restore()
return return


# To prevent quality worsening # To prevent quality worsening
@@ -412,6 +415,7 @@ class CanvasPort(QGraphicsItem):
poly_locx[4] = lineHinting poly_locx[4] = lineHinting
else: else:
qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode) qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode)
painter.restore()
return return


elif self.m_port_mode == PORT_MODE_OUTPUT: elif self.m_port_mode == PORT_MODE_OUTPUT:
@@ -431,10 +435,12 @@ class CanvasPort(QGraphicsItem):
poly_locx[4] = self.m_port_width + 12 - lineHinting poly_locx[4] = self.m_port_width + 12 - lineHinting
else: else:
qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode) qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode)
painter.restore()
return return


else: else:
qCritical("PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" % port_mode2str(self.m_port_mode)) qCritical("PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" % port_mode2str(self.m_port_mode))
painter.restore()
return return


polygon = QPolygonF() polygon = QPolygonF()


+ 8
- 17
source/frontend/patchcanvas/canvasportglow.py View File

@@ -1,25 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtWidgets import QGraphicsDropShadowEffect
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
elif qt_config == 6:
from PyQt6.QtWidgets import QGraphicsDropShadowEffect


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 12
- 19
source/frontend/patchcanvas/patchcanvas.py View File

@@ -1,27 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import pyqtSlot, qCritical, qFatal, qWarning, QObject
from PyQt5.QtCore import QPointF, QRectF, QTimer
from PyQt5.QtWidgets import QGraphicsObject
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import pyqtSlot, qCritical, qFatal, qWarning, QObject
from PyQt5.QtCore import QPointF, QRectF, QTimer
from PyQt5.QtWidgets import QGraphicsObject
elif qt_config == 6:
from PyQt6.QtCore import pyqtSlot, qCritical, qFatal, qWarning, QObject
from PyQt6.QtCore import QPointF, QRectF, QTimer
from PyQt6.QtWidgets import QGraphicsObject


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)


+ 13
- 20
source/frontend/patchcanvas/scene.py View File

@@ -1,29 +1,22 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas engine using QGraphicsView/Scene
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from math import floor from math import floor


from PyQt5.QtCore import QT_VERSION, pyqtSignal, pyqtSlot, qFatal, Qt, QPointF, QRectF
from PyQt5.QtGui import QCursor, QPixmap, QPolygonF
from PyQt5.QtWidgets import QGraphicsRectItem, QGraphicsScene
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import QT_VERSION, pyqtSignal, pyqtSlot, qFatal, Qt, QPointF, QRectF
from PyQt5.QtGui import QCursor, QPixmap, QPolygonF
from PyQt5.QtWidgets import QGraphicsRectItem, QGraphicsScene
elif qt_config == 6:
from PyQt6.QtCore import QT_VERSION, pyqtSignal, pyqtSlot, qFatal, Qt, QPointF, QRectF
from PyQt6.QtGui import QCursor, QPixmap, QPolygonF
from PyQt6.QtWidgets import QGraphicsRectItem, QGraphicsScene


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)
@@ -314,7 +307,7 @@ class PatchScene(QGraphicsScene):
) )
self.m_mouse_rubberband = False self.m_mouse_rubberband = False


if event.button() == Qt.MidButton and ctrlDown:
if event.button() == Qt.MiddleButton and ctrlDown:
self.startConnectionCut() self.startConnectionCut()
items = self.items(event.scenePos()) items = self.items(event.scenePos())
for item in items: for item in items:


+ 10
- 18
source/frontend/patchcanvas/theme.py View File

@@ -1,26 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-

# PatchBay Canvas Themes
# Copyright (C) 2010-2019 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the doc/GPL.txt file.
# SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
# SPDX-License-Identifier: GPL-2.0-or-later


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)


from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QFont, QPen, QPixmap
from qt_compat import qt_config

if qt_config == 5:
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QFont, QPen, QPixmap
elif qt_config == 6:
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QColor, QFont, QPen, QPixmap


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------




Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save