diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
new file mode 100644
index 0000000..6ce35ec
--- /dev/null
+++ b/.github/workflows/cmake.yml
@@ -0,0 +1,73 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - main
+ - develop
+ pull_request:
+ branches:
+ - main
+ - develop
+
+ workflow_dispatch:
+
+jobs:
+ build_and_test:
+ if: contains(toJson(github.event.commits), '***NO_CI***') == false && contains(toJson(github.event.commits), '[ci skip]') == false && contains(toJson(github.event.commits), '[skip ci]') == false
+ name: Test plugin on ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false # show all errors for each platform (vs. cancel jobs on error)
+ matrix:
+ os: [ubuntu-latest, windows-2019, macOS-latest]
+
+ steps:
+ - name: Install Linux Deps
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update
+ sudo apt install libasound2-dev libcurl4-openssl-dev libx11-dev libxinerama-dev libxext-dev libfreetype6-dev libwebkit2gtk-4.0-dev libglu1-mesa-dev libjack-jackd2-dev lv2-dev
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9
+ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9
+ - name: Get latest CMake
+ uses: lukka/get-cmake@latest
+
+ - name: Checkout code
+ uses: actions/checkout@v2
+ with:
+ submodules: recursive
+
+ - name: Configure
+ shell: bash
+ run: cmake -Bbuild
+
+ - name: Build
+ shell: bash
+ run: cmake --build build --config Release --parallel 4
+
+ # Failing validation, fix
+ #- name: Validate
+ # if: runner.os == 'Windows'
+ # run: bash validate.sh
+
+ - name: Upload Linux Artifact GitHub Action
+ if: runner.os == 'Linux'
+ uses: actions/upload-artifact@v2
+ with:
+ name: linux-assets
+ path: /home/runner/work/TS-M1N3/TS-M1N3/build/TS-M1N3_artefacts
+
+ - name: Upload Mac Artifact GitHub Action
+ if: runner.os == 'macOS'
+ uses: actions/upload-artifact@v2
+ with:
+ name: mac-assets
+ path: /Users/runner/work/TS-M1N3/TS-M1N3/build/TS-M1N3_artefacts
+
+ - name: Upload Windows Artifact GitHub Action
+ if: runner.os == 'Windows'
+ uses: actions/upload-artifact@v2
+ with:
+ name: win-assets
+ path: D:/a/TS-M1N3/TS-M1N3/build/TS-M1N3_artefacts
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..8d1d9cd
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "modules/JUCE"]
+ path = modules/JUCE
+ url = https://github.com/juce-framework/JUCE.git
+[submodule "modules/chowdsp_utils"]
+ path = modules/chowdsp_utils
+ url = https://github.com/Chowdhury-DSP/chowdsp_utils
+[submodule "modules/libsamplerate"]
+ path = modules/libsamplerate
+ url = https://github.com/libsndfile/libsamplerate
+[submodule "modules/eigen"]
+ path = modules/eigen
+ url = https://gitlab.com/libeigen/eigen.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..f8e8f0e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,58 @@
+cmake_minimum_required(VERSION 3.15)
+set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment target")
+project(SmartAmp VERSION 1.3)
+
+set(CMAKE_CXX_STANDARD 17)
+
+add_subdirectory(modules)
+include_directories(modules)
+
+juce_set_aax_sdk_path(C:/SDKs/AAX_SDK/)
+
+set(JUCE_FORMATS AU VST3)
+
+# Build LV2 only on Linux
+if(UNIX AND NOT APPLE)
+ message(STATUS "Building LV2 plugin format")
+ list(APPEND JUCE_FORMATS LV2)
+endif()
+
+# Build AAX if SDK target exists
+if(TARGET juce_aax_sdk)
+ message(STATUS "Building AAX plugin format")
+ list(APPEND JUCE_FORMATS AAX)
+endif()
+
+juce_add_plugin(SmartAmp
+ COMPANY_NAME GuitarML
+ PLUGIN_MANUFACTURER_CODE GtML
+ PLUGIN_CODE Npi3
+ FORMATS ${JUCE_FORMATS}
+ ProductName "SmartAmp"
+ LV2_URI https://github.com/GuitarML/SmartAmp
+ ICON_BIG resources/logo.png
+ MICROPHONE_PERMISSION_ENABLED TRUE
+)
+
+# create JUCE header
+juce_generate_juce_header(SmartAmp)
+
+# add sources
+add_subdirectory(src)
+include_directories(src)
+add_subdirectory(resources)
+
+target_compile_definitions(SmartAmp
+ PUBLIC
+ JUCE_DISPLAY_SPLASH_SCREEN=0
+ JUCE_REPORT_APP_USAGE=0
+ JUCE_WEB_BROWSER=0
+ JUCE_USE_CURL=0
+ JUCE_VST3_CAN_REPLACE_VST2=0
+ JUCE_MODAL_LOOPS_PERMITTED=1
+)
+
+target_link_libraries(SmartAmp PUBLIC
+ juce_plugin_modules
+)
+
diff --git a/LICENSE b/LICENSE.txt
similarity index 100%
rename from LICENSE
rename to LICENSE.txt
diff --git a/README.md b/README.md
index 030be65..ca24727 100644
--- a/README.md
+++ b/README.md
@@ -20,30 +20,32 @@ Model training is done using PyTorch on pre recorded .wav samples. More info in
To share your best models, email the json files to smartguitarml@gmail.com and they may be included
in the latest release as a downloadable zip.
-Also see companion plugin, the [SmartGuitarPedal](https://github.com/GuitarML/SmartGuitarPedal)
+Also see companion plugin, the [SmartGuitarPedal](https://github.com/GuitarML/SmartGuitarPedal)
+Note: As of SmartAmp version 1.3, the custom model load was removed to simplify the plugin. To load user
+trained models, use the SmartGuitarPedal, which plays all models trained with PedalNetRT.
## Installing the plugin
-1. Download plugin (Windows 10, Mac, Ubuntu Linux) [here](https://github.com/keyth72/SmartGuitarAmp/releases)
-2. Copy to your DAW's VST directory (for Mac, use .dmg installer or copy AU/VST3 to desired folder)
+1. Download the appropriate plugin installer (Windows, Mac, Linux)
+2. Run the installer and follow the instructions. May need to reboot to allow your DAW to recognize the new plugin.
## Build Instructions
-1. Clone or download this repository.
-2. Download and install [JUCE](https://juce.com/) This project uses the "Projucer" application from the JUCE website.
-3. Download [Eigen](http://eigen.tuxfamily.org)
- Extract Eigen to a convenient location on your system (will be linked with Projucer)
-4. Open SmartGuitarPedal.jucer file with Projucer
-5. Add the / Eigen folder to "Header Search Paths" in Exporters -> Debug/Release
-6. Open and build project in Visual Studio (Windows), Xcode (Mac), or Code::Blocks/Makefile (Linux)
+### Build with Cmake
-Note: Make sure to build in Release mode unless actually debugging. Debug mode will not keep up with real time playing.
+```bash
+# Clone the repository
+$ git clone https://github.com/GuitarML/SmartGuitarAmp.git
+$ cd SmartGuitarAmp
-## Using your own custom trained models (or models from the TonePack)
+# initialize and set up submodules
+$ git submodule update --init --recursive
-Use the "Load Tone" button in the plugin to load tone models trained with PedalNetRT. The current channel's
-EQ/gain will be applied to the custom tone. Switching the clean/lead channel unloads the custom tone and
-reloads the channel's default tone.
+# build with CMake
+$ cmake -Bbuild
+$ cmake --build build --config Release
+```
+The binaries will be located in `SmartAmp/build/SmartAmp_artefacts/`
## License
This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details.
diff --git a/aax_builds.sh b/aax_builds.sh
new file mode 100644
index 0000000..1d2b560
--- /dev/null
+++ b/aax_builds.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+# exit on failure
+set -e
+
+# need to run in sudo mode on Mac
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ if [ "$EUID" -ne 0 ]; then
+ echo "This script must be run in sudo mode! Exiting..."
+ exit 1
+ fi
+fi
+
+if [[ "$*" = *debug* ]]; then
+ echo "Making DEBUG build"
+ build_config="Debug"
+else
+ echo "Making RELEASE build"
+ build_config="Release"
+fi
+
+# clean up old builds
+if [[ $* = *clean* ]]; then
+ echo "Cleaning previous build..."
+ rm -rf build-aax/
+fi
+
+sed_cmakelist()
+{
+ sed_args="$1"
+
+ if [[ "$OSTYPE" == "darwin"* ]]; then
+ sed -i '' "$sed_args" CMakeLists.txt
+ else
+ sed -i -e "$sed_args" CMakeLists.txt
+ fi
+}
+
+# set up OS-dependent variables
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ echo "Building for MAC"
+ AAX_PATH=~/Developer/AAX_SDK/
+ ilok_pass=$(more ~/Developer/ilok_pass)
+ aax_target_dir="/Library/Application Support/Avid/Audio/Plug-Ins"
+ TEAM_ID=$(more ~/Developer/mac_id)
+ TARGET_DIR="Mac"
+
+else # Windows
+ echo "Building for WINDOWS"
+ AAX_PATH=C:/SDKs/AAX_SDK/
+ ilok_pass=$(cat /c/SDKs/ilok_pass)
+ aax_target_dir="/c/Program Files/Common Files/Avid/Audio/Plug-Ins"
+ TARGET_DIR="Win64"
+fi
+
+# set up build AAX
+#sed_cmakelist "s~# juce_set_aax_sdk_path.*~juce_set_aax_sdk_path(${AAX_PATH})~"
+
+# cmake new builds
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ cmake -Bbuild-aax -GXcode -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="Developer ID Application" \
+ -DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM="$TEAM_ID" \
+ -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE="Manual" \
+ -D"CMAKE_OSX_ARCHITECTURES=x86_64" \
+ -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO \
+ -DCMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS="--timestamp" \
+ -DMACOS_RELEASE=ON
+
+ cmake --build build-aax --config $build_config --target SmartAmp_AAX | xcpretty
+
+else # Windows
+ cmake -Bbuild-aax -G"Visual Studio 16 2019" -A x64
+ cmake --build build-aax --config $build_config --parallel $(nproc) --target SmartAmp_AAX
+fi
+
+# sign with PACE
+aax_location=build-aax/SmartAmp_artefacts/$build_config/AAX/SmartAmp.aaxplugin
+wcguid="" # Update
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ /Applications/PACEAntiPiracy/Eden/Fusion/Current/bin/wraptool sign --verbose \
+ --account keyth72 \
+ --password "$ilok_pass" \
+ --wcguid $wcguid \
+ --dsig1-compat off \
+ --signid "Developer ID Application: Keith Bloemer" \
+ --in $aax_location \
+ --out $aax_location
+
+ /Applications/PACEAntiPiracy/Eden/Fusion/Current/bin/wraptool verify --verbose --in $aax_location
+
+else # Windows
+ wraptool sign --verbose \
+ --account keyth72 \
+ --password "$ilok_pass" \
+ --wcguid $wcguid \
+ --keyfile /c/SDKs/keith_aax_cert.p12 \
+ --keypassword "$ilok_pass" \
+ --in $aax_location \
+ --out $aax_location
+
+ wraptool verify --verbose --in $aax_location/Contents/x64/SmartAmp.aaxplugin
+fi
+
+# reset AAX SDK field...
+#sed_cmakelist "s~juce_set_aax_sdk_path.*~# juce_set_aax_sdk_path(NONE)~"
+
+rm -rf "$aax_target_dir/SmartAmp.aaxplugin"
+cp -R "$aax_location" "$aax_target_dir/SmartAmp.aaxplugin"
+
+if [[ "$*" = *deploy* ]]; then
+ set +e
+
+ ssh "smartguitarml@gmail.com" "rm -r ~/aax_builds/${TARGET_DIR}/SmartAmp.aaxplugin"
+ scp -r "$aax_location" "smartguitarml@gmail.com:~/aax_builds/${TARGET_DIR}/"
+fi
diff --git a/installers/linux/build_deb.sh b/installers/linux/build_deb.sh
new file mode 100644
index 0000000..20e0b3e
--- /dev/null
+++ b/installers/linux/build_deb.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# This script builds a .deb package for installing the VST3, and LV2 plugins on Linux
+
+# Set the app name and version here
+app_name=SmartAmp
+version=1.3
+
+
+# 1. Create the package directory structure and control file
+
+mkdir -p $app_name"/DEBIAN"
+
+printf "Package: $app_name\n\
+Version: $version\n\
+Section: custom\n\
+Priority: optional\n\
+Architecture: all\n\
+Essential: no\n\
+Installed-Size: 16480128\n\
+Maintainer: GuitarML\n\
+Description: GuitarML Plugin Debian Package (VST3, LV2)\n" > $app_name"/DEBIAN/control"
+
+
+# 2. Copy VST3 and LV2 plugins to the package directory (assumes project is already built)
+
+mkdir -p $app_name/usr/local/lib/vst3/
+echo "Copying ../../build/"$app_name"_artefacts/Release/VST3/"$app_name".vst3"
+cp -r "../../build/"$app_name"_artefacts/Release/VST3/"$app_name".vst3" $app_name"/usr/local/lib/vst3/"
+
+mkdir -p $app_name/usr/local/lib/lv2/
+echo "Copying ../../build/"$app_name"_artefacts/Release/LV2/"$app_name".lv2"
+cp -r "../../build/"$app_name"_artefacts/Release/LV2/"$app_name".lv2" $app_name"/usr/local/lib/lv2/"
+
+
+# 3. Build the .deb package and rename
+
+dpkg-deb --build $app_name
+
+mv $app_name.deb $app_name-Linux-x64-$version.deb
diff --git a/installers/mac/Intro.txt b/installers/mac/Intro.txt
new file mode 100644
index 0000000..d193c93
--- /dev/null
+++ b/installers/mac/Intro.txt
@@ -0,0 +1 @@
+This application will install the SmartAmp audio plugin version ##APPVERSION## to your computer.
diff --git a/installers/mac/SmartAmp.pkgproj b/installers/mac/SmartAmp.pkgproj
new file mode 100644
index 0000000..6e298f9
--- /dev/null
+++ b/installers/mac/SmartAmp.pkgproj
@@ -0,0 +1,2065 @@
+
+
+
+
+ PACKAGES
+
+
+ MUST-CLOSE-APPLICATION-ITEMS
+
+ MUST-CLOSE-APPLICATIONS
+
+ PACKAGE_FILES
+
+ DEFAULT_INSTALL_LOCATION
+ /
+ HIERARCHY
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Applications
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 509
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Application Support
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ BUNDLE_CAN_DOWNGRADE
+
+ BUNDLE_POSTINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ BUNDLE_PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ ../../bin/Mac/SmartAmp.component
+ PATH_TYPE
+ 1
+ PERMISSIONS
+ 493
+ TYPE
+ 3
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Components
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Plug-Ins
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Audio
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Automator
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Documentation
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Extensions
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Filesystems
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Frameworks
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Input Methods
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Internet Plug-Ins
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchAgents
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchDaemons
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PreferencePanes
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Preferences
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Printers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PrivilegedHelperTools
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1005
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickLook
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickTime
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Screen Savers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Scripts
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Services
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Widgets
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Library
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Shared
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1023
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Users
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ /
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+ PAYLOAD_TYPE
+ 0
+ PRESERVE_EXTENDED_ATTRIBUTES
+
+ SHOW_INVISIBLE
+
+ SPLIT_FORKS
+
+ TREAT_MISSING_FILES_AS_WARNING
+
+ VERSION
+ 5
+
+ PACKAGE_SCRIPTS
+
+ POSTINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ RESOURCES
+
+
+ PACKAGE_SETTINGS
+
+ AUTHENTICATION
+ 1
+ CONCLUSION_ACTION
+ 0
+ FOLLOW_SYMBOLIC_LINKS
+
+ IDENTIFIER
+ com.GuitarML.SmartAmp.SmartAmpAU
+ LOCATION
+ 0
+ NAME
+ AU
+ OVERWRITE_PERMISSIONS
+
+ PAYLOAD_SIZE
+ -1
+ REFERENCE_PATH
+
+ RELOCATABLE
+
+ USE_HFS+_COMPRESSION
+
+ VERSION
+ ##APPVERSION##
+
+ TYPE
+ 0
+ UUID
+ 69EED16E-B119-4D35-B464-12717823DE0E
+
+
+ MUST-CLOSE-APPLICATION-ITEMS
+
+ MUST-CLOSE-APPLICATIONS
+
+ PACKAGE_FILES
+
+ DEFAULT_INSTALL_LOCATION
+ /
+ HIERARCHY
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Applications
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 509
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Application Support
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ BUNDLE_CAN_DOWNGRADE
+
+ BUNDLE_POSTINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ BUNDLE_PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ ../../bin/Mac/SmartAmp.vst3
+ PATH_TYPE
+ 1
+ PERMISSIONS
+ 493
+ TYPE
+ 3
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ VST3
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Plug-Ins
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Audio
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Automator
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Documentation
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Extensions
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Filesystems
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Frameworks
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Input Methods
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Internet Plug-Ins
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchAgents
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchDaemons
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PreferencePanes
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Preferences
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Printers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PrivilegedHelperTools
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1005
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickLook
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickTime
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Screen Savers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Scripts
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Services
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Widgets
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Library
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Shared
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1023
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Users
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ /
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+ PAYLOAD_TYPE
+ 0
+ PRESERVE_EXTENDED_ATTRIBUTES
+
+ SHOW_INVISIBLE
+
+ SPLIT_FORKS
+
+ TREAT_MISSING_FILES_AS_WARNING
+
+ VERSION
+ 5
+
+ PACKAGE_SETTINGS
+
+ AUTHENTICATION
+ 1
+ CONCLUSION_ACTION
+ 0
+ FOLLOW_SYMBOLIC_LINKS
+
+ IDENTIFIER
+ com.GuitarML.SmartAmp.SmartAmpVST3
+ LOCATION
+ 0
+ NAME
+ VST3
+ OVERWRITE_PERMISSIONS
+
+ PAYLOAD_SIZE
+ -1
+ REFERENCE_PATH
+
+ RELOCATABLE
+
+ USE_HFS+_COMPRESSION
+
+ VERSION
+ ##APPVERSION##
+
+ TYPE
+ 0
+ UUID
+ 17D06D06-18AD-4175-AA45-047F4984BE1A
+
+
+ MUST-CLOSE-APPLICATION-ITEMS
+
+ MUST-CLOSE-APPLICATIONS
+
+ PACKAGE_FILES
+
+ DEFAULT_INSTALL_LOCATION
+ /Library/Application Support/Avid/Audio/Plug-Ins
+ HIERARCHY
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Applications
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 509
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+
+ BUNDLE_CAN_DOWNGRADE
+
+ BUNDLE_POSTINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ BUNDLE_PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ ../../build-aax/SmartAmp_artefacts/Release/AAX/SmartAmp.aaxplugin
+ PATH_TYPE
+ 1
+ PERMISSIONS
+ 493
+ TYPE
+ 3
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Plug-Ins
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Audio
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Avid
+ PATH_TYPE
+ 2
+ PERMISSIONS
+ 509
+ TYPE
+ 2
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Application Support
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Automator
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Documentation
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Extensions
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Filesystems
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Frameworks
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Input Methods
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Internet Plug-Ins
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchAgents
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ LaunchDaemons
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PreferencePanes
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Preferences
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 80
+ PATH
+ Printers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ PrivilegedHelperTools
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1005
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickLook
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ QuickTime
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Screen Savers
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Scripts
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Services
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Widgets
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ Library
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ CHILDREN
+
+
+ CHILDREN
+
+ GID
+ 0
+ PATH
+ Shared
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 1023
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 80
+ PATH
+ Users
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+
+ GID
+ 0
+ PATH
+ /
+ PATH_TYPE
+ 0
+ PERMISSIONS
+ 493
+ TYPE
+ 1
+ UID
+ 0
+
+ PAYLOAD_TYPE
+ 0
+ PRESERVE_EXTENDED_ATTRIBUTES
+
+ SHOW_INVISIBLE
+
+ SPLIT_FORKS
+
+ TREAT_MISSING_FILES_AS_WARNING
+
+ VERSION
+ 5
+
+ PACKAGE_SCRIPTS
+
+ POSTINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ PREINSTALL_PATH
+
+ PATH_TYPE
+ 0
+
+ RESOURCES
+
+
+ PACKAGE_SETTINGS
+
+ AUTHENTICATION
+ 1
+ CONCLUSION_ACTION
+ 0
+ FOLLOW_SYMBOLIC_LINKS
+
+ IDENTIFIER
+ com.GuitarML.SmartAmp.SmartAmpAAX
+ LOCATION
+ 0
+ NAME
+ AAX
+ OVERWRITE_PERMISSIONS
+
+ PAYLOAD_SIZE
+ -1
+ REFERENCE_PATH
+
+ RELOCATABLE
+
+ USE_HFS+_COMPRESSION
+
+ VERSION
+ ##APPVERSION##
+
+ TYPE
+ 0
+ UUID
+ 67DBD464-3B62-45EF-964B-549829FB1466
+
+
+ PROJECT
+
+ PROJECT_COMMENTS
+
+ NOTES
+
+
+
+ PROJECT_PRESENTATION
+
+ BACKGROUND
+
+ APPAREANCES
+
+ DARK_AQUA
+
+ LIGHT_AQUA
+
+
+ SHARED_SETTINGS_FOR_ALL_APPAREANCES
+
+
+ INSTALLATION TYPE
+
+ HIERARCHIES
+
+ INSTALLER
+
+ LIST
+
+
+ CHILDREN
+
+ DESCRIPTION
+
+ OPTIONS
+
+ HIDDEN
+
+ STATE
+ 1
+
+ PACKAGE_UUID
+ 69EED16E-B119-4D35-B464-12717823DE0E
+ TITLE
+
+ TYPE
+ 0
+ UUID
+ 32A671B5-085A-4D25-9B73-CA9157DA33C8
+
+
+ CHILDREN
+
+ DESCRIPTION
+
+ OPTIONS
+
+ HIDDEN
+
+ STATE
+ 1
+
+ PACKAGE_UUID
+ 17D06D06-18AD-4175-AA45-047F4984BE1A
+ TITLE
+
+ TYPE
+ 0
+ UUID
+ 6B0DDE9A-47F8-4615-BC79-4C475F3E41F7
+
+
+ CHILDREN
+
+ DESCRIPTION
+
+ OPTIONS
+
+ HIDDEN
+
+ STATE
+ 1
+
+ PACKAGE_UUID
+ 67DBD464-3B62-45EF-964B-549829FB1466
+ TITLE
+
+ TYPE
+ 0
+ UUID
+ 2BBC047A-58AB-4D9C-AFC1-F8BF00186CE3
+
+
+ REMOVED
+
+
+
+ MODE
+ 2
+
+ INSTALLATION_STEPS
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewIntroductionController
+ INSTALLER_PLUGIN
+ Introduction
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewReadMeController
+ INSTALLER_PLUGIN
+ ReadMe
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewLicenseController
+ INSTALLER_PLUGIN
+ License
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewDestinationSelectController
+ INSTALLER_PLUGIN
+ TargetSelect
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewInstallationTypeController
+ INSTALLER_PLUGIN
+ PackageSelection
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewInstallationController
+ INSTALLER_PLUGIN
+ Install
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS
+ ICPresentationViewSummaryController
+ INSTALLER_PLUGIN
+ Summary
+ LIST_TITLE_KEY
+ InstallerSectionTitle
+
+
+ INTRODUCTION
+
+ LOCALIZATIONS
+
+
+ LANGUAGE
+ English
+ VALUE
+
+ PATH
+ Intro.txt
+ PATH_TYPE
+ 3
+
+
+
+
+ LICENSE
+
+ LOCALIZATIONS
+
+
+ LANGUAGE
+ English
+ VALUE
+
+ PATH
+ LICENSE.txt
+ PATH_TYPE
+ 3
+
+
+
+ MODE
+ 0
+
+ README
+
+ LOCALIZATIONS
+
+
+ TITLE
+
+ LOCALIZATIONS
+
+
+ LANGUAGE
+ English
+ VALUE
+ SmartAmp
+
+
+
+
+ PROJECT_REQUIREMENTS
+
+ LIST
+
+ RESOURCES
+
+ ROOT_VOLUME_ONLY
+
+
+ PROJECT_SETTINGS
+
+ BUILD_FORMAT
+ 0
+ BUILD_PATH
+
+ PATH
+ ../../build
+ PATH_TYPE
+ 1
+
+ EXCLUDED_FILES
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .DS_Store
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove .DS_Store files
+ PROXY_TOOLTIP
+ Remove ".DS_Store" files created by the Finder.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .pbdevelopment
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove .pbdevelopment files
+ PROXY_TOOLTIP
+ Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ CVS
+ TYPE
+ 1
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .cvsignore
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .cvspass
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .svn
+ TYPE
+ 1
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .git
+ TYPE
+ 1
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ .gitignore
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove SCM metadata
+ PROXY_TOOLTIP
+ Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ classes.nib
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ designable.db
+ TYPE
+ 0
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ info.nib
+ TYPE
+ 0
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Optimize nib files
+ PROXY_TOOLTIP
+ Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.
+ STATE
+
+
+
+ PATTERNS_ARRAY
+
+
+ REGULAR_EXPRESSION
+
+ STRING
+ Resources Disabled
+ TYPE
+ 1
+
+
+ PROTECTED
+
+ PROXY_NAME
+ Remove Resources Disabled folders
+ PROXY_TOOLTIP
+ Remove "Resources Disabled" folders.
+ STATE
+
+
+
+ SEPARATOR
+
+
+
+ NAME
+ SmartAmp
+ PAYLOAD_ONLY
+
+ TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING
+
+
+
+ TYPE
+ 0
+ VERSION
+ 2
+
+
diff --git a/installers/mac/build_mac_installer.sh b/installers/mac/build_mac_installer.sh
new file mode 100644
index 0000000..f96b544
--- /dev/null
+++ b/installers/mac/build_mac_installer.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+script_file=SmartAmp.pkgproj
+
+app_version=$(cut -f 2 -d '=' <<< "$(grep 'CMAKE_PROJECT_VERSION:STATIC' ../../build/CMakeCache.txt)")
+echo "Setting app version: $app_version..."
+sed -i '' "s/##APPVERSION##/${app_version}/g" $script_file
+sed -i '' "s/##APPVERSION##/${app_version}/g" Intro.txt
+
+echo "Copying License..."
+cp ../../LICENSE.txt LICENSE.txt
+
+# build installer
+echo Building...
+/usr/local/bin/packagesbuild $script_file
+
+# reset version number
+sed -i '' "s/${app_version}/##APPVERSION##/g" $script_file
+sed -i '' "s/${app_version}/##APPVERSION##/g" Intro.txt
+
+# clean up license file
+rm LICENSE.txt
+
+# sign the installer package
+echo "Signing installer package..."
+TEAM_ID=$(more ~/Developer/mac_id)
+pkg_dir=SmartAmp_Installer_Packaged
+rm -Rf $pkg_dir
+mkdir $pkg_dir
+productsign -s "$TEAM_ID" ../../build/SmartAmp.pkg $pkg_dir/SmartAmp-signed.pkg
+
+echo "Notarizing installer package..."
+INSTALLER_PASS=$(more ~/Developer/mac_installer_pass)
+npx notarize-cli --file $pkg_dir/SmartAmp-signed.pkg --bundle-id com.GuitarML.SmartAmp --asc-provider "$TEAM_ID" --username smartguitarml@gmail.com --password "$INSTALLER_PASS"
+
+echo "Building disk image..."
+vol_name=Install_SmartAmp-$app_version
+hdiutil create "$vol_name.dmg" -fs HFS+ -srcfolder $pkg_dir -format UDZO -volname "$vol_name"
diff --git a/installers/windows/build_win_installer.sh b/installers/windows/build_win_installer.sh
new file mode 100644
index 0000000..d85f5ac
--- /dev/null
+++ b/installers/windows/build_win_installer.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+script_file=SmartAmp_Install_Script.iss
+
+app_version=$(cut -f 2 -d '=' <<< "$(grep 'CMAKE_PROJECT_VERSION:STATIC' ../../build/CMakeCache.txt)")
+echo "Setting app version: $app_version..."
+sed -i "s/##APPVERSION##/${app_version}/g" $script_file
+
+# build installer
+echo Building...
+$"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" $script_file
+
+# reset version number
+sed -i "s/${app_version}/##APPVERSION##/g" $script_file
+
+exec="SmartPedal-Win-$app_version.exe"
+direc=$PWD
+
+
+echo SUCCESS
diff --git a/mac_builds.sh b/mac_builds.sh
new file mode 100644
index 0000000..dabc07e
--- /dev/null
+++ b/mac_builds.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# exit on failure
+set -e
+
+# clean up old builds
+rm -Rf build/
+rm -Rf bin/*Mac*
+
+
+# cmake new builds
+TEAM_ID=$(more ~/Developer/mac_id)
+cmake -Bbuild -DMACOS_RELEASE=ON -GXcode -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="Developer ID Application" \
+ -DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM="$TEAM_ID" \
+ -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE="Manual" \
+ -D"CMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
+ -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO \
+ -DCMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS="--timestamp" \
+ -DMACOS_RELEASE=ON
+cmake --build build --config Release -j8 | xcpretty
+
+# copy builds to bin
+mkdir -p bin/Mac
+declare -a plugins=("SmartAmp")
+for plugin in "${plugins[@]}"; do
+ cp -R build/${plugin}_artefacts/Release/VST3/${plugin}.vst3 bin/Mac/${plugin}.vst3
+ cp -R build/${plugin}_artefacts/Release/AU/${plugin}.component bin/Mac/${plugin}.component
+done
+
+
+# run auval
+echo "Running AU validation..."
+rm -Rf ~/Library/Audio/Plug-Ins/Components/${plugin}.component
+cp -R build/${plugin}_artefacts/Release/AU/${plugin}.component ~/Library/Audio/Plug-Ins/Components
+manu=$(cut -f 6 -d ' ' <<< "$(grep 'PLUGIN_MANUFACTURER_CODE' CMakeLists.txt)")
+code=$(cut -f 6 -d ' ' <<< "$(grep 'PLUGIN_CODE' CMakeLists.txt)")
+
+set +e
+auval_result=$(auval -v aufx "$code" "$manu")
+auval_code="$?"
+echo "AUVAL code: $auval_code"
+
+if [ "$auval_code" != 0 ]; then
+ echo "$auval_result"
+ echo "auval FAIL!!!"
+ #exit 1
+else
+ echo "auval PASSED"
+fi
+
+# zip builds
+echo "Zipping builds..."
+VERSION=$(cut -f 2 -d '=' <<< "$(grep 'CMAKE_PROJECT_VERSION:STATIC' build/CMakeCache.txt)")
+(
+ cd bin
+ rm -f "SmartAmp-Mac-${VERSION}.zip"
+ zip -r "SmartAmp-Mac-${VERSION}.zip" Mac
+)
+
+# create installer
+echo "Creating installer..."
+(
+ cd installers/mac
+ bash build_mac_installer.sh
+)
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
new file mode 100644
index 0000000..4016a43
--- /dev/null
+++ b/modules/CMakeLists.txt
@@ -0,0 +1,62 @@
+add_subdirectory(JUCE)
+
+include(cmake/SubprojectVersion.cmake)
+subproject_version(JUCE juce_version)
+message(STATUS "VERSION for JUCE: ${juce_version}")
+
+# Link to libsamplerate
+set(BUILD_TESTING OFF CACHE BOOL "Don't build libsamplerate tests!")
+#add_subdirectory(libsamplerate)
+#subproject_version(libsamplerate libsamplerate_version)
+#message(STATUS "VERSION for libsamplerate: ${libsamplerate_version}")
+
+
+include(cmake/WarningFlags.cmake)
+add_library(juce_plugin_modules STATIC)
+#add_subdirectory(chowdsp_utils)
+add_subdirectory(eigen)
+
+target_link_libraries(juce_plugin_modules
+ PRIVATE
+ BinaryData
+ juce::juce_audio_utils
+ juce::juce_audio_plugin_client
+ juce::juce_dsp
+ eigen
+ #samplerate
+ #chowdsp_dsp
+ PUBLIC
+ juce::juce_recommended_config_flags
+ juce::juce_recommended_lto_flags
+ warning_flags
+)
+
+target_compile_definitions(juce_plugin_modules
+ PUBLIC
+ JUCE_DISPLAY_SPLASH_SCREEN=0
+ JUCE_REPORT_APP_USAGE=0
+ JUCE_WEB_BROWSER=0
+ JUCE_USE_CURL=0
+ JUCE_VST3_CAN_REPLACE_VST2=0
+ JucePlugin_Manufacturer="GuitarML"
+ JucePlugin_VersionString="${CMAKE_PROJECT_VERSION}"
+ JucePlugin_Name="${CMAKE_PROJECT_NAME}"
+ #CHOWDSP_USE_LIBSAMPLERATE=1
+ INTERFACE
+ $
+)
+
+target_include_directories(juce_plugin_modules
+ PUBLIC
+ eigen/Eigen
+ #libsamplerate/include
+ INTERFACE
+ $
+)
+
+set_target_properties(juce_plugin_modules PROPERTIES
+ POSITION_INDEPENDENT_CODE TRUE
+ VISIBILITY_INLINES_HIDDEN TRUE
+ C_VISBILITY_PRESET hidden
+ CXX_VISIBILITY_PRESET hidden
+)
diff --git a/modules/JUCE b/modules/JUCE
new file mode 160000
index 0000000..965d0ca
--- /dev/null
+++ b/modules/JUCE
@@ -0,0 +1 @@
+Subproject commit 965d0ca4be178c4a0000b116d460e15c30311992
diff --git a/modules/cmake/SubprojectVersion.cmake b/modules/cmake/SubprojectVersion.cmake
new file mode 100644
index 0000000..0529f66
--- /dev/null
+++ b/modules/cmake/SubprojectVersion.cmake
@@ -0,0 +1,20 @@
+# subproject_version( )
+#
+# Extract version of a sub-project, which was previously included with add_subdirectory().
+function(subproject_version subproject_name VERSION_VAR)
+ # Read CMakeLists.txt for subproject and extract project() call(s) from it.
+ file(STRINGS "${${subproject_name}_SOURCE_DIR}/CMakeLists.txt" project_calls REGEX "[ \t]*project\\(")
+ # For every project() call try to extract its VERSION option
+ foreach(project_call ${project_calls})
+ string(REGEX MATCH "VERSION[ ]+([^ )]+)" version_param "${project_call}")
+ if(version_param)
+ set(version_value "${CMAKE_MATCH_1}")
+ endif()
+ endforeach()
+ if(version_value)
+ set(${VERSION_VAR} "${version_value}" PARENT_SCOPE)
+ else()
+ message("WARNING: Cannot extract version for subproject '${subproject_name}'")
+ endif()
+
+endfunction(subproject_version)
diff --git a/modules/cmake/WarningFlags.cmake b/modules/cmake/WarningFlags.cmake
new file mode 100644
index 0000000..a57ae57
--- /dev/null
+++ b/modules/cmake/WarningFlags.cmake
@@ -0,0 +1,49 @@
+add_library(warning_flags INTERFACE)
+
+if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
+ target_compile_options(warning_flags INTERFACE
+ /W4 # base warning level
+ #/wd4458 # declaration hides class member (from Foley's GUI Magic)
+ /wd4505 # since VS2019 doesn't handle [[ maybe_unused ]] for static functions (RTNeural::debug_print)
+ /wd4244 # for XSIMD
+ )
+elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))
+ target_compile_options(warning_flags INTERFACE
+ -Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing -Wuninitialized
+ -Wunused-parameter -Wconversion -Wsign-compare -Wint-conversion
+ -Wconditional-uninitialized -Woverloaded-virtual -Wreorder
+ -Wconstant-conversion -Wsign-conversion -Wunused-private-field
+ -Wbool-conversion -Wno-extra-semi -Wunreachable-code
+ -Wzero-as-null-pointer-constant -Wcast-align
+ -Wno-inconsistent-missing-destructor-override -Wshift-sign-overflow
+ -Wnullable-to-nonnull-conversion -Wno-missing-field-initializers
+ -Wno-ignored-qualifiers -Wpedantic -Wno-pessimizing-move
+ # These lines suppress some custom warnings.
+ # Comment them out to be more strict.
+ -Wno-shadow-field-in-constructor
+ # Supress warnings from xsimd
+ -Wno-cast-align -Wno-shadow -Wno-implicit-int-conversion
+ -Wno-zero-as-null-pointer-constant -Wno-sign-conversion
+ # Needed for ARM processor, OSX versions below 10.14
+ -fno-aligned-allocation
+ )
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ target_compile_options(warning_flags INTERFACE
+ -Wall -Wextra -Wstrict-aliasing -Wuninitialized -Wunused-parameter
+ -Wsign-compare -Woverloaded-virtual -Wreorder -Wunreachable-code
+ -Wzero-as-null-pointer-constant -Wcast-align -Wno-implicit-fallthrough
+ -Wno-maybe-uninitialized -Wno-missing-field-initializers -Wno-pedantic
+ -Wno-ignored-qualifiers -Wno-unused-function -Wno-pessimizing-move
+ # From LV2 Wrapper
+ -Wno-parentheses -Wno-deprecated-declarations -Wno-redundant-decls
+ # For XSIMD
+ -Wno-zero-as-null-pointer-constant
+ # These lines suppress some custom warnings.
+ # Comment them out to be more strict.
+ -Wno-redundant-move
+ )
+
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "7.0.0")
+ target_compile_options(warning_flags INTERFACE "-Wno-strict-overflow")
+ endif()
+endif()
diff --git a/modules/eigen b/modules/eigen
new file mode 160000
index 0000000..bd393e1
--- /dev/null
+++ b/modules/eigen
@@ -0,0 +1 @@
+Subproject commit bd393e15c3d8dfa5423652c75921e026bcab83c5
diff --git a/plugins/SmartAmp/SmartAmp.jucer b/plugins/SmartAmp/SmartAmp.jucer
deleted file mode 100644
index fd4b537..0000000
--- a/plugins/SmartAmp/SmartAmp.jucer
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/plugins/SmartAmp/Source/.vscode/settings.json b/plugins/SmartAmp/Source/.vscode/settings.json
deleted file mode 100644
index 6ccdf75..0000000
--- a/plugins/SmartAmp/Source/.vscode/settings.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "files.associations": {
- "initializer_list": "cpp",
- "xstring": "cpp",
- "xutility": "cpp",
- "cmath": "cpp",
- "cstddef": "cpp",
- "cstdint": "cpp",
- "cstdio": "cpp",
- "cstdlib": "cpp",
- "cstring": "cpp",
- "cwchar": "cpp",
- "exception": "cpp",
- "ios": "cpp",
- "iosfwd": "cpp",
- "istream": "cpp",
- "limits": "cpp",
- "new": "cpp",
- "ostream": "cpp",
- "stdexcept": "cpp",
- "streambuf": "cpp",
- "string": "cpp",
- "system_error": "cpp",
- "type_traits": "cpp",
- "typeinfo": "cpp",
- "utility": "cpp",
- "xfacet": "cpp",
- "xiosbase": "cpp",
- "xlocale": "cpp",
- "xlocinfo": "cpp",
- "xlocnum": "cpp",
- "xmemory0": "cpp",
- "xstddef": "cpp",
- "xtr1common": "cpp"
- }
-}
\ No newline at end of file
diff --git a/plugins/SmartAmp/Source/Eq4Band.cpp b/plugins/SmartAmp/Source/Eq4Band.cpp
deleted file mode 100644
index 41659c9..0000000
--- a/plugins/SmartAmp/Source/Eq4Band.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- ==============================================================================
-
- Eq4Band
-
- ==============================================================================
-*/
-
-#include "Eq4Band.h"
-
-Eq4Band::Eq4Band()
-{
- setParameters(0.0, 0.0, 0.0, 0.0);
-}
-
-void Eq4Band::process (AudioBuffer& buffer,
- MidiBuffer& midiMessages,
- const int numSamples,
- const int numInputChannels)
-{
- for (int channel = 0; channel < numInputChannels; ++channel) {
- float* channelData = buffer.getWritePointer(channel);
- // For each sample in the block of audio, apply filter
- for (int sample = 0; sample < numSamples; ++sample) {
- spl0 = channelData[sample];
- s0 = spl0;
- low0 = (tmplMID = a0MID * s0 - b1MID * tmplMID + cDenorm);
- spl0 = (tmplLOW = a0LOW * low0 - b1LOW * tmplLOW + cDenorm);
- lowS0 = low0 - spl0;
- hi0 = s0 - low0;
- midS0 = (tmplHI = a0HI * hi0 - b1HI * tmplHI + cDenorm);
- highS0 = hi0 - midS0;
- spl0 = (spl0 * lVol + lowS0 * lmVol + midS0 * hmVol + highS0 * hVol);// * outVol;
-
- channelData[sample] = spl0;
- }
- }
-}
-
-void Eq4Band::setParameters(float bass_slider, float mid_slider, float treble_slider, float presence_slider)
-{
- lVol = exp(bass_slider / cAmpDB);
- lmVol = exp(mid_slider / cAmpDB);
- hmVol = exp(treble_slider / cAmpDB);
- hVol = exp(presence_slider / cAmpDB);
- outVol = exp(0.0 / cAmpDB);
-
- xHI = exp(-2.0 * pi * treble_frequency / srate);
- a0HI = 1.0 - xHI;
- b1HI = -xHI;
-
- xMID = exp(-2.0 * pi * mid_frequency / srate);
- a0MID = 1.0 - xMID;
- b1MID = -xMID;
-
- xLOW = exp(-2.0 * pi * bass_frequency / srate);
- a0LOW = 1.0 - xLOW;
- b1LOW = -xLOW;
-}
\ No newline at end of file
diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt
new file mode 100644
index 0000000..76c49db
--- /dev/null
+++ b/resources/CMakeLists.txt
@@ -0,0 +1,19 @@
+juce_add_binary_data(BinaryData SOURCES
+ amp_clean.jpg
+ amp_lead.jpg
+ amp_off.jpg
+ knob_silver.png
+ led_blue_off.png
+ led_blue_on.png
+ led_blue_on_off.png
+ led_red_off.png
+ led_red_on.png
+ power_switch_down.png
+ power_switch_up.png
+ ../models/bluej_clean_p0088.json
+ ../models/bluej_fullD_p0153.json
+)
+
+# Need to build BinaryData with -fPIC flag on Linux
+set_target_properties(BinaryData PROPERTIES
+ POSITION_INDEPENDENT_CODE TRUE)
diff --git a/resources/amp_clean.jpg b/resources/amp_clean.jpg
index 4231375..d39aa08 100644
Binary files a/resources/amp_clean.jpg and b/resources/amp_clean.jpg differ
diff --git a/resources/amp_lead.jpg b/resources/amp_lead.jpg
index 27bc615..76365ce 100644
Binary files a/resources/amp_lead.jpg and b/resources/amp_lead.jpg differ
diff --git a/resources/amp_off.jpg b/resources/amp_off.jpg
index 70c2e45..f25d4c0 100644
Binary files a/resources/amp_off.jpg and b/resources/amp_off.jpg differ
diff --git a/resources/amp_pic.png b/resources/amp_pic.png
index 6a835cf..b7e735e 100644
Binary files a/resources/amp_pic.png and b/resources/amp_pic.png differ
diff --git a/resources/guitarml.ico b/resources/guitarml.ico
new file mode 100644
index 0000000..1a334eb
Binary files /dev/null and b/resources/guitarml.ico differ
diff --git a/resources/logo.png b/resources/logo.png
new file mode 100644
index 0000000..20ea04b
Binary files /dev/null and b/resources/logo.png differ
diff --git a/plugins/SmartAmp/Source/Activations.cpp b/src/Activations.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/Activations.cpp
rename to src/Activations.cpp
diff --git a/plugins/SmartAmp/Source/Activations.h b/src/Activations.h
similarity index 100%
rename from plugins/SmartAmp/Source/Activations.h
rename to src/Activations.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..d4a376b
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,26 @@
+#add_subdirectory(headless)
+
+target_sources(SmartAmp PRIVATE
+ Activations.cpp
+ Activations.h
+ Convolution.cpp
+ Convolution.h
+ ConvolutionLayer.cpp
+ ConvolutionLayer.h
+ ConvolutionStack.cpp
+ ConvolutionStack.h
+ Eq4Band.cpp
+ Eq4Band.h
+ myLookAndFeel.cpp
+ myLookAndFeel.h
+ PluginEditor.cpp
+ PluginEditor.h
+ PluginProcessor.cpp
+ PluginProcessor.h
+ WaveNet.cpp
+ WaveNet.h
+ WaveNetLoader.cpp
+ WaveNetLoader.h
+)
+
+#target_precompile_headers(SmartAmp PRIVATE pch.h)
diff --git a/plugins/SmartAmp/Source/Convolution.cpp b/src/Convolution.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/Convolution.cpp
rename to src/Convolution.cpp
diff --git a/plugins/SmartAmp/Source/Convolution.h b/src/Convolution.h
similarity index 100%
rename from plugins/SmartAmp/Source/Convolution.h
rename to src/Convolution.h
diff --git a/plugins/SmartAmp/Source/ConvolutionLayer.cpp b/src/ConvolutionLayer.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/ConvolutionLayer.cpp
rename to src/ConvolutionLayer.cpp
diff --git a/plugins/SmartAmp/Source/ConvolutionLayer.h b/src/ConvolutionLayer.h
similarity index 100%
rename from plugins/SmartAmp/Source/ConvolutionLayer.h
rename to src/ConvolutionLayer.h
diff --git a/plugins/SmartAmp/Source/ConvolutionStack.cpp b/src/ConvolutionStack.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/ConvolutionStack.cpp
rename to src/ConvolutionStack.cpp
diff --git a/plugins/SmartAmp/Source/ConvolutionStack.h b/src/ConvolutionStack.h
similarity index 100%
rename from plugins/SmartAmp/Source/ConvolutionStack.h
rename to src/ConvolutionStack.h
diff --git a/src/Eq4Band.cpp b/src/Eq4Band.cpp
new file mode 100644
index 0000000..eec67c7
--- /dev/null
+++ b/src/Eq4Band.cpp
@@ -0,0 +1,76 @@
+/*
+ ==============================================================================
+
+ Eq4Band
+
+ ==============================================================================
+*/
+
+#include "Eq4Band.h"
+
+Eq4Band::Eq4Band()
+{
+ setParameters(0.0, 0.0, 0.0, 0.0);
+}
+
+void Eq4Band::process (const float* inData, float* outData,
+ MidiBuffer& midiMessages,
+ const int numSamples,
+ const int numInputChannels,
+ const int sampleRate)
+{
+ // Reset params if new sampleRate detected
+ if (srate != sampleRate) {
+ srate = sampleRate;
+ resetSampleRate();
+ }
+ for (int sample = 0; sample < numSamples; ++sample) {
+ spl0 = inData[sample];
+ s0 = spl0;
+ low0 = (tmplMID = a0MID * s0 - b1MID * tmplMID + cDenorm);
+ spl0 = (tmplLOW = a0LOW * low0 - b1LOW * tmplLOW + cDenorm);
+ lowS0 = low0 - spl0;
+ hi0 = s0 - low0;
+ midS0 = (tmplHI = a0HI * hi0 - b1HI * tmplHI + cDenorm);
+ highS0 = hi0 - midS0;
+ spl0 = (spl0 * lVol + lowS0 * lmVol + midS0 * hmVol + highS0 * hVol);// * outVol;
+
+ outData[sample] = spl0;
+ }
+}
+
+void Eq4Band::setParameters(float bass_slider, float mid_slider, float treble_slider, float presence_slider)
+{
+ lVol = exp(bass_slider / cAmpDB);
+ lmVol = exp(mid_slider / cAmpDB);
+ hmVol = exp(treble_slider / cAmpDB);
+ hVol = exp(presence_slider / cAmpDB);
+ outVol = exp(0.0 / cAmpDB);
+
+ xHI = exp(-2.0 * pi * treble_frequency / srate);
+ a0HI = 1.0 - xHI;
+ b1HI = -xHI;
+
+ xMID = exp(-2.0 * pi * mid_frequency / srate);
+ a0MID = 1.0 - xMID;
+ b1MID = -xMID;
+
+ xLOW = exp(-2.0 * pi * bass_frequency / srate);
+ a0LOW = 1.0 - xLOW;
+ b1LOW = -xLOW;
+}
+
+void Eq4Band::resetSampleRate()
+{
+ xHI = exp(-2.0 * pi * treble_frequency / srate);
+ a0HI = 1.0 - xHI;
+ b1HI = -xHI;
+
+ xMID = exp(-2.0 * pi * mid_frequency / srate);
+ a0MID = 1.0 - xMID;
+ b1MID = -xMID;
+
+ xLOW = exp(-2.0 * pi * bass_frequency / srate);
+ a0LOW = 1.0 - xLOW;
+ b1LOW = -xLOW;
+}
\ No newline at end of file
diff --git a/plugins/SmartAmp/Source/Eq4Band.h b/src/Eq4Band.h
similarity index 86%
rename from plugins/SmartAmp/Source/Eq4Band.h
rename to src/Eq4Band.h
index 0db4a78..01c501a 100644
--- a/plugins/SmartAmp/Source/Eq4Band.h
+++ b/src/Eq4Band.h
@@ -17,8 +17,9 @@ class Eq4Band
{
public:
Eq4Band();
- void process (AudioBuffer& buffer, MidiBuffer& midiMessages, const int numSamples, const int numInputChannels);
+ void process (const float* inData, float* outData, MidiBuffer& midiMessages, const int numSamples, const int numInputChannels, const int sampleRate);
void setParameters(float bass_slider, float mid_slider, float treble_slider, float presence_slider);
+ void resetSampleRate();
private:
// Tone Knob related variables
@@ -30,7 +31,7 @@ class Eq4Band
int treble_frequency = 5000;
//int presence_frequency = 5500;
- int srate = 44100; //TODO set from input
+ int srate = 44100; // Set default
float pi = 3.1415926;
diff --git a/plugins/SmartAmp/Source/PluginEditor.cpp b/src/PluginEditor.cpp
similarity index 53%
rename from plugins/SmartAmp/Source/PluginEditor.cpp
rename to src/PluginEditor.cpp
index 796910a..f862e0f 100644
--- a/plugins/SmartAmp/Source/PluginEditor.cpp
+++ b/src/PluginEditor.cpp
@@ -29,15 +29,6 @@ WaveNetVaAudioProcessorEditor::WaveNetVaAudioProcessorEditor (WaveNetVaAudioProc
addAndMakeVisible(ampOnButton);
ampOnButton.addListener(this);
- addAndMakeVisible(loadButton);
- loadButton.setButtonText("Load Tone");
- loadButton.addListener(this);
-
- addAndMakeVisible(modelLabel);
- modelLabel.setText(processor.loaded_tone_name, juce::NotificationType::dontSendNotification);
- modelLabel.setJustificationType(juce::Justification::left);
- modelLabel.setColour(juce::Label::textColourId, juce::Colours::black);
-
ampCleanLeadButton.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
@@ -53,189 +44,120 @@ WaveNetVaAudioProcessorEditor::WaveNetVaAudioProcessorEditor (WaveNetVaAudioProc
0.0);
addAndMakeVisible(ampLED);
+ presenceSliderAttach = std::make_unique(processor.treeState, PRESENCE_ID, ampPresenceKnob);
addAndMakeVisible(ampPresenceKnob);
ampPresenceKnob.setLookAndFeel(&SilverKnobLAF);
ampPresenceKnob.addListener(this);
- //ampPresenceKnob.setSkewFactorFromMidPoint(1000.0); // Not working because of custom lookAndFeel class
- ampPresenceKnob.setRange(-10.0, 10.0);
- ampPresenceKnob.setValue(processor.ampPresenceKnobState);
ampPresenceKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampPresenceKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 75, 20);
- ampPresenceKnob.setNumDecimalPlacesToDisplay(1);
ampPresenceKnob.setDoubleClickReturnValue(true, 0.0);
+ cleanBassSliderAttach = std::make_unique(processor.treeState, CLEAN_BASS_ID, ampCleanBassKnob);
addAndMakeVisible(ampCleanBassKnob);
ampCleanBassKnob.setLookAndFeel(&SilverKnobLAF);
ampCleanBassKnob.addListener(this);
- ampCleanBassKnob.setRange(-8.0, 8.0);
- ampCleanBassKnob.setValue(processor.ampCleanBassKnobState);
ampCleanBassKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampCleanBassKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampCleanBassKnob.setNumDecimalPlacesToDisplay(1);
ampCleanBassKnob.setDoubleClickReturnValue(true, 0.0);
+ cleanMidSliderAttach = std::make_unique(processor.treeState, CLEAN_MID_ID, ampCleanMidKnob);
addAndMakeVisible(ampCleanMidKnob);
ampCleanMidKnob.setLookAndFeel(&SilverKnobLAF);
ampCleanMidKnob.addListener(this);
- ampCleanMidKnob.setRange(-8.0, 8.0);
- ampCleanMidKnob.setValue(processor.ampCleanMidKnobState);
ampCleanMidKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampCleanMidKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampCleanMidKnob.setNumDecimalPlacesToDisplay(1);
ampCleanMidKnob.setDoubleClickReturnValue(true, 0.0);
+ cleanTrebleSliderAttach = std::make_unique(processor.treeState, CLEAN_TREBLE_ID, ampCleanTrebleKnob);
addAndMakeVisible(ampCleanTrebleKnob);
ampCleanTrebleKnob.setLookAndFeel(&SilverKnobLAF);
ampCleanTrebleKnob.addListener(this);
- ampCleanTrebleKnob.setRange(-8.0, 8.0);
- ampCleanTrebleKnob.setValue(processor.ampCleanTrebleKnobState);
ampCleanTrebleKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampCleanTrebleKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampCleanTrebleKnob.setNumDecimalPlacesToDisplay(1);
ampCleanTrebleKnob.setDoubleClickReturnValue(true, 0.0);
+ cleanGainSliderAttach = std::make_unique(processor.treeState, CLEAN_GAIN_ID, ampCleanGainKnob);
addAndMakeVisible(ampCleanGainKnob);
ampCleanGainKnob.setLookAndFeel(&SilverKnobLAF);
ampCleanGainKnob.addListener(this);
- ampCleanGainKnob.setRange(0.0, 20.0);
- ampCleanGainKnob.setValue(processor.ampCleanGainKnobState);
ampCleanGainKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampCleanGainKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampCleanGainKnob.setNumDecimalPlacesToDisplay(1);
- ampCleanGainKnob.setDoubleClickReturnValue(true, 10.0);
+ ampCleanGainKnob.setDoubleClickReturnValue(true, 0.5);
+ leadBassSliderAttach = std::make_unique(processor.treeState, LEAD_BASS_ID, ampLeadBassKnob);
addAndMakeVisible(ampLeadBassKnob);
ampLeadBassKnob.setLookAndFeel(&SilverKnobLAF);
ampLeadBassKnob.addListener(this);
- ampLeadBassKnob.setRange(-8.0, 8.0);
- ampLeadBassKnob.setValue(processor.ampLeadBassKnobState);
ampLeadBassKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampLeadBassKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampLeadBassKnob.setNumDecimalPlacesToDisplay(1);
ampLeadBassKnob.setDoubleClickReturnValue(true, 0.0);
+ leadMidSliderAttach = std::make_unique(processor.treeState, LEAD_MID_ID, ampLeadMidKnob);
addAndMakeVisible(ampLeadMidKnob);
ampLeadMidKnob.setLookAndFeel(&SilverKnobLAF);
ampLeadMidKnob.addListener(this);
- ampLeadMidKnob.setRange(-8.0, 8.0);
- ampLeadMidKnob.setValue(processor.ampLeadMidKnobState);
ampLeadMidKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
- ampLeadMidKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampLeadMidKnob.setNumDecimalPlacesToDisplay(1);
+ ampLeadMidKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);;
ampLeadMidKnob.setDoubleClickReturnValue(true, 0.0);
+ leadTrebleSliderAttach = std::make_unique(processor.treeState, LEAD_TREBLE_ID, ampLeadTrebleKnob);
addAndMakeVisible(ampLeadTrebleKnob);
ampLeadTrebleKnob.setLookAndFeel(&SilverKnobLAF);
ampLeadTrebleKnob.addListener(this);
- ampLeadTrebleKnob.setRange(-8.0, 8.0);
- ampLeadTrebleKnob.setValue(processor.ampLeadTrebleKnobState);
ampLeadTrebleKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampLeadTrebleKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampLeadTrebleKnob.setNumDecimalPlacesToDisplay(1);
ampLeadTrebleKnob.setDoubleClickReturnValue(true, 0.0);
+ leadGainSliderAttach = std::make_unique(processor.treeState, LEAD_GAIN_ID, ampLeadGainKnob);
addAndMakeVisible(ampLeadGainKnob);
ampLeadGainKnob.setLookAndFeel(&SilverKnobLAF);
ampLeadGainKnob.addListener(this);
- ampLeadGainKnob.setRange(0.0, 20.0);
- ampLeadGainKnob.setValue(processor.ampLeadGainKnobState);
ampLeadGainKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampLeadGainKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
- ampLeadGainKnob.setNumDecimalPlacesToDisplay(1);
- ampLeadGainKnob.setDoubleClickReturnValue(true, 10.0);
+ ampLeadGainKnob.setDoubleClickReturnValue(true, 0.5);
+ masterSliderAttach = std::make_unique(processor.treeState, MASTER_ID, ampMasterKnob);
addAndMakeVisible(ampMasterKnob);
ampMasterKnob.setLookAndFeel(&SilverKnobLAF);
ampMasterKnob.addListener(this);
- ampMasterKnob.setRange(-24.0, 0.0);
- ampMasterKnob.setValue(processor.ampMasterKnobState);
ampMasterKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
ampMasterKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20 );
- ampMasterKnob.setNumDecimalPlacesToDisplay(1);
- ampMasterKnob.setDoubleClickReturnValue(true, -12.0);
+ ampMasterKnob.setDoubleClickReturnValue(true, 0.5);
// Size of plugin GUI
- setSize (1085, 660);
+ setSize (1085, 540);
- // Load the preset wavenet json model from the project resources
- if (processor.custom_tone == 0) {
- processor.loadConfigAmp();
- } else {
- processor.loadConfig(processor.loaded_tone);
- }
+ processor.loadConfigAmp();
+ resetImages();
}
WaveNetVaAudioProcessorEditor::~WaveNetVaAudioProcessorEditor()
{
+ ampPresenceKnob.setLookAndFeel(nullptr);
+ ampCleanBassKnob.setLookAndFeel(nullptr);
+ ampCleanMidKnob.setLookAndFeel(nullptr);
+ ampCleanTrebleKnob.setLookAndFeel(nullptr);
+ ampCleanGainKnob.setLookAndFeel(nullptr);
+ ampLeadBassKnob.setLookAndFeel(nullptr);
+ ampLeadMidKnob.setLookAndFeel(nullptr);
+ ampLeadTrebleKnob.setLookAndFeel(nullptr);
+ ampLeadGainKnob.setLookAndFeel(nullptr);
+ ampMasterKnob.setLookAndFeel(nullptr);
}
//==============================================================================
void WaveNetVaAudioProcessorEditor::paint (Graphics& g)
{
- // (Our component is opaque, so we must completely fill the background with a solid colour)
- //g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
- if ( current_background == 1 && processor.amp_state == 1 && processor.amp_lead == 1 ) {
- // Redraw only the clipped part of the background image
- juce::Rectangle ClipRect = g.getClipBounds();
- g.drawImage(background_clean, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
-
- } else if (current_background == 1 && processor.amp_state == 1 && processor.amp_lead == 0) {
- // Redraw only the clipped part of the background image
- juce::Rectangle ClipRect = g.getClipBounds();
- g.drawImage(background_lead, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
-
- } else {
- // Redraw only the clipped part of the background image
- juce::Rectangle ClipRect = g.getClipBounds();
- g.drawImage(background_off, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
-
- }
- //g.drawImageAt(background, 0, 0);
- //g.setColour (Colours::white);
- //g.setFont (15.0f);
+ // Workaround for graphics on Windows builds (clipping code doesn't work correctly on Windows)
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+ g.drawImageAt(background_set, 0, 0); // Debug Line: Redraw entire background image
+#else
+// Redraw only the clipped part of the background image
+ juce::Rectangle ClipRect = g.getClipBounds();
+ g.drawImage(background_set, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
+#endif
- // Should really override the ToggleButton class, but being lazy here
- // Set On/Off amp graphic
- if (processor.amp_state == 0) {
- ampOnButton.setImages(true, true, true,
- ImageCache::getFromMemory(BinaryData::power_switch_down_png, BinaryData::power_switch_down_pngSize), 1.0, Colours::transparentWhite,
- Image(), 1.0, Colours::transparentWhite,
- ImageCache::getFromMemory(BinaryData::power_switch_down_png, BinaryData::power_switch_down_pngSize), 1.0, Colours::transparentWhite,
- 0.0);
- ampLED.setImages(true, true, true,
- ImageCache::getFromMemory(BinaryData::led_blue_off_png, BinaryData::led_blue_off_pngSize), 1.0, Colours::transparentWhite,
- Image(), 1.0, Colours::transparentWhite,
- ImageCache::getFromMemory(BinaryData::led_blue_off_png, BinaryData::led_blue_off_pngSize), 1.0, Colours::transparentWhite,
- 0.0);
- }
- else {
- ampOnButton.setImages(true, true, true,
- ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite,
- Image(), 1.0, Colours::transparentWhite,
- ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite,
- 0.0);
- ampLED.setImages(true, true, true,
- ImageCache::getFromMemory(BinaryData::led_blue_on_png, BinaryData::led_blue_on_pngSize), 1.0, Colours::transparentWhite,
- Image(), 1.0, Colours::transparentWhite,
- ImageCache::getFromMemory(BinaryData::led_blue_on_png, BinaryData::led_blue_on_pngSize), 1.0, Colours::transparentWhite,
- 0.0);
- }
- // Set clean/lead switch graphic
- if (processor.amp_lead == 0) {
- ampCleanLeadButton.setImages(true, true, true,
- ImageCache::getFromMemory(BinaryData::power_switch_down_png, BinaryData::power_switch_down_pngSize), 1.0, Colours::transparentWhite,
- Image(), 1.0, Colours::transparentWhite,
- ImageCache::getFromMemory(BinaryData::power_switch_down_png, BinaryData::power_switch_down_pngSize), 1.0, Colours::transparentWhite,
- 0.0);
- }
- else {
- ampCleanLeadButton.setImages(true, true, true,
- ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite,
- Image(), 1.0, Colours::transparentWhite,
- ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite,
- 0.0);
- }
}
void WaveNetVaAudioProcessorEditor::resized()
@@ -243,41 +165,22 @@ void WaveNetVaAudioProcessorEditor::resized()
// This is generally where you'll want to lay out the positions of any
// subcomponents in your editor..
- loadButton.setBounds(50, 40, 125, 25);
- modelLabel.setBounds(50, 65, 400, 25);
// Amp Widgets
- ampPresenceKnob.setBounds(97, 495, 75, 105);
- ampCleanBassKnob.setBounds(197, 495, 75, 105);
- ampCleanMidKnob.setBounds(280, 495, 75, 105);
- ampCleanTrebleKnob.setBounds(378, 495, 75, 105);
- ampCleanGainKnob.setBounds(456, 495, 75, 105);
- ampLeadBassKnob.setBounds(553, 495, 75, 105);
- ampLeadMidKnob.setBounds(636, 495, 75, 105);
- ampLeadTrebleKnob.setBounds(726, 495, 75, 105);
- ampLeadGainKnob.setBounds(806, 495, 75, 105);
- ampMasterKnob.setBounds(903, 495, 75, 105);
-
- ampOnButton.setBounds(9, 495, 35, 45);
- ampCleanLeadButton.setBounds(959, 495, 15, 25);
-
- ampLED.setBounds(975, 160, 15, 25);
-}
-
-void WaveNetVaAudioProcessorEditor::loadButtonClicked()
-{
- FileChooser chooser("Select a .json tone...",
- {},
- "*.json");
- if (chooser.browseForFileToOpen())
- {
- File file = chooser.getResult();
- processor.loadConfig(file);
- fname = file.getFileName();
- modelLabel.setText(fname, juce::NotificationType::dontSendNotification);
- processor.loaded_tone = file;
- processor.loaded_tone_name = fname;
- processor.custom_tone = 1;
- }
+ ampPresenceKnob.setBounds(97, 375, 75, 105);
+ ampCleanBassKnob.setBounds(197, 375, 75, 105);
+ ampCleanMidKnob.setBounds(280, 375, 75, 105);
+ ampCleanTrebleKnob.setBounds(378, 375, 75, 105);
+ ampCleanGainKnob.setBounds(456, 375, 75, 105);
+ ampLeadBassKnob.setBounds(553, 375, 75, 105);
+ ampLeadMidKnob.setBounds(636, 375, 75, 105);
+ ampLeadTrebleKnob.setBounds(726, 375, 75, 105);
+ ampLeadGainKnob.setBounds(806, 375, 75, 105);
+ ampMasterKnob.setBounds(903, 375, 75, 105);
+
+ ampOnButton.setBounds(9, 375, 35, 45);
+ ampCleanLeadButton.setBounds(959, 375, 15, 25);
+
+ ampLED.setBounds(975, 40, 15, 25);
}
void WaveNetVaAudioProcessorEditor::buttonClicked(juce::Button* button)
@@ -286,12 +189,9 @@ void WaveNetVaAudioProcessorEditor::buttonClicked(juce::Button* button)
ampOnButtonClicked();
} else if (button == &CleanLeadButton) {
ampCleanLeadButtonClicked();
- } else if (button == &loadButton) {
- loadButtonClicked();
}
}
-
void WaveNetVaAudioProcessorEditor::ampOnButtonClicked() {
if (processor.amp_state == 0) {
processor.amp_state = 1;
@@ -300,57 +200,39 @@ void WaveNetVaAudioProcessorEditor::ampOnButtonClicked() {
processor.amp_state = 0;
}
resetImages();
- repaint();
}
void WaveNetVaAudioProcessorEditor::ampCleanLeadButtonClicked() {
- if (processor.amp_lead == 0) {
- processor.amp_lead = 1;
+ if (processor.amp_lead == 1) {
+ processor.amp_lead = 0;
processor.loadConfigAmp();
processor.set_ampEQ(ampCleanBassKnob.getValue(), ampCleanMidKnob.getValue(), ampCleanTrebleKnob.getValue(), ampPresenceKnob.getValue());
}
- else if (processor.amp_lead == 1) {
- processor.amp_lead = 0;
+ else {
+ processor.amp_lead = 1;
processor.loadConfigAmp();
processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue());
}
- modelLabel.setText("", juce::NotificationType::dontSendNotification);
- processor.loaded_tone_name = "";
- processor.custom_tone = 0;
resetImages();
- repaint();
}
void WaveNetVaAudioProcessorEditor::sliderValueChanged(Slider* slider)
{
// Amp
- if (slider == &CleanGainKnob)
- processor.set_ampCleanDrive(slider->getValue());
- else if (slider == &LeadGainKnob)
- processor.set_ampLeadDrive(slider->getValue());
- else if (slider == &MasterKnob)
- processor.set_ampMaster(slider->getValue());
- else if (slider == &CleanBassKnob || slider == &CleanMidKnob || slider == &CleanTrebleKnob) {
- if (processor.amp_lead == 1)
+
+ if (slider == &CleanBassKnob || slider == &CleanMidKnob || slider == &CleanTrebleKnob) {
+ if (processor.amp_lead == 0)
processor.set_ampEQ(ampCleanBassKnob.getValue(), ampCleanMidKnob.getValue(), ampCleanTrebleKnob.getValue(), ampPresenceKnob.getValue());
- // Set knob states for saving positions when closing/reopening GUI
- processor.ampCleanBassKnobState = ampCleanBassKnob.getValue();
- processor.ampCleanMidKnobState = ampCleanMidKnob.getValue();
- processor.ampCleanTrebleKnobState = ampCleanTrebleKnob.getValue();
}
else if (slider == &LeadBassKnob || slider == &LeadMidKnob || slider == &LeadTrebleKnob) {
- if (processor.amp_lead == 0)
- processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue());
- // Set knob states for saving positions when closing/reopening GUI
- processor.ampLeadBassKnobState = ampLeadBassKnob.getValue();
- processor.ampLeadMidKnobState = ampLeadMidKnob.getValue();
- processor.ampLeadTrebleKnobState = ampLeadTrebleKnob.getValue();
+ if (processor.amp_lead == 1)
+ processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue());
}
else if (slider == &PresenceKnob) {
- if (processor.amp_lead == 1)
+ if (processor.amp_lead == 0)
processor.set_ampEQ(ampCleanBassKnob.getValue(), ampCleanMidKnob.getValue(), ampCleanTrebleKnob.getValue(), ampPresenceKnob.getValue());
- else if (processor.amp_lead == 0)
+ else if (processor.amp_lead == 1)
processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue());
}
@@ -358,6 +240,13 @@ void WaveNetVaAudioProcessorEditor::sliderValueChanged(Slider* slider)
void WaveNetVaAudioProcessorEditor::resetImages()
{
+ if (processor.amp_state == 1 && processor.amp_lead == 1 ) {
+ background_set = background_lead;
+ } else if (processor.amp_state == 1 && processor.amp_lead == 0) {
+ background_set = background_clean;
+ } else {
+ background_set = background_off;
+ }
// Set On/Off amp graphic
if (processor.amp_state == 0) {
ampOnButton.setImages(true, true, true,
@@ -384,7 +273,7 @@ void WaveNetVaAudioProcessorEditor::resetImages()
0.0);
}
// Set clean/lead switch graphic
- if (processor.amp_lead == 0) {
+ if (processor.amp_lead == 1) {
ampCleanLeadButton.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::power_switch_down_png, BinaryData::power_switch_down_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
@@ -398,4 +287,5 @@ void WaveNetVaAudioProcessorEditor::resetImages()
ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite,
0.0);
}
+ repaint();
}
diff --git a/plugins/SmartAmp/Source/PluginEditor.h b/src/PluginEditor.h
similarity index 66%
rename from plugins/SmartAmp/Source/PluginEditor.h
rename to src/PluginEditor.h
index b9c165e..edf3ced 100644
--- a/plugins/SmartAmp/Source/PluginEditor.h
+++ b/src/PluginEditor.h
@@ -30,7 +30,7 @@ class WaveNetVaAudioProcessorEditor : public AudioProcessorEditor,
void paint (Graphics&) override;
void resized() override;
-
+ void resetImages();
private:
// This reference is provided as a quick way for your editor to
@@ -60,17 +60,29 @@ class WaveNetVaAudioProcessorEditor : public AudioProcessorEditor,
Image background_clean = ImageCache::getFromMemory(BinaryData::amp_clean_jpg, BinaryData::amp_clean_jpgSize);
Image background_lead = ImageCache::getFromMemory(BinaryData::amp_lead_jpg, BinaryData::amp_lead_jpgSize);
Image background_off = ImageCache::getFromMemory(BinaryData::amp_off_jpg, BinaryData::amp_off_jpgSize);
+ Image background_set = ImageCache::getFromMemory(BinaryData::amp_clean_jpg, BinaryData::amp_clean_jpgSize);
int current_background = 1;
TextButton loadButton;
Label modelLabel;
juce::String fname;
virtual void buttonClicked(Button* button) override;
- void loadButtonClicked();
+ //void loadButtonClicked();
virtual void sliderValueChanged(Slider* slider) override;
void ampOnButtonClicked();
void ampCleanLeadButtonClicked();
- void resetImages();
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WaveNetVaAudioProcessorEditor)
+public:
+ std::unique_ptr cleanGainSliderAttach;
+ std::unique_ptr cleanBassSliderAttach;
+ std::unique_ptr cleanMidSliderAttach;
+ std::unique_ptr cleanTrebleSliderAttach;
+ std::unique_ptr leadGainSliderAttach;
+ std::unique_ptr leadBassSliderAttach;
+ std::unique_ptr leadMidSliderAttach;
+ std::unique_ptr leadTrebleSliderAttach;
+ std::unique_ptr presenceSliderAttach;
+ std::unique_ptr masterSliderAttach;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WaveNetVaAudioProcessorEditor)
};
diff --git a/plugins/SmartAmp/Source/PluginProcessor.cpp b/src/PluginProcessor.cpp
similarity index 61%
rename from plugins/SmartAmp/Source/PluginProcessor.cpp
rename to src/PluginProcessor.cpp
index ceef2af..dbe09e1 100644
--- a/plugins/SmartAmp/Source/PluginProcessor.cpp
+++ b/src/PluginProcessor.cpp
@@ -22,10 +22,51 @@ WaveNetVaAudioProcessor::WaveNetVaAudioProcessor()
.withOutput("Output", AudioChannelSet::stereo(), true)
#endif
),
- waveNet(1, 1, 1, 1, "linear", { 1 })
-
+ waveNet(1, 1, 1, 1, "linear", { 1 }),
+ treeState(*this, nullptr, "PARAMETER", { std::make_unique(CLEAN_GAIN_ID, CLEAN_GAIN_NAME, NormalisableRange(0.0f, 1.0f, 0.01f), 0.5f),
+ std::make_unique(CLEAN_BASS_ID, CLEAN_BASS_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+ std::make_unique(CLEAN_MID_ID, CLEAN_MID_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+ std::make_unique(CLEAN_TREBLE_ID, CLEAN_TREBLE_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+
+ std::make_unique(LEAD_GAIN_ID, LEAD_GAIN_NAME, NormalisableRange(0.0f, 1.0f, 0.01f), 0.5f),
+ std::make_unique(LEAD_BASS_ID, LEAD_BASS_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+ std::make_unique(LEAD_MID_ID, LEAD_MID_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+ std::make_unique(LEAD_TREBLE_ID, LEAD_TREBLE_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+
+ std::make_unique(PRESENCE_ID, PRESENCE_NAME, NormalisableRange(-8.0f, 8.0f, 0.01f), 0.0f),
+ std::make_unique(MASTER_ID, MASTER_NAME, NormalisableRange(0.0f, 1.0f, 0.01f), 0.5f) })
+
#endif
{
+ loadConfigAmp();
+
+ cleanBassParam = treeState.getRawParameterValue (CLEAN_BASS_ID);
+ cleanMidParam = treeState.getRawParameterValue (CLEAN_MID_ID);
+ cleanTrebleParam = treeState.getRawParameterValue (CLEAN_TREBLE_ID);
+ cleanGainParam = treeState.getRawParameterValue (CLEAN_GAIN_ID);
+ leadGainParam = treeState.getRawParameterValue (LEAD_GAIN_ID);
+ leadBassParam = treeState.getRawParameterValue (LEAD_BASS_ID);
+ leadMidParam = treeState.getRawParameterValue (LEAD_MID_ID);
+ leadTrebleParam = treeState.getRawParameterValue (LEAD_TREBLE_ID);
+ presenceParam = treeState.getRawParameterValue (PRESENCE_ID);
+ masterParam = treeState.getRawParameterValue (MASTER_ID);
+
+
+ auto cleanBassValue = static_cast (cleanBassParam->load());
+ auto cleanMidValue = static_cast (cleanMidParam->load());
+ auto cleanTrebleValue = static_cast (cleanTrebleParam->load());
+
+ auto leadBassValue = static_cast (leadBassParam->load());
+ auto leadMidValue = static_cast (leadMidParam->load());
+ auto leadTrebleValue = static_cast (leadTrebleParam->load());
+
+ auto presenceValue = static_cast (presenceParam->load());
+
+ if (amp_lead == 0) {
+ eq4band.setParameters(cleanBassValue, cleanMidValue, cleanTrebleValue, presenceValue);
+ } else {
+ eq4band.setParameters(leadBassValue, leadMidValue, leadTrebleValue, presenceValue);
+ }
}
WaveNetVaAudioProcessor::~WaveNetVaAudioProcessor()
@@ -139,29 +180,31 @@ void WaveNetVaAudioProcessor::processBlock (AudioBuffer& buffer, MidiBuff
// Setup Audio Data
const int numSamples = buffer.getNumSamples();
const int numInputChannels = getTotalNumInputChannels();
+ const int sampleRate = getSampleRate();
+
+ auto cleanGainValue = static_cast (cleanGainParam->load());
+ auto leadGainValue = static_cast (leadGainParam->load());
+ auto presenceValue = static_cast (presenceParam->load());
+ auto masterValue = static_cast (masterParam->load());
// Amp =============================================================================
if (amp_state == 1) {
- // EQ TODO before or after wavenet? (Presence; Bass, Mid, Treble for both channels)
- eq4band.process(buffer, midiMessages, numSamples, numInputChannels);
-
- if (amp_lead == 1) {// if clean channel eq/gain
-
- buffer.applyGain(ampCleanDrive);
+ if (amp_lead == 0) {// if clean channel eq/gain
+ buffer.applyGain(cleanGainValue * 8.0);
}
else {// else lead channel eq/gain
-
- buffer.applyGain(ampLeadDrive);
-
+ buffer.applyGain(leadGainValue * 8.0);
}
// Wavenet, load json for waveNet2 based on lead/clean switch
waveNet.process(buffer.getArrayOfReadPointers(), buffer.getArrayOfWritePointers(), buffer.getNumSamples());
+ eq4band.process(buffer.getReadPointer(0), buffer.getWritePointer(0), midiMessages, numSamples, numInputChannels, sampleRate);
+
// Master Volume
- buffer.applyGain(ampMaster);
+ buffer.applyGain(masterValue);
// Apply levelAdjust from model param (for adjusting quiet or loud models)
if ( waveNet.levelAdjust != 0.0 ) {
@@ -191,12 +234,31 @@ void WaveNetVaAudioProcessor::getStateInformation (MemoryBlock& destData)
// You should use this method to store your parameters in the memory block.
// You could do that either as raw data, or use the XML or ValueTree classes
// as intermediaries to make it easy to save and load complex data.
+ auto state = treeState.copyState();
+ std::unique_ptr xml (state.createXml());
+ xml->setAttribute ("amp_state", amp_state);
+ xml->setAttribute ("amp_lead", amp_lead);
+ copyXmlToBinary (*xml, destData);
}
void WaveNetVaAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
// You should use this method to restore your parameters from this memory block,
// whose contents will have been created by the getStateInformation() call.
+
+ std::unique_ptr xmlState (getXmlFromBinary (data, sizeInBytes));
+
+ if (xmlState.get() != nullptr)
+ {
+ if (xmlState->hasTagName (treeState.state.getType()))
+ {
+ treeState.replaceState (juce::ValueTree::fromXml (*xmlState));
+ amp_state = xmlState->getBoolAttribute ("amp_state");
+ amp_lead = xmlState->getBoolAttribute ("amp_lead");
+ if (auto* editor = dynamic_cast (getActiveEditor()))
+ editor->resetImages();
+ }
+ }
}
@@ -205,7 +267,7 @@ void WaveNetVaAudioProcessor::loadConfigAmp()
// Load Second Wavenet
this->suspendProcessing(true);
- if (amp_lead == 0) { // if lead on
+ if (amp_lead == 1) { // if lead on
WaveNetLoader loader2(BinaryData::bluej_fullD_p0153_json);
float levelAdjust = loader2.levelAdjust;
int numChannels2 = loader2.numChannels;
@@ -234,60 +296,13 @@ void WaveNetVaAudioProcessor::loadConfigAmp()
this->suspendProcessing(false);
}
-void WaveNetVaAudioProcessor::loadConfig(File configFile)
-{
- this->suspendProcessing(true);
- WaveNetLoader loader(dummyVar, configFile);
- float levelAdjust = loader.levelAdjust;
- int numChannels = loader.numChannels;
- int inputChannels = loader.inputChannels;
- int outputChannels = loader.outputChannels;
- int filterWidth = loader.filterWidth;
- std::vector dilations = loader.dilations;
- std::string activation = loader.activation;
- waveNet.setParams(inputChannels, outputChannels, numChannels, filterWidth, activation,
- dilations, levelAdjust);
- loader.loadVariables(waveNet);
- this->suspendProcessing(false);
-}
-
-float WaveNetVaAudioProcessor::convertLogScale(float in_value, float x_min, float x_max, float y_min, float y_max)
-{
- float b = log(y_max / y_min) / (x_max - x_min);
- float a = y_max / exp(b * x_max);
- float converted_value = a * exp(b * in_value);
- return converted_value;
-}
-
-void WaveNetVaAudioProcessor::set_ampCleanDrive(float db_ampCleanDrive)
-{
- ampCleanDrive = decibelToLinear(db_ampCleanDrive);
- ampCleanGainKnobState = db_ampCleanDrive;
-}
-
-void WaveNetVaAudioProcessor::set_ampLeadDrive(float db_ampLeadDrive)
-{
- ampLeadDrive = decibelToLinear(db_ampLeadDrive);
- ampLeadGainKnobState = db_ampLeadDrive;
-}
-
-void WaveNetVaAudioProcessor::set_ampMaster(float db_ampMaster)
-{
- ampMaster = decibelToLinear(db_ampMaster);
- ampMasterKnobState = db_ampMaster;
-}
void WaveNetVaAudioProcessor::set_ampEQ(float bass_slider, float mid_slider, float treble_slider, float presence_slider)
{
eq4band.setParameters(bass_slider, mid_slider, treble_slider, presence_slider);
-
- ampPresenceKnobState = presence_slider;
}
-float WaveNetVaAudioProcessor::decibelToLinear(float dbValue)
-{
- return powf(10.0, dbValue/20.0);
-}
+
//==============================================================================
// This creates new instances of the plugin..
diff --git a/plugins/SmartAmp/Source/PluginProcessor.h b/src/PluginProcessor.h
similarity index 68%
rename from plugins/SmartAmp/Source/PluginProcessor.h
rename to src/PluginProcessor.h
index 7315641..7f5aa9b 100644
--- a/plugins/SmartAmp/Source/PluginProcessor.h
+++ b/src/PluginProcessor.h
@@ -15,6 +15,31 @@
#include "WaveNetLoader.h"
#include "Eq4Band.h"
+#define CLEAN_GAIN_ID "cleangain"
+#define CLEAN_GAIN_NAME "CleanGain"
+#define CLEAN_BASS_ID "cleanbass"
+#define CLEAN_BASS_NAME "CleanBass"
+#define CLEAN_MID_ID "cleanmid"
+#define CLEAN_MID_NAME "CleanMid"
+#define CLEAN_TREBLE_ID "cleantreble"
+#define CLEAN_TREBLE_NAME "CleanTreble"
+
+#define LEAD_GAIN_ID "leadgain"
+#define LEAD_GAIN_NAME "LeadGain"
+#define LEAD_BASS_ID "leadbass"
+#define LEAD_BASS_NAME "LeadBass"
+#define LEAD_MID_ID "leadmid"
+#define LEAD_MID_NAME "LeadMid"
+#define LEAD_TREBLE_ID "leadtreble"
+#define LEAD_TREBLE_NAME "LeadTreble"
+
+#define PRESENCE_ID "presence"
+#define PRESENCE_NAME "Presence"
+#define MASTER_ID "master"
+#define MASTER_NAME "Master"
+
+
+
//==============================================================================
/**
*/
@@ -59,18 +84,8 @@ class WaveNetVaAudioProcessor : public AudioProcessor
void setStateInformation (const void* data, int sizeInBytes) override;
void loadConfigAmp();
- void loadConfig(File configFile);
-
- // Overdrive Pedal
- float convertLogScale(float in_value, float x_min, float x_max, float y_min, float y_max);
-
- // Amp
- void set_ampCleanDrive(float db_ampCleanDrive);
- void set_ampLeadDrive(float db_ampLeadDrive);
- void set_ampMaster(float db_ampMaster);
void set_ampEQ(float bass_slider, float mid_slider, float treble_slider, float presence_slider);
- float decibelToLinear(float dbValue);
// Pedal/amp states
int amp_state = 1; // 0 = off, 1 = on
@@ -79,27 +94,26 @@ class WaveNetVaAudioProcessor : public AudioProcessor
File loaded_tone;
juce::String loaded_tone_name;
- // Amp knob states
- float ampPresenceKnobState = 0.0;
- float ampCleanBassKnobState = 0.0;
- float ampCleanMidKnobState = 0.0;
- float ampCleanTrebleKnobState = 0.0;
- float ampCleanGainKnobState = 10.0;
- float ampLeadBassKnobState = 0.0;
- float ampLeadMidKnobState = 0.0;
- float ampLeadTrebleKnobState = 0.0;
- float ampLeadGainKnobState = 10.0;
- float ampMasterKnobState = -12.0;
+ AudioProcessorValueTreeState treeState;
private:
WaveNet waveNet; // Amp Clean Channel / Lead Channel
Eq4Band eq4band; // Amp EQ
+ std::atomic* presenceParam = nullptr;
+ std::atomic* cleanBassParam = nullptr;
+ std::atomic* cleanMidParam = nullptr;
+ std::atomic* cleanTrebleParam = nullptr;
+ std::atomic* cleanGainParam = nullptr;
+ std::atomic* leadGainParam = nullptr;
+ std::atomic* leadBassParam = nullptr;
+ std::atomic* leadMidParam = nullptr;
+ std::atomic* leadTrebleParam = nullptr;
+ std::atomic* masterParam = nullptr;
+
- // Amp
- float ampCleanDrive = 1.0;
- float ampLeadDrive = 1.0;
- float ampMaster = 1.0;
+ float previousGainValue = 0.5;
+ float previousMasterValue = 0.5;
var dummyVar;
diff --git a/plugins/SmartAmp/Source/WaveNet.cpp b/src/WaveNet.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/WaveNet.cpp
rename to src/WaveNet.cpp
diff --git a/plugins/SmartAmp/Source/WaveNet.h b/src/WaveNet.h
similarity index 100%
rename from plugins/SmartAmp/Source/WaveNet.h
rename to src/WaveNet.h
diff --git a/plugins/SmartAmp/Source/WaveNetLoader.cpp b/src/WaveNetLoader.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/WaveNetLoader.cpp
rename to src/WaveNetLoader.cpp
diff --git a/plugins/SmartAmp/Source/WaveNetLoader.h b/src/WaveNetLoader.h
similarity index 100%
rename from plugins/SmartAmp/Source/WaveNetLoader.h
rename to src/WaveNetLoader.h
diff --git a/plugins/SmartAmp/Source/myLookAndFeel.cpp b/src/myLookAndFeel.cpp
similarity index 100%
rename from plugins/SmartAmp/Source/myLookAndFeel.cpp
rename to src/myLookAndFeel.cpp
diff --git a/plugins/SmartAmp/Source/myLookAndFeel.h b/src/myLookAndFeel.h
similarity index 100%
rename from plugins/SmartAmp/Source/myLookAndFeel.h
rename to src/myLookAndFeel.h
diff --git a/validate.sh b/validate.sh
new file mode 100644
index 0000000..d04a40d
--- /dev/null
+++ b/validate.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+# install functions
+install_pluginval_linux()
+{
+ curl -L "https://github.com/Tracktion/pluginval/releases/download/latest_release/pluginval_Linux.zip" -o pluginval.zip
+ unzip pluginval > /dev/null
+ echo "./pluginval"
+}
+
+install_pluginval_mac()
+{
+ curl -L "https://github.com/Tracktion/pluginval/releases/download/latest_release/pluginval_macOS.zip" -o pluginval.zip
+ unzip pluginval > /dev/null
+ echo "pluginval.app/Contents/MacOS/pluginval"
+}
+
+install_pluginval_win()
+{
+ powershell -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest https://github.com/Tracktion/pluginval/releases/download/latest_release/pluginval_Windows.zip -OutFile pluginval.zip"
+ powershell -Command "Expand-Archive pluginval.zip -DestinationPath ."
+ echo "./pluginval.exe"
+}
+
+# install
+if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ pluginval=$(install_pluginval_linux)
+ plugin="Plugin/build/TS-M1N3_artefacts/Release/VST3/TS-M1N3.vst3"
+elif [[ "$OSTYPE" == "darwin"* ]]; then
+ pluginval=$(install_pluginval_mac)
+ plugin="Plugin/build/TS-M1N3_artefacts/VST3/TS-M1N3.vst3"
+else
+ pluginval=$(install_pluginval_win)
+ plugin="Plugin/build/TS-M1N3_artefacts/Release/VST3/TS-M1N3.vst3"
+fi
+
+echo "Pluginval installed at ${pluginval}"
+echo "Validating ${plugin}"
+
+n_tries=0
+result=1
+until [ "$n_tries" -ge 4 ] || [ "$result" -eq 0 ]
+do
+ $pluginval --strictness-level 8 --timeout-ms 90000 --validate-in-process --skip-gui-tests --validate $plugin
+ result=$?
+ n_tries=$((n_tries+1))
+done
+
+# clean up
+rm -Rf pluginval*
+exit $result
diff --git a/win_builds.sh b/win_builds.sh
new file mode 100644
index 0000000..a766615
--- /dev/null
+++ b/win_builds.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+build64(){
+ #cmake -Bbuild -G"Visual Studio 15 2017 Win64"
+ cmake -Bbuild -G "Visual Studio 16 2019" -A x64
+ cmake --build build --config Release -j4
+}
+
+# exit on failure
+set -e
+
+# clean up old builds
+rm -Rf build/
+rm -Rf bin/*Win64*
+
+# set up VST and ASIO paths
+sed -i -e "9s/#//" CMakeLists.txt
+sed -i -e "10s/#//" CMakeLists.txt
+sed -i -e '16s/#//' CMakeLists.txt
+
+# cmake new builds
+build64 &
+wait
+
+# copy builds to bin
+mkdir -p bin/Win64
+declare -a plugins=("SmartAmp")
+for plugin in "${plugins[@]}"; do
+ cp -R build/${plugin}_artefacts/Release/VST3/${plugin}.vst3 bin/Win64/${plugin}.vst3
+done
+
+# reset CMakeLists.txt
+#git restore CMakeLists.txt
+
+# zip builds
+VERSION=$(cut -f 2 -d '=' <<< "$(grep 'CMAKE_PROJECT_VERSION:STATIC' build/CMakeCache.txt)")
+(
+ cd bin
+ rm -f "SmartAmp-Win64-${VERSION}.zip"
+ tar -a -c -f "SmartAmp-Win64-${VERSION}.zip" Win64
+)
+
+# create installer
+echo "Creating installer..."
+(
+ cd installers/windows
+ bash build_win_installer.sh
+)