diff --git a/.gitignore b/.gitignore index b40d29e5b0a..fcf4c11cb8c 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,12 @@ target/ *.pdb packages.config +# XCode +Surge.xcworkspace/ +surge-au.xcodeproj/ +surge-vst2.xcodeproj/ +surge-vst3.xcodeproj/ +products/ # IntelliJ IDEA -.idea \ No newline at end of file +.idea diff --git a/README.md b/README.md index d8803e34dc7..06177ff608e 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,6 @@ It currently only builds on windows, but getting it to build on macOS again & Li [Releases are available here](https://github.com/kurasu/surge/releases) -Discussion at KVR-Forum [here](https://www.kvraudio.com/forum/viewtopic.php?f=1&t=511922) -Development Discussion at KVR-Forum [here](https://www.kvraudio.com/forum/viewtopic.php?f=33&t=511921) - ## Preparation First you need to grab all git submodules (needed to get the VST3 SDK) @@ -140,4 +137,5 @@ An example of setting the environment variable `VST2SDK_DIR` would be: ## References -* IRC channel #surgesynth @ irc.freenode.net + * Discussion at KVR-Forum [here](https://www.kvraudio.com/forum/viewtopic.php?f=1&t=511922) + * IRC channel #surgesynth @ irc.freenode.net diff --git a/build-osx.sh b/build-osx.sh index 97f072f7cd9..a7ede821bce 100755 --- a/build-osx.sh +++ b/build-osx.sh @@ -1,5 +1,10 @@ #!/bin/sh premake5 xcode4 -xcodebuild build -configuration Release -project surge-vst2.xcodeproj +if [ -n "$VST2SDK_DIR" ]; then + xcodebuild clean -project surge-vst2.xcodeproj + xcodebuild build -configuration Release -project surge-vst2.xcodeproj +fi +xcodebuild clean -project surge-vst3.xcodeproj xcodebuild build -configuration Release -project surge-vst3.xcodeproj +xcodebuild clean -project surge-au.xcodeproj xcodebuild build -configuration Release -project surge-au.xcodeproj diff --git a/libs/filesystem/filesystem.cpp b/libs/filesystem/filesystem.cpp index def47ee0140..e61aa880d00 100644 --- a/libs/filesystem/filesystem.cpp +++ b/libs/filesystem/filesystem.cpp @@ -12,53 +12,67 @@ #include "filesystem.h" namespace std::experimental::filesystem { - path::path(): - path("") - {} - - path::path(std::string filePath): - p(filePath) - {} - - path::operator std::string() { - return p; - } - - void path::append(std::string s) { - p.append("/"); - p.append(s); - } - - const char* path::c_str() { - return p.c_str(); - } - - std::string path::generic_string() { - return p; - } - - path path::filename() { - auto idx = this->p.find_last_of("/"); - path p(this->p.substr(idx+1)); - return p; - } - - std::string path::extension() { - auto idx = this->p.find_last_of("."); - return p.substr(idx); - } + // path class: + path::path(): + path("") + {} - file::file(std::string filePath): - p(filePath) - {} - - file::operator class path() { - return p; - } - - path file::path() { - return p; - } + path::path(std::string filePath): + p(filePath) + {} + + path::operator std::string() { + return p; + } + + void path::append(std::string s) { + p.append("/"); + p.append(s); + } + + const char* path::c_str() { + return p.c_str(); + } + + std::string path::generic_string() const { + return p; + } + + path path::filename() { + auto idx = this->p.find_last_of("/"); + path p(this->p.substr(idx+1)); + return p; + } + + std::string path::extension() { + auto idx = this->p.find_last_of("."); + return p.substr(idx); + } + // emd path class + + // file class: + file::file(std::string filePath): + p(filePath) + {} + + file::operator class path() { + return p; + } + + path file::path() const { + return p; + } + // end file class + + // directory_entry class: + directory_entry::directory_entry(class path p): + p(p) + {} + + path directory_entry::path() const { + return p; + } + // end directory_entry bool exists(path p) { FILE *file; @@ -107,9 +121,13 @@ namespace std::experimental::filesystem { // this needs to return the full path not just the relative path while ((dirp = readdir(dp)) != NULL) { - path newp = p; - newp.append( dirp->d_name ); - file res( newp.c_str() ); + string fname(dirp->d_name); + // Skip . and .. : https://github.com/kurasu/surge/issues/77 + if (fname.compare(".") == 0 || fname.compare("..") == 0) { + continue; + } + + file res(p.generic_string() + '/' + fname); files.push_back(res); } @@ -118,6 +136,65 @@ namespace std::experimental::filesystem { return files; } + + std::vector recursive_directory_iterator(const path& src) { + std::vector entries; + for(const auto& entry : directory_iterator(src)) { + const auto& p = entry.path(); + directory_entry e(p); + entries.emplace_back(e); + if (is_directory(p)) { + std::vector subdir = recursive_directory_iterator(p); + for(const auto& subdirEntry : subdir) { + entries.emplace_back(subdirEntry); + } + } + } + return entries; + } + + path relative(const path& p, const path& root) { + return path(p.generic_string().substr(root.generic_string().length())); + } + + void copy(const path& src, const path& dst, const copy_options options) { + std::ifstream in(src.generic_string()); + std::ofstream out(dst.generic_string()); + out << in.rdbuf(); + } + + void copy_recursive(const path& src, const path& target, const std::function& predicate) noexcept + { + try + { + for (const auto& dirEntry : recursive_directory_iterator(src)) + { + const auto& p = dirEntry.path(); + if (predicate(p)) + { + // Create path in target, if not existing. + const auto relativeSrc = relative(p, src); + auto targetStr = target.generic_string() + '/' + relativeSrc.generic_string(); + path targetPath(targetStr); + if (is_directory(p)) { + create_directories(targetPath); + } else { + // Copy to the targetParentPath which we just created. + copy(p, targetPath, copy_options::overwrite_existing); + } + } + } + } + catch (std::exception& e) + { + // std::cout << e.what(); + } + } + + void copy_recursive(const path& src, const path& target) noexcept + { + copy_recursive(src, target, [](path p) { return true; }); + } } #endif diff --git a/libs/filesystem/filesystem.h b/libs/filesystem/filesystem.h index b31c411de65..41590eff8c7 100644 --- a/libs/filesystem/filesystem.h +++ b/libs/filesystem/filesystem.h @@ -8,6 +8,8 @@ #ifndef Filesystem_h #define Filesystem_h +#include + #ifdef __APPLE__ #include "TargetConditionals.h" #ifdef TARGET_OS_MAC @@ -17,6 +19,7 @@ #include #include #include +#include namespace std::experimental::filesystem { class path { @@ -33,7 +36,7 @@ namespace std::experimental::filesystem { const char* c_str(); - std::string generic_string(); + std::string generic_string() const; path filename(); @@ -48,7 +51,16 @@ namespace std::experimental::filesystem { operator path(); - path path(); + path path() const; + }; + + class directory_entry { + public: + path p; + + directory_entry(path p); + + path path() const; }; bool exists(path p); @@ -58,6 +70,21 @@ namespace std::experimental::filesystem { bool is_directory(path p); std::vector directory_iterator(path p); + + std::vector recursive_directory_iterator(const path& src); + + path relative(const path& p, const path& root); + + enum copy_options { + overwrite_existing = 1 + }; + + void copy(const path& src, const path& dst, const copy_options options); + + // Exras: + void copy_recursive(const path& src, const path& target, const std::function& predicate) noexcept; + + void copy_recursive(const path& src, const path& target) noexcept; } #endif diff --git a/package-au.sh b/package-au.sh index 4d3069c9e2a..b8c4ff5abb9 100755 --- a/package-au.sh +++ b/package-au.sh @@ -6,6 +6,7 @@ PACKAGE_SRC_LOCATION="$RES_SRC_LOCATION/osx-au" BITMAP_SRC_LOCATION="$RES_SRC_LOCATION/bitmaps" BUNDLE_RES_SRC_LOCATION="$RES_SRC_LOCATION/osx-resources" EXEC_LOCATION="target/au/Release/Surge.dylib" +#EXEC_LOCATION="target/au/Debug/Surge-Debug.dylib" # output configs OUTPUT_DIR=products @@ -13,7 +14,7 @@ BUNDLE_NAME="Surge.component" BUNDLE_DIR="$OUTPUT_DIR/$BUNDLE_NAME" EXEC_TARGET_NAME="Surge" -echo Creating VST Bundle... +echo "Creating AudioUnit (AU) Bundle..." # create basic bundle structure @@ -32,3 +33,5 @@ cp $PACKAGE_SRC_LOCATION/* "$BUNDLE_DIR/Contents/" # copy bundle resources cp -R "$BUNDLE_RES_SRC_LOCATION" "$BUNDLE_DIR/Contents/Resources" cp $BITMAP_SRC_LOCATION/* "$BUNDLE_DIR/Contents/Resources/" +mkdir -p "$BUNDLE_DIR/Contents/Data" +cp -rf resources/data "$BUNDLE_DIR/Contents/Data" diff --git a/package-vst.sh b/package-vst.sh index 6c56bf68c5a..80e1dadae0c 100755 --- a/package-vst.sh +++ b/package-vst.sh @@ -6,6 +6,7 @@ PACKAGE_SRC_LOCATION="$RES_SRC_LOCATION/osx-vst2" BITMAP_SRC_LOCATION="$RES_SRC_LOCATION/bitmaps" BUNDLE_RES_SRC_LOCATION="$RES_SRC_LOCATION/osx-resources" EXEC_LOCATION="target/vst2/Release/Surge.dylib" +#EXEC_LOCATION="target/vst2/Debug/Surge-Debug.dylib" # output configs OUTPUT_DIR=products @@ -32,3 +33,6 @@ cp $PACKAGE_SRC_LOCATION/* "$BUNDLE_DIR/Contents/" # copy bundle resources cp -R "$BUNDLE_RES_SRC_LOCATION" "$BUNDLE_DIR/Contents/Resources" cp $BITMAP_SRC_LOCATION/* "$BUNDLE_DIR/Contents/Resources/" +mkdir -p "$BUNDLE_DIR/Contents/Data" +cp -rf resources/data "$BUNDLE_DIR/Contents/Data" + diff --git a/package-vst3.sh b/package-vst3.sh index 6c56bf68c5a..7d934074e90 100755 --- a/package-vst3.sh +++ b/package-vst3.sh @@ -32,3 +32,6 @@ cp $PACKAGE_SRC_LOCATION/* "$BUNDLE_DIR/Contents/" # copy bundle resources cp -R "$BUNDLE_RES_SRC_LOCATION" "$BUNDLE_DIR/Contents/Resources" cp $BITMAP_SRC_LOCATION/* "$BUNDLE_DIR/Contents/Resources/" +mkdir -p "$BUNDLE_DIR/Contents/Data" +cp -rf resources/data "$BUNDLE_DIR/Contents/Data" + diff --git a/premake5.lua b/premake5.lua index fbdb8afae72..607452f82be 100644 --- a/premake5.lua +++ b/premake5.lua @@ -9,8 +9,8 @@ language "C++" VSTGUI = "vst3sdk/vstgui4/vstgui/"; defines -{ - "VSTGUI_ENABLE_DEPRECATED_METHODS=0" +{ + "VSTGUI_ENABLE_DEPRECATED_METHODS=0" } floatingpoint "Fast" @@ -33,7 +33,7 @@ if (os.istarget("macosx")) then vectorextensions "SSE2" defines - { + { "PPC=0", "_MM_ALIGN16=__attribute__((aligned(16)))", "__forceinline=inline", @@ -43,21 +43,27 @@ if (os.istarget("macosx")) then "SSE_VERSION=3", "MAC_COCOA=1", "COCOA=1", - "OBJC_OLD_DISPATCH_PROTOTYPES=1" - } - - links + "OBJC_OLD_DISPATCH_PROTOTYPES=1" + } + + links { } - defines { "MAC=1", "PPC=0", "WINDOWS=0", } - - buildoptions { "-std=c++17", "-stdlib=libc++", "-DOBJC_OLD_DISPATCH_PROTOTYPES=1" } - links { "c++" } - buildoptions { "-mmacosx-version-min=10.9" } - linkoptions { "-mmacosx-version-min=10.9" } + defines { "MAC=1", "PPC=0", "WINDOWS=0", } + + buildoptions + { + "-std=c++17", "-stdlib=libc++", + "-DOBJC_OLD_DISPATCH_PROTOTYPES=1", + "-Wno-deprecated-declarations", -- Alas the AU V2 uses a whole bunch of deprecated stuff + "-Wno-inconsistent-missing-override" -- Surge was written before this was even a keyword! We do need to fix this though + } + links { "c++" } + buildoptions { "-mmacosx-version-min=10.9" } + linkoptions { "-mmacosx-version-min=10.9" } - platforms { "x64" } + platforms { "x64" } elseif (os.istarget("linux")) then @@ -68,32 +74,32 @@ elseif (os.istarget("linux")) then { "_MM_ALIGN16=__attribute__((aligned(16)))", "__forceinline=inline", - "forceinline=inline", + "forceinline=inline", "_aligned_malloc(x,a)=malloc(x)", "_aligned_free(x)=free(x)", "stricmp=strcasecmp", "SSE_VERSION=3", - "__cdecl=" - } - - links + "__cdecl=" + } + + links { } - defines { "WINDOWS=0" } - - buildoptions { "-std=c++17" } - links { } - buildoptions { } - linkoptions { } + defines { "WINDOWS=0" } + + buildoptions { "-std=c++17" } + links { } + buildoptions { } + linkoptions { } - platforms { "x64" } + platforms { "x64" } elseif (os.istarget("windows")) then - toolset "v141" - defines - { + toolset "v141" + defines + { "WINDOWS=1", "WIN32", "_WINDOWS", @@ -106,35 +112,35 @@ elseif (os.istarget("windows")) then } nuget { "libpng-msvc-x64:1.6.33.8807" } - - characterset "MBCS" - buildoptions { "/MP" } - - includedirs { - "libs/wtl" - } + + characterset "MBCS" + buildoptions { "/MP" } + + includedirs { + "libs/wtl" + } - flags { "StaticRuntime", "NoMinimalRebuild" } + flags { "StaticRuntime", "NoMinimalRebuild" } - platforms { "x64" } + platforms { "x64" } - configuration {} + configuration {} end includedirs { - "libs/xml", - "src/common/vt_dsp", - "src/common/thread", - "vst3sdk/vstgui4", - "vst3sdk", + "libs/xml", + "src/common/vt_dsp", + "src/common/thread", + "vst3sdk/vstgui4", + "vst3sdk", "libs/" -} + } -- PLUGIN COMMON -- function plugincommon() - targetprefix "" + targetprefix "" targetname "Surge" files { @@ -144,16 +150,16 @@ function plugincommon() "libs/xml/tinyxml.cpp", "libs/xml/tinyxmlerror.cpp", "libs/xml/tinyxmlparser.cpp", - "libs/filesystem/filesystem.cpp", + "libs/filesystem/filesystem.cpp", "src/common/vt_dsp/*.cpp", "src/common/thread/*.cpp", "vst3sdk/pluginterfaces/base/*.cpp", } includedirs { - "src/common", - "src/common/dsp", - "src/common/gui", + "src/common", + "src/common/dsp", + "src/common/gui", } if (os.istarget("macosx")) then @@ -165,11 +171,11 @@ function plugincommon() "-Wno-unused-variable" } - sysincludedirs { - "src/**", - "libs/**", - "vst3sdk/vstgui4", - } + sysincludedirs { + "src/**", + "libs/**", + "vst3sdk/vstgui4", + } files { @@ -177,8 +183,6 @@ function plugincommon() "src/mac/**.cpp", "src/mac/**.h", "libs/vst/*.mm", - "libs/AUPublic/*.cpp", - "libs/PublicUtility/*.cpp", VSTGUI .. "vstgui_mac.mm", VSTGUI .. "vstgui_uidescription_mac.mm", } @@ -194,7 +198,7 @@ function plugincommon() "src/mac" } - links { + links { "Accelerate.framework", "ApplicationServices.framework", "AudioUnit.framework", @@ -215,8 +219,8 @@ function plugincommon() buildoptions { "-Wno-unused-variable", - "`pkg-config gtkmm-3.0 --cflags`", - "-std=c++14" + "`pkg-config gtkmm-3.0 --cflags`", + "-std=c++14" } files @@ -242,13 +246,12 @@ function plugincommon() links { "pthread", - "stdc++fs" - + "stdc++fs" } - linkoptions { - "`pkg-config gtkmm-3.0 --libs`", - } + linkoptions { + "`pkg-config gtkmm-3.0 --libs`", + } elseif (os.istarget("windows")) then pchheader "precompiled.h" @@ -294,61 +297,60 @@ local VST24SDK = os.getenv("VST2SDK_DIR") if VST24SDK then - project "surge-vst2" - kind "SharedLib" - uuid "007990D5-2B46-481D-B38C-D83037CDF54B" - - defines - { - "TARGET_VST2=1", - } + project "surge-vst2" + kind "SharedLib" + uuid "007990D5-2B46-481D-B38C-D83037CDF54B" - plugincommon() + defines + { + "TARGET_VST2=1", + } - files { - "src/vst2/**.cpp", - "src/vst2/**.h", - VST24SDK .. "/public.sdk/source/vst2.x/**.cpp", - "vst3sdk/public.sdk/source/vst2.x/**.cpp", - VSTGUI .. "plugin-bindings/aeffguieditor.cpp", - } + plugincommon() - excludes { - VSTGUI .. "plugguieditor.cpp", - } + files { + "src/vst2/**.cpp", + "src/vst2/**.h", + VST24SDK .. "/public.sdk/source/vst2.x/**.cpp", + "vst3sdk/public.sdk/source/vst2.x/**.cpp", + VSTGUI .. "plugin-bindings/aeffguieditor.cpp", + } - includedirs { - "src/vst2", - VST24SDK, - "vst3sdk" - } + excludes { + VSTGUI .. "plugguieditor.cpp", + } - configuration { "Debug" } - targetdir "target/vst2/Debug" - targetsuffix "-Debug" + includedirs { + "src/vst2", + VST24SDK, + "vst3sdk" + } - configuration { "Release" } - targetdir "target/vst2/Release" + configuration { "Debug" } + targetdir "target/vst2/Debug" + targetsuffix "-Debug" - configuration {} + configuration { "Release" } + targetdir "target/vst2/Release" + configuration {} - if (os.istarget("macosx")) then + if (os.istarget("macosx")) then - targetname "Surge" - targetprefix "" - postbuildcommands { "./package-vst.sh" } + targetname "Surge" + targetprefix "" + postbuildcommands { "./package-vst.sh" } - files - { - "libs/vst/*.mm" - } + files + { + "libs/vst/*.mm" + } - elseif (os.istarget("windows")) then + elseif (os.istarget("windows")) then - linkoptions { "/DEF:resources\\windows-vst2\\surge.def" } + linkoptions { "/DEF:resources\\windows-vst2\\surge.def" } - end + end end -- VST3 PLUGIN -- @@ -366,32 +368,32 @@ defines plugincommon() files { - "src/vst3/**.cpp", - "src/vst3/**.h", - "vst3sdk/*.cpp", - "vst3sdk/base/source/*.cpp", - "vst3sdk/base/thread/source/*.cpp", - "vst3sdk/public.sdk/source/common/*.cpp", - "vst3sdk/public.sdk/source/main/pluginfactoryvst3.cpp", - "vst3sdk/public.sdk/source/vst/vstguieditor.cpp", - "vst3sdk/public.sdk/source/vst/vstinitiids.cpp", - "vst3sdk/public.sdk/source/vst/vstnoteexpressiontypes.cpp", - "vst3sdk/public.sdk/source/vst/vstsinglecomponenteffect.cpp", - "vst3sdk/public.sdk/source/vst/vstaudioeffect.cpp", - "vst3sdk/public.sdk/source/vst/vstcomponent.cpp", - "vst3sdk/public.sdk/source/vst/vstsinglecomponenteffect.cpp", - "vst3sdk/public.sdk/source/vst/vstcomponentbase.cpp", - "vst3sdk/public.sdk/source/vst/vstbus.cpp", - "vst3sdk/public.sdk/source/vst/vstparameters.cpp", - } + "src/vst3/**.cpp", + "src/vst3/**.h", + "vst3sdk/*.cpp", + "vst3sdk/base/source/*.cpp", + "vst3sdk/base/thread/source/*.cpp", + "vst3sdk/public.sdk/source/common/*.cpp", + "vst3sdk/public.sdk/source/main/pluginfactoryvst3.cpp", + "vst3sdk/public.sdk/source/vst/vstguieditor.cpp", + "vst3sdk/public.sdk/source/vst/vstinitiids.cpp", + "vst3sdk/public.sdk/source/vst/vstnoteexpressiontypes.cpp", + "vst3sdk/public.sdk/source/vst/vstsinglecomponenteffect.cpp", + "vst3sdk/public.sdk/source/vst/vstaudioeffect.cpp", + "vst3sdk/public.sdk/source/vst/vstcomponent.cpp", + "vst3sdk/public.sdk/source/vst/vstsinglecomponenteffect.cpp", + "vst3sdk/public.sdk/source/vst/vstcomponentbase.cpp", + "vst3sdk/public.sdk/source/vst/vstbus.cpp", + "vst3sdk/public.sdk/source/vst/vstparameters.cpp", + } excludes { - VSTGUI .. "aeffguieditor.cpp", + VSTGUI .. "aeffguieditor.cpp", } includedirs { - "src/vst3", - "vst3sdk" + "src/vst3", + "vst3sdk" } configuration { "Debug" } @@ -405,25 +407,25 @@ configuration {} if (os.istarget("macosx")) then - postbuildcommands { "./package-vst3.sh" } - - files - { + postbuildcommands { "./package-vst3.sh" } + + files + { "vst3sdk/public.sdk/source/main/macmain.cpp", - "vst3sdk/*.mm" - } + "vst3sdk/*.mm" + } elseif (os.istarget("windows")) then - linkoptions { "/DEF:resources\\windows-vst3\\surge.def" } + linkoptions { "/DEF:resources\\windows-vst3\\surge.def" } files { "vst3sdk/public.sdk/source/main/dllmain.cpp", } - flags { "NoImportLib" } - + flags { "NoImportLib" } + end -- AUDIO UNIT PLUGIN -- @@ -438,32 +440,34 @@ if (os.istarget("macosx")) then configuration { "Debug" } targetdir "target/au/Debug" - targetsuffix "-Debug" + targetsuffix "-Debug" configuration { "Release" } targetdir "target/au/Release" configuration {} - defines - { + defines + { "TARGET_AUDIOUNIT=1", "TARGET_AU=1", "PLUGGUI=1", } - links - { + links + { "AudioToolbox.framework", + "AudioUnit.framework", } - files + files { "src/au/**.cpp", + "src/au/**.mm", "src/au/**.h", - "libs/AudioUnits/AUPublic/**.cpp", - "libs/AudioUnits/AUPublic/**.h", - "libs/AudioUnits/PublicUtility/*.cpp", + "libs/AUPublic/**.cpp", + "libs/AUPublic/**.h", + "libs/PublicUtility/*.cpp", VSTGUI .. "plugin-bindings/plugguieditor.cpp", } @@ -474,15 +478,15 @@ if (os.istarget("macosx")) then "libs/AudioUnits/PublicUtility/CASpectralProcessor.cpp", } - includedirs + includedirs { - "src/au", + "src/au", "libs/", "libs/AudioUnits/AUPublic", "libs/AudioUnits/PublicUtility", } - excludes + excludes { VSTGUI .. "winfileselector.cpp", } diff --git a/resources/osx-au/Info.plist b/resources/osx-au/Info.plist index 4972834dc95..f1e41294f7a 100644 --- a/resources/osx-au/Info.plist +++ b/resources/osx-au/Info.plist @@ -32,7 +32,7 @@ CFBundleIconFile surgeicon CFBundleIdentifier - com.vemberaudio.audiounit.surge + com.vemberaudio.plugins.surge CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/resources/osx-vst2/Info.plist b/resources/osx-vst2/Info.plist index 90bad7f27ea..bdd21cdca9a 100644 --- a/resources/osx-vst2/Info.plist +++ b/resources/osx-vst2/Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile surgeicon.icns CFBundleIdentifier - com.vemberaudio.vst.surge + com.vemberaudio.plugins.surge CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/src/au/aulayer.cpp b/src/au/aulayer.cpp index 7f24b666e80..47b45b2a7cc 100644 --- a/src/au/aulayer.cpp +++ b/src/au/aulayer.cpp @@ -3,14 +3,20 @@ #include #include #include +#include "aulayer_cocoaui.h" typedef SurgeSynthesizer sub3_synth; +#ifdef GENERATE_AU_LOG +FILE* AULOG::lf = NULL; +#endif + //---------------------------------------------------------------------------------------------------- -aulayer::aulayer (AudioUnit au) : MusicDeviceBase (au,1,1) +aulayer::aulayer (AudioUnit au) : AUInstrumentBase (au,1,1) { plugin_instance = 0; + editor_instance = 0; } //---------------------------------------------------------------------------------------------------- @@ -22,6 +28,11 @@ aulayer::~aulayer() plugin_instance->~plugin(); _aligned_free(plugin_instance); } + + if( editor_instance ) + { + delete editor_instance; + } } //---------------------------------------------------------------------------------------------------- @@ -105,15 +116,15 @@ void aulayer::InitializePlugin() { if(!plugin_instance) { - fprintf( stderr, "SURGE:>> Constructing new plugin\n" ); - fprintf( stderr, " :>> BUILD %s on %s\n", __TIME__, __DATE__ ); + AULOG::log( "SURGE:>> Constructing new plugin\n" ); + AULOG::log( " :>> BUILD %s on %s\n", __TIME__, __DATE__ ); //sub3_synth* synth = (sub3_synth*)_aligned_malloc(sizeof(sub3_synth),16); //new(synth) sub3_synth(this); // FIXME: The VST uses a std::unique_ptr<> and we probably should here also plugin_instance = new SurgeSynthesizer( this ); - fprintf( stderr, "SURGE:>> Plugin Created\n" ); - } + AULOG::log( " :>> Plugin Created\n" ); + } assert(plugin_instance); } @@ -147,7 +158,7 @@ ComponentResult aulayer::Initialize() parameterIDlist_CFString[i] = 0; } - MusicDeviceBase::Initialize(); + AUInstrumentBase::Initialize(); return noErr; } @@ -155,7 +166,7 @@ ComponentResult aulayer::Initialize() void aulayer::Cleanup() { - MusicDeviceBase::Cleanup(); + AUInstrumentBase::Cleanup(); } //---------------------------------------------------------------------------------------------------- @@ -406,81 +417,50 @@ ComponentResult aulayer::Render( AudioUnitRenderActionFlags & ioActionFlags, con return noErr; } -//---------------------------------------------------------------------------------------------------- - -const char* getclamptxt(int id) -{ - switch(id) - { - case 1: return "Macro Parameters"; - case 2: return "Global / FX"; - case 3: return "Scene A Common"; - case 4: return "Scene A Osc"; - case 5: return "Scene A Osc Mixer"; - case 6: return "Scene A Filters"; - case 7: return "Scene A Envelopes"; - case 8: return "Scene A LFOs"; - case 9: return "Scene B Common"; - case 10: return "Scene B Osc"; - case 11: return "Scene B Osc Mixer"; - case 12: return "Scene B Filters"; - case 13: return "Scene B Envelopes"; - case 14: return "Scene B LFOs"; - } - return ""; -} //---------------------------------------------------------------------------------------------------- -ComponentResult aulayer::GetProperty(AudioUnitPropertyID iID, AudioUnitScope iScope, AudioUnitElement iElem, void* pData) -{ - if(iID == kAudioUnitProperty_ParameterValueName) - { - if(!IsInitialized()) return kAudioUnitErr_Uninitialized; - AudioUnitParameterValueName *aup = (AudioUnitParameterValueName*)pData; - char tmptxt[64]; - float f; - if(aup->inValue) f = *(aup->inValue); - else f = plugin_instance->getParameter01(plugin_instance->remapExternalApiToInternalId(aup->inParamID)); - plugin_instance->getParameterDisplay(plugin_instance->remapExternalApiToInternalId(aup->inParamID),tmptxt,f); - aup->outName = CFStringCreateWithCString(NULL,tmptxt,kCFStringEncodingUTF8); - return noErr; - } - else if(iID == kAudioUnitProperty_ParameterClumpName) - { - AudioUnitParameterNameInfo *aup = (AudioUnitParameterNameInfo*)pData; - aup->outName = CFStringCreateWithCString(NULL,getclamptxt(aup->inID),kCFStringEncodingUTF8); - return noErr; - } - else if(iID==kVmbAAudioUnitProperty_GetPluginCPPInstance) - { - void** pThis = (void**)(pData); - *pThis = (void*)plugin_instance; - return noErr; - } - return MusicDeviceBase::GetProperty(iID, iScope, iElem, pData); -} + //---------------------------------------------------------------------------------------------------- ComponentResult aulayer::GetPropertyInfo(AudioUnitPropertyID iID, AudioUnitScope iScope, AudioUnitElement iElem, UInt32& iSize, Boolean& fWritable) -{ - if(iID == kAudioUnitProperty_ParameterValueName) - { - iSize=sizeof(AudioUnitParameterValueName); - return noErr; - } - else if(iID == kAudioUnitProperty_ParameterClumpName) - { - iSize=sizeof(AudioUnitParameterNameInfo); - return noErr; - } - else if (iID==kVmbAAudioUnitProperty_GetPluginCPPInstance) - { - iSize=sizeof(void*); - return noErr; - } - return MusicDeviceBase::GetPropertyInfo(iID, iScope, iElem, iSize,fWritable); +{ + // OK so big todo here and in GetProperty + // 1: Switch these all to have an inScope--kAudioUnitScope_Global guard + // 2: Switch these to be a switch + // 3: Make Cocoa UI make the datasize the size of the view info. Take a look in juce_audio_plugin_client/AU/juce_AU_Wrapper.mm + // 4: That will probably core out since the calss isn't defined. That's OK! MOve on from there. + if( iScope == kAudioUnitScope_Global ) + { + switch( iID ) + { + case kAudioUnitProperty_CocoaUI: + iSize = sizeof (AudioUnitCocoaViewInfo); + fWritable = true; + return noErr; + break; + case kVmbAAudioUnitProperty_GetEditPointer: + iSize = sizeof( SurgeGUIEditor *); + fWritable = true; + return noErr; + break; + case kAudioUnitProperty_ParameterValueName: + iSize = sizeof( AudioUnitParameterValueName ); + return noErr; + break; + case kAudioUnitProperty_ParameterClumpName: + iSize = sizeof( AudioUnitParameterNameInfo ); + return noErr; + break; + case kVmbAAudioUnitProperty_GetPluginCPPInstance: + iSize = sizeof( void* ); + return noErr; + break; + } + } + + return AUInstrumentBase::GetPropertyInfo(iID, iScope, iElem, iSize,fWritable); } //---------------------------------------------------------------------------------------------------- @@ -518,6 +498,7 @@ ComponentResult aulayer::SaveState(CFPropertyListRef * plist) // append raw chunk data // TODO det är här det finns ze memleaks!!! + // TODO It is here that we can find memory leaks!!! CFMutableDictionaryRef dict = (CFMutableDictionaryRef)*plist; void* data; @@ -538,7 +519,7 @@ ComponentResult aulayer::GetPresets (CFArrayRef *outData) const // Returns an array of AUPreset that contain a number and name for each of the presets. //The number of each preset must be greater (or equal to) zero, and the numbers need not be ordered or contiguous. //The name of each preset can be presented to the user as a means of identifying each preset. - // The CFArrayRef should be released by the caller. + // The CFArrayRef should be released by the caller. if(!IsInitialized()) return kAudioUnitErr_Uninitialized; @@ -591,7 +572,7 @@ ComponentResult aulayer::GetParameterList(AudioUnitScope inScope, AudioUnitParam outNumParameters = 0; return noErr; } - + outNumParameters = n_total_params; if(outParameterList) memcpy(outParameterList,parameterIDlist,sizeof(AudioUnitParameterID)*n_total_params); return noErr; @@ -602,8 +583,9 @@ ComponentResult aulayer::GetParameterList(AudioUnitScope inScope, AudioUnitParam ComponentResult aulayer::GetParameterInfo( AudioUnitScope inScope, AudioUnitParameterID inParameterID, - AudioUnitParameterInfo &outParameterInfo) + AudioUnitParameterInfo &outParameterInfo) { + //FIXME: I think this code can be a bit tighter and cleaner, but it works OK for now outParameterInfo.unit = kAudioUnitParameterUnit_Generic; outParameterInfo.minValue = 0.f; outParameterInfo.maxValue = 1.f; @@ -653,13 +635,17 @@ ComponentResult aulayer::GetParameter(AudioUnitParameterID inID, AudioUnitScope ComponentResult aulayer::SetParameter(AudioUnitParameterID inID, AudioUnitScope inScope, AudioUnitElement inElement, Float32 inValue, UInt32 inBufferOffsetInFrames) { - if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidParameter; + if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidParameter; if(inID >= n_total_params) return kAudioUnitErr_InvalidParameter; if(!IsInitialized()) return kAudioUnitErr_Uninitialized; plugin_instance->setParameter01(plugin_instance->remapExternalApiToInternalId(inID),inValue,true); // TODO lägg till signalering frÃ¥n här -> editor om den är öppen // glöm inte att mappa om parametrarna ifall det är ableton live som är host // EDIT gör det hellre med en threadsafe buffer i sub3_synth + // Translated: + // TODO: Add signaling from here to the editor, if the editor is open + // Do not forget to map the parameters if Ableton Live is the host + // EDIT: Do it rather with a threadsafe buffer within sub3_synth return noErr; } @@ -788,6 +774,7 @@ class VSTGUIAUView : public AUCarbonViewBase CRect fsize = editor->getFrame ()->getViewSize (fsize); SizeControl (mCarbonPane, fsize.width (), fsize.height ()); // CreateEventLoopTimer verkar sno focus och göra sÃ¥ den tappar mouseup-events + // CreateEventLoopTimer Sees no focus OR seems to steal the? focus, and then starts losing mouse-up events CreateEventLoopTimer (kEventDurationSecond, kEventDurationSecond / 30); HIViewSetVisible (platformControl, true); HIViewSetNeedsDisplay (platformControl, true); diff --git a/src/au/aulayer.h b/src/au/aulayer.h index 381ef1827f4..5a2d5dcd9a8 100644 --- a/src/au/aulayer.h +++ b/src/au/aulayer.h @@ -3,7 +3,7 @@ //------------------------------------------------------------------------------------------------------- #pragma once -#include "MusicDeviceBase.h" +#include "AUInstrumentBase.h" #include "surge_auversion.h" #include "SurgeStorage.h" @@ -12,12 +12,45 @@ class SurgeGUIEditor; class SurgeSynthesizer; typedef SurgeSynthesizer plugin; +#define GENERATE_AU_LOG +struct AULOG +{ +#ifdef GENERATE_AU_LOG + static FILE* lf; + + static void log( const char* format, ... ) + { + if( lf == NULL ) + { + char fname[ 1024 ]; + sprintf( fname, "%s/Library/Logs/Surge.log", getenv( "HOME" ) ); + lf = fopen( fname, "a" ); + } + va_list args; + va_start( args, format ); + vfprintf( stderr, format, args ); + va_end( args ); + if( lf != NULL ) + { + va_start( args, format ); + vfprintf( lf, format, args ); + va_end( args ); + fflush( lf ); + } + + } +#else + static void log( const char* format, ... ) { } +#endif +}; + //------------------------------------------------------------------------------------------------------- const CFStringRef rawchunkname = CFSTR("VmbA_chunk"); enum { kVmbAAudioUnitProperty_GetPluginCPPInstance = 70000, + kVmbAAudioUnitProperty_GetEditPointer = 70001, }; // event @@ -27,7 +60,7 @@ struct AuMIDIEvent long inStartFrame; }; -class aulayer : public MusicDeviceBase +class aulayer : public AUInstrumentBase { public: aulayer (AudioUnit au); @@ -113,7 +146,9 @@ class aulayer : public MusicDeviceBase void InitializePlugin(); bool IsPluginInitialized(); + // FIXME: Move to std::unique_ptr<> plugin *plugin_instance; + SurgeGUIEditor *editor_instance; protected: //void handleEvent(VstEvent*); AuMIDIEvent eventbuffer[1024]; diff --git a/src/au/aulayer_cocoaui.h b/src/au/aulayer_cocoaui.h new file mode 100644 index 00000000000..e4cf034a831 --- /dev/null +++ b/src/au/aulayer_cocoaui.h @@ -0,0 +1,13 @@ +// +// aulayer_cocoaui.h +// surge-au +// +// Created by Paul Walker on 12/10/18. +// + +#ifndef aulayer_cocoaui_h +#define aulayer_cocoaui_h + +#import + +#endif /* aulayer_cocoaui_h */ diff --git a/src/au/aulayer_cocoaui.mm b/src/au/aulayer_cocoaui.mm new file mode 100644 index 00000000000..d4689854bfb --- /dev/null +++ b/src/au/aulayer_cocoaui.mm @@ -0,0 +1,300 @@ +// +// aulayer_cocoaui.mm +// surge-au +// +// Created by Paul Walker on 12/10/18. +// +/* + OK so how do cocoa uis work in AU2? There's two things + + 1: You return a valid AudioUnitViewInfo which contains basically a bundle URL and class name. You implement this in GetProperty in + response to kAudioUnitPropert_CocoaUI + + 2: You make that class that you return match the AUCococUIBase protocol which requires it to be able to create a frame + + Now the question is how does that frame get a reference to your audio unit? Well there's trick three, which is the uiForAudioUnit has to + use the property mechanism to get a reference to an editor. In this case I do that by sending the kVmBAudioUnitPropert_GetEditPointer + which I basically just made up. That returns (in this case) a pointer to a SurgeGUIEditor which uses a subset of the VST api + (only the public API) to give you a drawable element. + + The other trick to make this all work is that Surge itself works by having parameter changes which imapct other parameter changes + (like when you change patch number it changes patch name) just update parameters and not redraw. This makes sense for all + the obvious reasons (thread locality; bunched drawing; etc...). You can see the refresh_param_quuee and refresh_control_queue + implementation which just keep getting stacked up. But to unstack them you need to call a redraw, basically, and that's what the + editor ::idle method does. So the final thing to make it all work is to spin up a CFRunLoopTimer (not an NSTImer, note; I tried and + that's not the way to go) to call ::idle every 50ms. + + And that's what this code does. + + */ + +#include +#import +#import +#include "aulayer.h" +#include "aulayer_cocoaui.h" +#include + + + +@interface SurgeNSView : NSView +{ + SurgeGUIEditor *editController; + CFRunLoopTimerRef idleTimer; + float lastScale; + NSSize underlyingUISize; + bool setSizeByZoom; // use this flag to see if resize comes from here or from external + +} + +- (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size; +- (void) doIdle; +- (void) dealloc; +- (void) setFrame:(NSRect)newSize; + +@end + +@interface SurgeCocoaUI : NSObject +{ +} + +- (NSString *) description; +@end + +@implementation SurgeCocoaUI +- (NSView *) uiViewForAudioUnit: (AudioUnit) inAudioUnit + withSize: (NSSize) inPreferredSize +{ + // Remember we end up being called here because that's what AUCocoaUIView does in the initiation collaboration with hosts + AULOG::log( "uiViewForAudioUnit %s on %s\n", __TIME__, __DATE__ ); + AULOG::log( "prefSize is %f %f\n", inPreferredSize.width, inPreferredSize.height ); + + SurgeGUIEditor* editController = 0; + UInt32 size = sizeof (SurgeGUIEditor *); + if (AudioUnitGetProperty (inAudioUnit, kVmbAAudioUnitProperty_GetEditPointer, kAudioUnitScope_Global, 0, &editController, &size) != noErr) + return nil; + + return [[[SurgeNSView alloc] initWithSurge:editController preferredSize:inPreferredSize] autorelease]; + // return nil; +} + +- (unsigned int)interfaceVersion { + return 0; +} + +- (NSString *) description { + return [NSString stringWithUTF8String: "Surge View"]; +} + +@end + +void timerCallback( CFRunLoopTimerRef timer, void *info ) +{ + SurgeNSView *view = (SurgeNSView *)info; + [view doIdle]; +} + +@implementation SurgeNSView +- (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size +{ + self = [super initWithFrame: NSMakeRect (0, 0, size.width / 2, size.height / 2)]; + + idleTimer = nil; + editController = cont; + lastScale = cont->getZoomFactor() / 100.0; + if (self) + { + cont->open( self ); + + ERect *vr; + if (cont->getRect(&vr)) + { + float zf = cont->getZoomFactor() / 100.0; + NSRect newSize = NSMakeRect (0, 0, + vr->right - vr->left, + vr->bottom - vr->top ) ; + underlyingUISize = newSize.size; + newSize = NSMakeRect (0, 0, + lastScale * ( vr->right - vr->left ), + lastScale * ( vr->bottom - vr->top ) ) ; + [self scaleUnitSquareToSize:NSMakeSize( lastScale, lastScale )]; + setSizeByZoom = true; + [self setFrame:newSize]; + setSizeByZoom = false; + } + + cont->setZoomCallback( [self]( SurgeGUIEditor *ed ) { + ERect *vr; + float zf = ed->getZoomFactor() / 100.0; + if (ed->getRect(&vr)) + { + NSRect newSize = NSMakeRect (0, 0, + (int)( (vr->right - vr->left) * zf ), + (int)( (vr->bottom - vr->top) * zf ) ); + [self scaleUnitSquareToSize:NSMakeSize( zf / lastScale, zf / lastScale )]; + lastScale = zf; + + setSizeByZoom = true; + [self setFrame:newSize]; + setSizeByZoom = false; + } + + } + ); + + CFTimeInterval TIMER_INTERVAL = .05; // In SurgeGUISynthesizer.h it uses 50 ms + CFRunLoopTimerContext TimerContext = {0, self, NULL, NULL, NULL}; + CFAbsoluteTime FireTime = CFAbsoluteTimeGetCurrent() + TIMER_INTERVAL; + idleTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, + FireTime, + TIMER_INTERVAL, + 0, 0, + timerCallback, + &TimerContext); + if (idleTimer) + CFRunLoopAddTimer (CFRunLoopGetMain (), idleTimer, kCFRunLoopCommonModes); + } + + return self; +} + +- (void) doIdle +{ + editController->idle(); +} + +- (void) dealloc +{ + editController->close(); + if( idleTimer ) + { + CFRunLoopTimerInvalidate( idleTimer ); + } + + [super dealloc]; +} + +- (void) setFrame: (NSRect) newSize +{ + /* + * I override setFrame because hosts have independent views of window sizes which are saved. + * this needs to be found when the host resizes after creation to set the zoomFactor properly. + * Teensy bit gross, but works. Seems AU Lab does this but Logic Pro does not. + * + * the other option is to make zoom a parameter but then its in a patch and that seems wrong. + */ + NSSize targetSize = newSize.size; + + if( !setSizeByZoom && fabs( targetSize.width - underlyingUISize.width * lastScale ) > 2 ) + { + // so what's my apparent ratio + float apparentZoom = targetSize.width / ( underlyingUISize.width * lastScale ); + int azi = roundf( apparentZoom * 10 ) * 10; // this is a bit gross. I know the zoom is incremented by 10s + editController->setZoomFactor( azi ); + } + + [super setFrame:newSize]; +} + +@end + + +static CFBundleRef GetBundleFromExecutable (const char* filepath) +{ + @autoreleasepool { + NSString* execStr = [NSString stringWithCString:filepath encoding:NSUTF8StringEncoding]; + NSString* macOSStr = [execStr stringByDeletingLastPathComponent]; + NSString* contentsStr = [macOSStr stringByDeletingLastPathComponent]; + NSString* bundleStr = [contentsStr stringByDeletingLastPathComponent]; + return CFBundleCreate (0, (CFURLRef)[NSURL fileURLWithPath:bundleStr isDirectory:YES]); + } + +} + +//---------------------------------------------------------------------------------------------------- + +const char* getclamptxt(int id) +{ + switch(id) + { + case 1: return "Macro Parameters"; + case 2: return "Global / FX"; + case 3: return "Scene A Common"; + case 4: return "Scene A Osc"; + case 5: return "Scene A Osc Mixer"; + case 6: return "Scene A Filters"; + case 7: return "Scene A Envelopes"; + case 8: return "Scene A LFOs"; + case 9: return "Scene B Common"; + case 10: return "Scene B Osc"; + case 11: return "Scene B Osc Mixer"; + case 12: return "Scene B Filters"; + case 13: return "Scene B Envelopes"; + case 14: return "Scene B LFOs"; + } + return ""; +} + +ComponentResult aulayer::GetProperty(AudioUnitPropertyID iID, AudioUnitScope iScope, AudioUnitElement iElem, void* outData) +{ + if( iScope == kAudioUnitScope_Global ) + { + switch( iID ) + { + case kAudioUnitProperty_CocoaUI: + { + auto surgeclass = objc_getClass( "SurgeCocoaUI" ); + const char* image = class_getImageName ( surgeclass ); + CFBundleRef bundle = GetBundleFromExecutable (image); + CFURLRef url = CFBundleCopyBundleURL (bundle); + CFRetain( url ); + CFRelease (bundle); + + + AudioUnitCocoaViewInfo* info = static_cast (outData); + info->mCocoaAUViewClass[0] = CFStringCreateWithCString(kCFAllocatorDefault, class_getName(surgeclass), kCFStringEncodingUTF8); + info->mCocoaAUViewBundleLocation = url; + + return noErr; + } + case kVmbAAudioUnitProperty_GetEditPointer: + { + if( editor_instance == NULL ) + { + editor_instance = new SurgeGUIEditor( this, plugin_instance ); + } + void** pThis = (void**)(outData); + *pThis = (void*)editor_instance; + + return noErr; + } + case kAudioUnitProperty_ParameterValueName: + { + if(!IsInitialized()) return kAudioUnitErr_Uninitialized; + AudioUnitParameterValueName *aup = (AudioUnitParameterValueName*)outData; + char tmptxt[64]; + float f; + if(aup->inValue) f = *(aup->inValue); + else f = plugin_instance->getParameter01(plugin_instance->remapExternalApiToInternalId(aup->inParamID)); + plugin_instance->getParameterDisplay(plugin_instance->remapExternalApiToInternalId(aup->inParamID),tmptxt,f); + aup->outName = CFStringCreateWithCString(NULL,tmptxt,kCFStringEncodingUTF8); + return noErr; + } + case kAudioUnitProperty_ParameterClumpName: + { + AudioUnitParameterNameInfo *aupn = (AudioUnitParameterNameInfo*)outData; + aupn->outName = CFStringCreateWithCString(NULL,getclamptxt(aupn->inID),kCFStringEncodingUTF8); + return noErr; + } + case kVmbAAudioUnitProperty_GetPluginCPPInstance: + { + void** pThis = (void**)(outData); + *pThis = (void*)plugin_instance; + return noErr; + } + } + } + + return AUInstrumentBase::GetProperty(iID, iScope, iElem, outData); +} + diff --git a/src/common/CpuArchitecture.cpp b/src/common/CpuArchitecture.cpp index f24a7535ff7..b933e69ee28 100644 --- a/src/common/CpuArchitecture.cpp +++ b/src/common/CpuArchitecture.cpp @@ -23,6 +23,10 @@ void initCpuArchitecture() CpuArchitecture |= CaCMOV; if ((1 << 26) & CPUInfo[3]) CpuArchitecture |= CaSSE2; +#elif MAC + // intel macs always support + CpuArchitecture |= CaCMOV; + CpuArchitecture |= CaSSE2; #else __builtin_cpu_init(); if (__builtin_cpu_supports("sse2")) diff --git a/src/common/Parameter.cpp b/src/common/Parameter.cpp index 296b1007b50..44956891659 100644 --- a/src/common/Parameter.cpp +++ b/src/common/Parameter.cpp @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------------------------------- -// Copyright 2005 Claes Johanson & Vember Audio +// Copyright 2005 Claes Johanson & Vember Audio //------------------------------------------------------------------------------------------------------- #include "SurgeStorage.h" #include "Parameter.h" @@ -93,18 +93,18 @@ void Parameter::set_name(const char* n) create_fullname(dispname, fullname, ctrlgroup, ctrlgroup_entry); } -Parameter* Parameter::assign(int id, - int pid, - const char* name, - const char* dispname, - int ctrltype, - int posx, - int posy, - int scene, - ControlGroup ctrlgroup, - int ctrlgroup_entry, - bool modulateable, - int ctrlstyle) +Parameter* Parameter::assign( int id, + int pid, + const char* name, + const char* dispname, + int ctrltype, + int posx, + int posy, + int scene, + ControlGroup ctrlgroup, + int ctrlgroup_entry, + bool modulateable, + int ctrlstyle) { this->id = id; this->param_id_in_scene = pid; @@ -369,8 +369,8 @@ void Parameter::set_type(int ctrltype) val_min.i = 0; val_default.i = 0; val_max.i = num_fxtypes - 1; - // affect_other_parameters = true; // kan inte addas förrän den har en custom - // controltype + // affect_other_parameters = true; // kan inte addas förrän den har en custom controltype + // TRANSLATE: Can not be added, before/until it has a custom controltype break; case ct_fxbypass: valtype = vt_int; @@ -763,7 +763,7 @@ void Parameter::get_display(char* txt, bool external, float ef) sprintf(txt, "%.1f cents", f * 100.f); break; case ct_stereowidth: - sprintf(txt, "%.1fº", f); + sprintf(txt, "%.1fº", f); break; case ct_freq_hpf: case ct_freq_audible: @@ -1008,8 +1008,8 @@ pdata Parameter::morph(Parameter* b, float x) } else { - if (x>0.5) - memcpy(this,b,sizeof(parameter)); + if (x>0.5) + memcpy(this,b,sizeof(parameter)); } }*/ diff --git a/src/common/SampleLoadRiffWave.cpp b/src/common/SampleLoadRiffWave.cpp index d7d78c405f0..c42886b8943 100644 --- a/src/common/SampleLoadRiffWave.cpp +++ b/src/common/SampleLoadRiffWave.cpp @@ -31,7 +31,7 @@ bool Sample::load_riff_wave_mk2(const char* fname) HMMIO hmmio; - /* Open the file for reading with buffered I/O. Let windows use its default internal buffer */ + /* Open the file for reading with buffered I/O. Let Windows use its default internal buffer */ hmmio = mmioOpen((LPSTR)filename, NULL, MMIO_READ | MMIO_ALLOCBUF); if (!hmmio) { @@ -132,7 +132,7 @@ bool Sample::load_riff_wave_mk2(const char* fname) } if (mmioRead(hmmio, (HPSTR)loaddata, mmckinfoSubchunk.cksize) != - (LRESULT)mmckinfoSubchunk.cksize) // ACHTUNG!! här händer något bad! + (LRESULT)mmckinfoSubchunk.cksize) // ACHTUNG/WARNING!! Something bad happens here! (här händer nÃ¥got bad!) { /* Oops! */ write_log("file io: error reading the data chunk!"); @@ -143,7 +143,8 @@ bool Sample::load_riff_wave_mk2(const char* fname) this->inst_present = false; /* does not seem to be in general use - + + mmioAscend(hmmio, &mmckinfoSubchunk, 0); mmioSeek(hmmio,startpos,SEEK_SET); // read instrument chunk @@ -154,11 +155,11 @@ bool Sample::load_riff_wave_mk2(const char* fname) this->inst_present = false; } else { this->inst_present = true; - + if (mmioRead(hmmio, (HPSTR)&inst_tag, mmckinfoSubchunk.cksize) != (LRESULT)mmckinfoSubchunk.cksize) { - + write_log("file io: error reading the inst chunk!"); mmioClose(hmmio, 0); return false; @@ -293,4 +294,4 @@ bool Sample::load_riff_wave_mk2(const char* fname) return true; } -#endif \ No newline at end of file +#endif diff --git a/src/common/SurgeStorage.cpp b/src/common/SurgeStorage.cpp index 3b7c4e9dd00..fc8f00ab0be 100644 --- a/src/common/SurgeStorage.cpp +++ b/src/common/SurgeStorage.cpp @@ -6,6 +6,8 @@ #include #include #if MAC +#include +#include //#include //#include #include @@ -28,8 +30,42 @@ float samplerate, samplerate_inv; double dsamplerate, dsamplerate_inv; double dsamplerate_os, dsamplerate_os_inv; +#if MAC +#include +string getSelfLocation() { + char path[PATH_MAX]; + // TODO: use a build-provided symbol + CFStringRef selfName = CFSTR("com.vemberaudio.plugins.surge"); + CFBundleRef mainBundle = CFBundleGetBundleWithIdentifier(selfName); + CFURLRef resourcesURL = CFBundleCopyBundleURL(mainBundle); + CFStringRef str = CFURLCopyFileSystemPath( resourcesURL, kCFURLPOSIXPathStyle ); + CFRelease(resourcesURL); + CFStringGetCString( str, path, FILENAME_MAX, kCFStringEncodingASCII ); + CFRelease(str); + string out(path); + return out; +} +#endif + SurgeStorage::SurgeStorage() { +#if MAC + // Quick hack to install all the bundled surge data to user's local ~/Library/... + fs::path userSurgeDir(string(getenv("HOME")) + "/Library/Application Support/Surge"); + + // FIXME: currently, this only runs the first time you run Surge (e.g. when it's + // scanned by the host, so it doesn't run whenever surge instances are loaded but it + // also could fail to synchronize updates if the bundled resources change. It's unclear + // how to handle this in the face of users editing the `configuration.xml`. Perhaps + // a better approach is to leave a basic set of resources in the bundle and merge them + // with any user-provided things like waveforms in ~/Library/Application Support/Surge/... + // at least for now, this gets users up and running with presets, waveforms, effects, etc. + if (!fs::is_directory(userSurgeDir)) { + fs::create_directories(userSurgeDir); + fs::copy_recursive(fs::path(getSelfLocation() + "/Contents/Data"), userSurgeDir); + } +#endif + _patch.reset(new SurgePatch(this)); float cutoff = 0.455f; @@ -160,6 +196,28 @@ SurgeStorage::SurgeStorage() MessageBox(::GetActiveWindow(), "Surge is not properly installed. Please reinstall.", "Configuration not found", MB_OK | MB_ICONERROR); #endif +#if MAC + SInt32 nRes = 0; + CFUserNotificationRef pDlg = NULL; + const void* keys[] = { kCFUserNotificationAlertHeaderKey, + kCFUserNotificationAlertMessageKey + }; + const void* vals[] = { + CFSTR("Surge is not properly installed"), + CFSTR("Unable to open configuration.xml from ~/Library/Application Support/Surge") + + }; + + CFDictionaryRef dict = CFDictionaryCreate(0, keys, vals, + sizeof(keys)/sizeof(*keys), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + pDlg = CFUserNotificationCreate(kCFAllocatorDefault, 0, + kCFUserNotificationStopAlertLevel, + &nRes, dict); +#endif + } TiXmlElement* e = snapshotloader.FirstChild("autometa")->ToElement(); @@ -342,8 +400,10 @@ void SurgeStorage::load_wt(string filename, Wavetable* wt) extension[i] = tolower(extension[i]); if (extension.compare(".wt") == 0) load_wt_wt(filename, wt); +#if !MAC else if (extension.compare(".wav") == 0) load_wt_wav(filename, wt); +#endif } void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) @@ -354,14 +414,12 @@ void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) wt_header wh; memset(&wh, 0, sizeof(wt_header)); - // FIXME: Implement error handling when there is a convention to implement - // the error handling (e.g. return code or exception). - if (fread(&wh, sizeof(wt_header), 1, f) != 1) - fprintf(stderr, "%s: reading the wavetable header failed.\n", - __func__); - - if (memcmp(wh.tag, "vawt", 4)) + size_t read = fread( &wh, sizeof( wt_header ), 1, f ); + // I'm not sure why this ever worked but it is checking the 4 bytes against vawt so... + // if (wh.tag != vt_read_int32BE('vawt')) + if ( ! ( wh.tag[ 0 ] == 'v' && wh.tag[ 1 ] == 'a' && wh.tag[ 2 ] == 'w' && wh.tag[ 3 ] == 't' ) ) { + // SOME sort of error reporting is appropriate fclose(f); return; } @@ -374,10 +432,7 @@ void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) ds = sizeof(float) * vt_read_int16LE(wh.n_tables) * vt_read_int32LE(wh.n_samples); data = malloc(ds); - // FIXME: Implement error handling when there is a convention to implement - // the error handling (e.g. return code or exception). - if (fread(data, 1, ds, f) != ds) - fprintf(stderr, "%s: reading the wavetable data failed.\n", __func__); + fread(data, 1, ds, f); CS_WaveTableData.enter(); wt->BuildWT(data, wh, false); CS_WaveTableData.leave(); diff --git a/src/common/SurgeStorageLoadWavetable.cpp b/src/common/SurgeStorageLoadWavetable.cpp index ec734a1fad5..5accc0e8288 100644 --- a/src/common/SurgeStorageLoadWavetable.cpp +++ b/src/common/SurgeStorageLoadWavetable.cpp @@ -3,12 +3,12 @@ //------------------------------------------------------------------------------------------------------- #include "SurgeStorage.h" #include "DspUtilities.h" - -#if WINDOWS + +#if WINDOWS #include #include #include -#endif +#endif void error_msg(char* c) {} // add messagebox? @@ -17,7 +17,7 @@ void error_msg(char* c) #define int32 int void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) -{ +{ #if WINDOWS uint32 wave_channels = 0; uint32 wave_samplerate = 0; @@ -27,7 +27,7 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) HMMIO hmmio; - /* Open the file for reading with buffered I/O. Let windows use its default internal buffer */ + /* Open the file for reading with buffered I/O. Let Windows use its default internal buffer */ hmmio = mmioOpen((LPSTR)filename.c_str(), NULL, MMIO_READ | MMIO_ALLOCBUF); if (!hmmio) { @@ -131,7 +131,7 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) } if (mmioRead(hmmio, (HPSTR)loaddata, mmckinfoSubchunk.cksize) != - (LRESULT)mmckinfoSubchunk.cksize) // ACHTUNG!! här händer något bad! + (LRESULT)mmckinfoSubchunk.cksize) // ACHTUNG!! Something bad happens here! ("här händer nÃ¥got bad!") { /* Oops! */ error_msg("file io: error reading the data chunk!"); @@ -142,7 +142,7 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) // this->inst_present = false; /* does not seem to be in general use - + mmioAscend(hmmio, &mmckinfoSubchunk, 0); mmioSeek(hmmio,startpos,SEEK_SET); // read instrument chunk @@ -153,11 +153,11 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) this->inst_present = false; } else { this->inst_present = true; - + if (mmioRead(hmmio, (HPSTR)&inst_tag, mmckinfoSubchunk.cksize) != (LRESULT)mmckinfoSubchunk.cksize) { - + error_msg("file io: error reading the inst chunk!"); mmioClose(hmmio, 0); return false; @@ -200,8 +200,10 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) loop_present = true; mmioRead(hmmio, (HPSTR)&smpl_loop, sizeof(smpl_loop)); - // Dandruffs skumme wt-bug verkar vara här? + // Dandruffs skumme wt-bug verkar vara här? + // TRANSLATE: Dandruff's skim wt bug seems to be here? // hoppar in i malloc i callstack? wtf!? + // TRANSLATE: jumping into malloc in call stack? wtf!? smpl_loop.dwEnd++; // SC wants the loop end point to be the first sample AFTER the loop } @@ -292,9 +294,9 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) /* Close the file */ mmioClose(hmmio, 0); -#else - // FIXME: Implement WAV file loading for macOS and Linux. - fprintf(stderr, "%s: WAV file loading is not implemented.\n", - __func__); -#endif -} +#else + // FIXME: Implement WAV file loading for macOS and Linux. + fprintf(stderr, "%s: WAV file loading is not implemented.\n", + __func__); +#endif +} diff --git a/src/common/SurgeSynthesizer.cpp b/src/common/SurgeSynthesizer.cpp index 806bed6a9ba..e60d0896b86 100644 --- a/src/common/SurgeSynthesizer.cpp +++ b/src/common/SurgeSynthesizer.cpp @@ -265,7 +265,7 @@ void SurgeSynthesizer::softkillVoice(int s) (*max_playing)->uber_release(); } -// only allow 'margin' number of voices to be softkilled simultainously +// only allow 'margin' number of voices to be softkilled simultaneously void SurgeSynthesizer::enforcePolyphonyLimit(int s, int margin) { list::iterator iter; @@ -727,8 +727,10 @@ void SurgeSynthesizer::channelController(char channel, int cc, int value) int channelmask = ((channel == 0) ? 3 : 0) | ((channel == 1) ? 1 : 0) | ((channel == 2) ? 2 : 0); float fval = (float)value * (1.f / 127.f); - // spara all m�jliga NRPN & RPN's i ett short-array.. blir endast 128kb eller n�t av av det - // �nd�.. + // spara all möjliga NRPN & RPN's i ett short-array.. blir endast 128kb eller nÃ¥t av av det + // ändÃ¥.. + // TRANSLATE: + // save all possible NRPN & RPNs in a short array .. just gets/only amounts for 128kb or something off of it anyway switch (cc) { case 0: @@ -929,7 +931,9 @@ void SurgeSynthesizer::purgeHoldbuffer(int scene) iter++; } - // note: m�ste remova entries n�r noter d�dar sig sj�lv auch + // note: mÃ¥ste remova entries när noter dödar sig själv auch + // TRANSLATE: + // note: Must remove entries when notes kill themselves (ouch!) } void SurgeSynthesizer::allNotesOff() @@ -1295,8 +1299,8 @@ bool SurgeSynthesizer::loadFx(bool initp, bool force_reload_all) fx[s]->init_default_values(); /*for(int j=0; jinit(); @@ -1494,7 +1498,7 @@ bool SurgeSynthesizer::isModDestUsed(long ptag) void SurgeSynthesizer::updateUsedState() { - // intended for gui only + // intended for GUI only for (int i = 0; i < n_modsources; i++) modsourceused[i] = false; @@ -1904,7 +1908,9 @@ void SurgeSynthesizer::getParameterMeta(long index, parametermeta& pm) pm.fdefault = 0.5f; pm.hide = false; pm.meta = - false; // ironiskt eftersom det �r metaparameters, men dom p�verkar inga andra sliders + false;// ironiskt eftersom det är metaparameters, men dom pÃ¥verkar inga andra sliders + // TRANSLATE: + // ironic because it is metaparameters, but they don't affect any other sliders pm.expert = false; pm.clump = 1; } @@ -2043,6 +2049,8 @@ void SurgeSynthesizer::processControl() storage.getPatch().copy_globaldata( storage.getPatch().globaldata); // suger ganska mkt cpu i debug mode + // TRANSLATE: + // Drains a great deal of CPU while in Debug mode if (playA) storage.getPatch().copy_scenedata(storage.getPatch().scenedata[0], 0); // -""- if (playB) diff --git a/src/common/dsp/BiquadFilter.cpp b/src/common/dsp/BiquadFilter.cpp index dc687e11221..bd12d4603b8 100644 --- a/src/common/dsp/BiquadFilter.cpp +++ b/src/common/dsp/BiquadFilter.cpp @@ -78,7 +78,7 @@ void BiquadFilter::coeff_LP2B(double omega, double Q) // alpha = sinu*sinh((log(2.0)/2.0) * (BW) * omega / sinu), alpha = sinu / (2 * Q), // G1 = 0.05, //powf(2,-log(M_PI/omega)/log(2.0)), - // sätt aa till 6 db + // sätt aa till 6 db A = 2 * sqrt(G1) * sqrt(2 - G1), b0 = (1 - cosi + G1 * (1 + cosi) + A * sinu) * 0.5, b1 = (1 - cosi - G1 * (1 + cosi)), b2 = (1 - cosi + G1 * (1 + cosi) - A * sinu) * 0.5, @@ -213,7 +213,8 @@ void BiquadFilter::coeff_orfanidisEQ(double omega, double BW, double G, double G double G01 = abs(G * G - G0 * G1); double G11 = abs(G * G - G1 * G1); double F01 = abs(GB * GB - G0 * G1); - double F11 = abs(GB * GB - G1 * G1); // blir wacko ? + double F11 = abs(GB * GB - G1 * G1); // blir wacko ? + // goes crazy (?) double W2 = sqrt(G11 / G00) * square(tan(w0 / 2)); double w_lower = w0 * powf(2, -0.5 * BW); double w_upper = @@ -241,7 +242,8 @@ void BiquadFilter::coeff_orfanidisEQ(double omega, double BW, double G, double G void BiquadFilter::coeff_same_as_last_time() { - // ifall man skulle byta ipol så sätt dv = 0 här + // ifall man skulle byta ipol sÃ¥ sätt dv = 0 här + // If you want to change ipol then dv = 0 here } void BiquadFilter::coeff_instantize() diff --git a/src/common/dsp/BiquadFilterSSE2.cpp b/src/common/dsp/BiquadFilterSSE2.cpp index 43f5e6b1a64..9e2b517ea6f 100644 --- a/src/common/dsp/BiquadFilterSSE2.cpp +++ b/src/common/dsp/BiquadFilterSSE2.cpp @@ -5,8 +5,15 @@ #include "globals.h" #include -// dessa är långsammare än motsvarande x87-variant -// använd icke förrän codeanal har fått leka lite +// dessa är lĺngsammare än motsvarande x87-variant +// använd icke förrän codeanal har fĺtt leka lite + +// TRANSLATE1: +// these are slower than the corresponding x87 variant +// do not use until codeanal has been playing a little +// TRANSLATE2: +// these are more common than the corresponding x87 variant +// do not use until codeanal has been playing a little void biquadunit::process_block_SSE2(double *data) { @@ -77,7 +84,7 @@ void biquadunit::process_block_SSE2(float *dataL,float *dataR) __m128 vl = _mm_load_ps(dataL + k); __m128 vr = _mm_load_ps(dataR + k); __m128 v0 = _mm_unpacklo_ps(vl,vr); - + // first __m128d input = _mm_cvtps_pd(v0); v0 = _mm_movehl_ps(v0,v0); @@ -87,7 +94,6 @@ void biquadunit::process_block_SSE2(float *dataL,float *dataR) reg0.v = _mm_sub_pd(_mm_add_pd(_mm_mul_pd(b1.v.v, input), reg1.v), _mm_mul_pd(a1.v.v, op0)); reg1.v = _mm_sub_pd(_mm_mul_pd(b2.v.v, input), _mm_mul_pd(a2.v.v, op0)); - // second input = _mm_cvtps_pd(v0); a1.process_SSE2(); a2.process_SSE2(); b0.process_SSE2(); b1.process_SSE2(); b2.process_SSE2(); @@ -95,7 +101,6 @@ void biquadunit::process_block_SSE2(float *dataL,float *dataR) reg0.v = _mm_sub_pd(_mm_add_pd(_mm_mul_pd(b1.v.v, input), reg1.v), _mm_mul_pd(a1.v.v, op1)); reg1.v = _mm_sub_pd(_mm_mul_pd(b2.v.v, input), _mm_mul_pd(a2.v.v, op1)); - // third v0 = _mm_unpackhi_ps(vl,vr); input = _mm_cvtps_pd(v0); @@ -133,7 +138,7 @@ void biquadunit::process_block_slowlag_SSE2(float *dataL,float *dataR) __m128 vl = _mm_load_ps(dataL + k); __m128 vr = _mm_load_ps(dataR + k); __m128 v0 = _mm_unpacklo_ps(vl,vr); - + // first __m128d input = _mm_cvtps_pd(v0); v0 = _mm_movehl_ps(v0,v0); @@ -142,14 +147,12 @@ void biquadunit::process_block_slowlag_SSE2(float *dataL,float *dataR) reg0.v = _mm_sub_pd(_mm_add_pd(_mm_mul_pd(b1.v.v, input), reg1.v), _mm_mul_pd(a1.v.v, op0)); reg1.v = _mm_sub_pd(_mm_mul_pd(b2.v.v, input), _mm_mul_pd(a2.v.v, op0)); - // second input = _mm_cvtps_pd(v0); __m128d op1 = _mm_add_pd(reg0.v,_mm_mul_pd(b0.v.v, input)); reg0.v = _mm_sub_pd(_mm_add_pd(_mm_mul_pd(b1.v.v, input), reg1.v), _mm_mul_pd(a1.v.v, op1)); reg1.v = _mm_sub_pd(_mm_mul_pd(b2.v.v, input), _mm_mul_pd(a2.v.v, op1)); - // third v0 = _mm_unpackhi_ps(vl,vr); input = _mm_cvtps_pd(v0); @@ -183,7 +186,7 @@ void biquadunit::process_block_to_SSE2(float *dataL,float *dataR, float *dstL,fl __m128 vl = _mm_load_ps(dataL + k); __m128 vr = _mm_load_ps(dataR + k); __m128 v0 = _mm_unpacklo_ps(vl,vr); - + // first __m128d input = _mm_cvtps_pd(v0); v0 = _mm_movehl_ps(v0,v0); @@ -193,7 +196,6 @@ void biquadunit::process_block_to_SSE2(float *dataL,float *dataR, float *dstL,fl reg0.v = _mm_sub_pd(_mm_add_pd(_mm_mul_pd(b1.v.v, input), reg1.v), _mm_mul_pd(a1.v.v, op0)); reg1.v = _mm_sub_pd(_mm_mul_pd(b2.v.v, input), _mm_mul_pd(a2.v.v, op0)); - // second input = _mm_cvtps_pd(v0); a1.process_SSE2(); a2.process_SSE2(); b0.process_SSE2(); b1.process_SSE2(); b2.process_SSE2(); @@ -201,7 +203,6 @@ void biquadunit::process_block_to_SSE2(float *dataL,float *dataR, float *dstL,fl reg0.v = _mm_sub_pd(_mm_add_pd(_mm_mul_pd(b1.v.v, input), reg1.v), _mm_mul_pd(a1.v.v, op1)); reg1.v = _mm_sub_pd(_mm_mul_pd(b2.v.v, input), _mm_mul_pd(a2.v.v, op1)); - // third v0 = _mm_unpackhi_ps(vl,vr); input = _mm_cvtps_pd(v0); @@ -228,4 +229,4 @@ void biquadunit::process_block_to_SSE2(float *dataL,float *dataR, float *dstL,fl _mm_store_ps(dstR+k,sr); } } -#endif \ No newline at end of file +#endif diff --git a/src/common/dsp/DspUtilities.h b/src/common/dsp/DspUtilities.h index 5dd1320e3e6..4d1d30299fe 100644 --- a/src/common/dsp/DspUtilities.h +++ b/src/common/dsp/DspUtilities.h @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------------------------------- -// Copyright 2005 Claes Johanson & Vember Audio +// Copyright 2005 Claes Johanson & Vember Audio //------------------------------------------------------------------------------------------------------- #pragma once @@ -238,7 +238,8 @@ inline float tanh_fast(float in) __m128 xx = _mm_mul_ss(x,x); __m128 denom = _mm_add_ss(_mm_add_ss(one,x), _mm_add_ss(xx,_mm_mul_ss(xx,_mm_mul_ss(_mm_load_ss(&a),x))); - + + #endif*/ } @@ -269,8 +270,12 @@ __forceinline float clamp1bp(float in) return in; } -// använd custom format (x^3 ?) internt, men spara som decibel i xml-datan +// använd custom format (x^3 ?) internt, men spara som decibel i xml-datan // bollocks to it +// TRANSLATE +// Use custom format (x^3 ?) internally, but save as decibel in XML-data +// bollocks to it + inline float amp_to_linear(float x) { x = max(0.f, x); diff --git a/src/common/dsp/FilterCoefficientMaker.cpp b/src/common/dsp/FilterCoefficientMaker.cpp index 9f6e6590855..32341efdb97 100644 --- a/src/common/dsp/FilterCoefficientMaker.cpp +++ b/src/common/dsp/FilterCoefficientMaker.cpp @@ -356,7 +356,7 @@ void FilterCoefficientMaker::Coeff_COMB(float freq, float reso, int subtype) { float dtime = (1.f / 440.f) * note_to_pitch(-freq); dtime = dtime * dsamplerate_os - - FIRoffset; // 1 sample f�r feedback, 1 f�r ett IIR-filter utan resonans + FIRoffset; // 1 sample for feedback, 1 sample for the IIR-filter without resonance dtime = limit_range(dtime, (float)FIRipol_N, (float)max_fb_comb - FIRipol_N); reso = ((subtype & 2) ? -1.0f : 1.0f) * limit_range(reso, 0.f, 1.f); @@ -482,4 +482,4 @@ void FilterCoefficientMaker::Reset() memset(C, 0, sizeof(float) * n_cm_coeffs); memset(dC, 0, sizeof(float) * n_cm_coeffs); memset(tC, 0, sizeof(float) * n_cm_coeffs); -} \ No newline at end of file +} diff --git a/src/common/dsp/LfoModulationSource.cpp b/src/common/dsp/LfoModulationSource.cpp index d8d6832b78f..3ef4b1264ad 100644 --- a/src/common/dsp/LfoModulationSource.cpp +++ b/src/common/dsp/LfoModulationSource.cpp @@ -94,10 +94,13 @@ float CubicInterpolate(float y0, float y1, float y2, float y3, float mu) void LfoModulationSource::attack() { /* - // TODO lägg till scene LFO envelope release->attack blend om det går - // if !state så är det en scenelfo - // var inte så kul i verkligheten - + // TODO lägg till scene LFO envelope release->attack blend om det gÃ¥r + // if !state sÃ¥ är det en scenelfo + // var inte sÃ¥ kul i verkligheten + // TRANSLATE + // TODO Add Scene LFO Envelope Release -> Attack blend, if it is possible + // If !state, then it is a SceneLFO - was not so nice in reality / messy + if(!state && (localcopy[idelay].f == lfo->delay.val_min.f)) { env_state = lenv_attack; @@ -134,7 +137,8 @@ void LfoModulationSource::attack() { float phaseslider; if (lfo->shape.val.i == ls_stepseq) - phaseslider = 0.f; // använd phase som shuffle-param istället + phaseslider = 0.f; // använd phase som shuffle-param istället + // TRANSLATE: Use Phase as shuffle-parameter instead // else if(state) phaseslider = lfo->start_phase.val.f; else phaseslider = localcopy[startphase].f; @@ -450,4 +454,4 @@ void LfoModulationSource::process_block() if (lfo->unipolar.val.b && (s != ls_stepseq)) io2 = 0.5f + 0.5f * io2; output = env_val * localcopy[magn].f * io2; -} \ No newline at end of file +} diff --git a/src/common/dsp/Oscillator.cpp b/src/common/dsp/Oscillator.cpp index 0a2177269b0..36daa1217d1 100644 --- a/src/common/dsp/Oscillator.cpp +++ b/src/common/dsp/Oscillator.cpp @@ -120,7 +120,8 @@ void osc_sine::process_block(float pitch, float drift, bool stereo, bool FM, flo // const __m128 scale = _mm_set1_ps(0.000030517578125); - // HACK för att testa sine(__m64) + // HACK för att testa sine(__m64) + // TRANSLATE: HACK for testing sine(__m64) // const __m64 rate = _mm_set1_pi16(0x0040); /*m64phase = _mm_add_pi16(m64phase,rate); @@ -147,7 +148,8 @@ void osc_sine::process_block(float pitch, float drift, bool stereo, bool FM, flo /* add controls: input L/R gain -limiter?*/ +limiter? +*/ osc_audioinput::osc_audioinput(SurgeStorage* storage, OscillatorStorage* oscdata, pdata* localcopy) : Oscillator(storage, oscdata, localcopy) @@ -201,4 +203,4 @@ void osc_audioinput::process_block(float pitch, float drift, bool stereo, bool F output[k] = a * storage->audio_in[0][k] + b * storage->audio_in[1][k]; } } -} \ No newline at end of file +} diff --git a/src/common/dsp/QuadFilterChain.cpp b/src/common/dsp/QuadFilterChain.cpp index b7830258320..6384989c66d 100644 --- a/src/common/dsp/QuadFilterChain.cpp +++ b/src/common/dsp/QuadFilterChain.cpp @@ -46,15 +46,21 @@ template void ProcessFBQuad(QuadFilterChainState& d, fbq_global& g, float* OutL, float* OutR) { - const __m128 hb_c = _mm_set1_ps(0.5f); // om denna ‰ndras frÂn 0.5, se till att ‰ndra i koden - // eftersom det antas att den ‰r h‰lften + const __m128 hb_c = _mm_set1_ps(0.5f); // om denna ändras frÃ¥n 0.5, se till att ändra i koden + // eftersom det antas att den är hälften + // TRANSLATE: + // If this is changed from 0.5, make sure to change + // this in the code because it is assumed to be half const __m128 one = _mm_set1_ps(1.0f); switch (config) { case fb_serial: // no feedback at all (saves CPU) - // TODO denna skulle nog kunna bli ‰nnu snabbare om den serialiseras (vilket ‰r l‰ttare nu) - // lite mer L1 v‰nlig, men latency-lalal blir nog detsamma + // TODO denna skulle nog kunna bli ännu snabbare om den serialiseras (vilket är lättare nu) + // lite mer L1 vänlig, men latency-lalal blir nog detsamma + // TRANSLATE: + // TODO this might be even faster if it is serialized (which is now easier) + // a little more L1 friendly, but latency-lalal will probably be the same for (int k = 0; k < block_size_os; k++) { __m128 input = d.DL[k]; diff --git a/src/common/dsp/QuadFilterUnit.cpp b/src/common/dsp/QuadFilterUnit.cpp index a208f575c83..486200ab607 100644 --- a/src/common/dsp/QuadFilterUnit.cpp +++ b/src/common/dsp/QuadFilterUnit.cpp @@ -519,7 +519,9 @@ __m128 IIR12WDFquad(QuadFilterUnitState* __restrict f, __m128 in) #if PPC __m128 IIR12CFCquad(QuadFilterUnitState* __restrict f, __m128 in) { - // state-space med clipgain (2nd order, direkt registerbegr‰nsning) + // state-space med clipgain (2nd order, direkt registerbegränsning) + // TRANSLATE: + // State-space with clipgain (2nd order, direct registry limitation / registerlimit) f->C[0] = vec_add(f->C[0], f->dC[0]); // ar f->C[1] = vec_add(f->C[1], f->dC[1]); // ai @@ -545,7 +547,9 @@ __m128 IIR12CFCquad(QuadFilterUnitState* __restrict f, __m128 in) #else __m128 IIR12CFCquad(QuadFilterUnitState* __restrict f, __m128 in) { - // state-space med clipgain (2nd order, direkt registerbegr‰nsning) + // state-space med clipgain (2nd order, direkt registerbegränsning) + // TRANSLATE: + // State-space with clipgain (2nd order, direct registry limitation / registerlimit) f->C[0] = _mm_add_ps(f->C[0], f->dC[0]); // ar f->C[1] = _mm_add_ps(f->C[1], f->dC[1]); // ai @@ -580,6 +584,7 @@ __m128 IIR12CFCquad(QuadFilterUnitState* __restrict f, __m128 in) __m128 IIR12CFLquad(QuadFilterUnitState* __restrict f, __m128 in) { // State-space med mjukare limiter + // State-space with softer limiter f->C[0] = _mm_add_ps(f->C[0], f->dC[0]); // (ar) f->C[1] = _mm_add_ps(f->C[1], f->dC[1]); // (ai) @@ -621,8 +626,10 @@ __m128 IIR12CFLquad(QuadFilterUnitState* __restrict f, __m128 in) #if PPC __m128 IIR24CFCquad(QuadFilterUnitState* __restrict f, __m128 in) { - // state-space med clipgain (2nd order, direkt registerbegr‰nsning) - + // state-space med clipgain (2nd order, direkt registerbegränsning) + // TRANSLATE: + // State-space with clipgain (2nd order, direct registry limitation / registerlimit) + f->C[0] = vec_add(f->C[0], f->dC[0]); // ar f->C[1] = vec_add(f->C[1], f->dC[1]); // ai f->C[2] = vec_add(f->C[2], f->dC[2]); // b1 @@ -654,8 +661,10 @@ __m128 IIR24CFCquad(QuadFilterUnitState* __restrict f, __m128 in) #else __m128 IIR24CFCquad(QuadFilterUnitState* __restrict f, __m128 in) { - // state-space med clipgain (2nd order, direkt registerbegr‰nsning) - + // state-space med clipgain (2nd order, direkt registerbegränsning) + // TRANSLATE: + // State-space with clipgain (2nd order, direct registry limitation / registerlimit) + f->C[0] = _mm_add_ps(f->C[0], f->dC[0]); // ar f->C[1] = _mm_add_ps(f->C[1], f->dC[1]); // ai f->C[2] = _mm_add_ps(f->C[2], f->dC[2]); // b1 @@ -694,8 +703,9 @@ __m128 IIR24CFCquad(QuadFilterUnitState* __restrict f, __m128 in) #else __m128 IIR24CFLquad(QuadFilterUnitState* __restrict f, __m128 in) { - // State-space med mjukare limiter - + // State-space med mjukare limiter + // State-space with softer limiter + f->C[0] = _mm_add_ps(f->C[0], f->dC[0]); // (ar) f->C[1] = _mm_add_ps(f->C[1], f->dC[1]); // (ai) f->C[2] = _mm_add_ps(f->C[2], f->dC[2]); // b1 @@ -1314,6 +1324,7 @@ __m128 ASYM_PPC(__m128 in, __m128 drive) e.V = vec_max(vec_min(e.V, UB), LB); // funkar inte med optimization ? + // Does not work with (or without?) optimization? _MM_ALIGN16 float ws4[4], wsn4[4]; ws4[0] = waveshapers[2][e.Int[0] & 0x3ff]; diff --git a/src/common/dsp/SampleAndHoldOscillator.cpp b/src/common/dsp/SampleAndHoldOscillator.cpp index d31ef38d59b..f11c4c0e62b 100644 --- a/src/common/dsp/SampleAndHoldOscillator.cpp +++ b/src/common/dsp/SampleAndHoldOscillator.cpp @@ -7,10 +7,10 @@ // const float integrator_hpf = 0.99999999f; // const float integrator_hpf = 0.9992144f; // 44.1 kHz // const float integrator_hpf = 0.9964f; // 44.1 kHz -// const float integrator_hpf = 0.9982f; // 44.1 kHz magisk moog freq +// const float integrator_hpf = 0.9982f; // 44.1 kHz Magic Moog freq const float integrator_hpf = 0.999f; -// 290 samples för att falla 50% (british) (är nog ett 2-pole hpf) -// 202 samples (american) +// 290 samples to fall 50% (British) (is probably a 2-pole HPF) +// 202 samples (American) // const float integrator_hpf = 0.999f; // pow(ln(0.5)/(samplerate/50hz) const float hpf_cycle_loss = 0.995f; @@ -38,7 +38,7 @@ void SampleAndHoldOscillator::init(float pitch, bool is_display) bufpos = 0; dc = 0; - // init här + // init här id_shape = oscdata->p[0].param_id_in_scene; id_pw = oscdata->p[1].param_id_in_scene; id_smooth = oscdata->p[2].param_id_in_scene; @@ -373,7 +373,9 @@ template void SampleAndHoldOscillator::update_lagvals() float invt = 4.f * min(1.0, (8.175798915 * note_to_pitch(pitch + l_sync.v)) * dsamplerate_os_inv); - float hpf2 = min(integrator_hpf, powf(hpf_cycle_loss, invt)); // ACHTUNG! gör lookup-table + float hpf2 = min(integrator_hpf, powf(hpf_cycle_loss, invt)); + // ACHTUNG! gör lookup-table + // ACHTUNG/WARNING! Make a lookup-table li_hpf.set_target(hpf2); @@ -397,7 +399,8 @@ void SampleAndHoldOscillator::process_block( pitchmult_inv = max(1.0, dsamplerate_os * (1 / 8.175798915) * note_to_pitch_inv(pitch)); pitchmult = 1.f / - pitchmult_inv; // denna måste vara en riktig division, reciprocal-approx är inte precis nog + pitchmult_inv; + // This must be a real division, reciprocal-approximation is not precise enough int k, l; // if (FM) FMdepth.newValue(depth); @@ -546,4 +549,4 @@ void SampleAndHoldOscillator::process_block( } #endif } -} \ No newline at end of file +} diff --git a/src/common/dsp/SurgeSuperOscillator.cpp b/src/common/dsp/SurgeSuperOscillator.cpp index 462c354f52a..747aed0c77d 100644 --- a/src/common/dsp/SurgeSuperOscillator.cpp +++ b/src/common/dsp/SurgeSuperOscillator.cpp @@ -7,10 +7,10 @@ // const float integrator_hpf = 0.99999999f; // const float integrator_hpf = 0.9992144f; // 44.1 kHz // const float integrator_hpf = 0.9964f; // 44.1 kHz -// const float integrator_hpf = 0.9982f; // 44.1 kHz magisk moog freq +// const float integrator_hpf = 0.9982f; // 44.1 kHz Magical Moog frequency -// 290 samples för att falla 50% (british) (är nog ett 2-pole hpf) -// 202 samples (american) +// 290 samples to fall by 50% (British) (Is probably a 2-pole HPF) +// 202 samples (American) // const float integrator_hpf = 0.999f; // pow(ln(0.5)/(samplerate/50hz) const float hpf_cycle_loss = 0.995f; @@ -114,7 +114,7 @@ void SurgeSuperOscillator::init(float pitch, bool is_display) bufpos = 0; dc = 0; - // init här + // Init here id_shape = oscdata->p[0].param_id_in_scene; id_pw = oscdata->p[1].param_id_in_scene; id_pw2 = oscdata->p[2].param_id_in_scene; @@ -327,7 +327,7 @@ template void SurgeSuperOscillator::convolute(int voice, bool stereo) vFloat g128R = vec_loadAndSplatScalar(&gR); vFloat st[3]; vFloat lipol128 = vec_loadAndSplatScalar(&flipol); - vector unsigned char mask, maskstore; // since both buffers are aligned and read the same + vector unsigned char mask, maskstore; // since both buffers are aligned and read (from) the same // position, the same mask can be used // load & align oscbuffer (left) @@ -503,7 +503,7 @@ template void SurgeSuperOscillator::update_lagvals() float invt = 4.f * min(1.0, (8.175798915 * note_to_pitch(pitch + l_sync.v)) * dsamplerate_os_inv); - float hpf2 = min(integrator_hpf, powf(hpf_cycle_loss, invt)); // TODO ACHTUNG! gör lookup-table + float hpf2 = min(integrator_hpf, powf(hpf_cycle_loss, invt)); // TODO ACHTUNG/WARNING! Make a lookup table li_hpf.set_target(hpf2); // li_integratormult.set_target(invt); @@ -531,7 +531,7 @@ void SurgeSuperOscillator::process_block( pitchmult = 1.f / - pitchmult_inv; // denna måste vara en riktig division, reciprocal-approx är inte precis nog + pitchmult_inv; // This must be a real division, reciprocal-approximation is not precise enough int k, l; @@ -558,9 +558,8 @@ void SurgeSuperOscillator::process_block( while (((l_sync.v > 0) && (syncstate[l] < a)) || (oscstate[l] < a)) { FMmul_inv = rcp(fmmul); - // divisionen racar med ökningen av oscstate så att den aldrig kommer ur loopen - // detta blir unsafe fucka inte med oscstate utan gör divisionen inne i convolute - // istället + // The division races with the growth of the oscstate so that it never comes out of/gets out of the loop + // this becomes unsafe, don't fuck with the oscstate but make a division within the convolute instead. convolute(l, stereo); } @@ -721,4 +720,4 @@ void SurgeSuperOscillator::process_block( #endif } first_run = false; -} \ No newline at end of file +} diff --git a/src/common/dsp/SurgeVoice.cpp b/src/common/dsp/SurgeVoice.cpp index 98cccfa809e..c5a848c8998 100644 --- a/src/common/dsp/SurgeVoice.cpp +++ b/src/common/dsp/SurgeVoice.cpp @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------------------------------- -// Copyright 2005 Claes Johanson & Vember Audio +// Copyright 2005 Claes Johanson & Vember Audio //------------------------------------------------------------------------------------------------------- #include "SurgeVoice.h" #include "DspUtilities.h" @@ -277,7 +277,7 @@ void SurgeVoice::switch_toggled() set_path(use_osc1, use_osc2, use_osc3, FM, use_ring12, use_ring23, use_noise); } - // kolla filtertype + // Check the filtertype (kolla = check?) for (int u = 0; u < 2; u++) { if ((scene->filterunit[u].type.val.i != FBP.FU[u].type) || @@ -438,9 +438,9 @@ template void SurgeVoice::calc_ctrldata(QuadFilterChainState* Q, in localcopy[pan_id].f + state.voiceChannelState->pan + state.mainChannelState->pan, -1.f, 1.f); float amp = 0.5f * amp_to_linear(localcopy[volume_id].f); // the *0.5 multiplication will be eliminated - // by the 2x gain of the halfband filter + // by the 2x gain of the halfband filter - // volymkorrigering (fb_stereo uppdaterad sedan v1.2.2 + // Volume correcting/correction (fb_stereo updated since v1.2.2) if (scene->filterblock_configuration.val.i == fb_wide) amp *= 0.6666666f; else if (scene->filterblock_configuration.val.i == fb_stereo) @@ -707,7 +707,7 @@ void SurgeVoice::set_path( this->noise = noise; } -void SurgeVoice::SetQFB(QuadFilterChainState* Q, int e) // Q == 0 betyder init +void SurgeVoice::SetQFB(QuadFilterChainState* Q, int e) // Q == 0 means init(ialise) { fbq = Q; fbqi = e; @@ -801,7 +801,8 @@ void SurgeVoice::SetQFB(QuadFilterChainState* Q, int e) // Q == 0 betyder init if (scene->filterunit[u].type.val.i == fut_lpmoog) Q->FU[u].WP[0] = scene->filterunit[u] - .subtype.val.i; // lpmoog's output stage finns i WP[0] för hela quaden + .subtype.val.i; // lpmoog's output stage finns i WP[0] för hela quaden + // LPMoog's output stage is/exists/can be found in WP[0] for the whole/entire quad if (scene->filterblock_configuration.val.i == fb_wide) { diff --git a/src/common/dsp/SurgeVoice.h b/src/common/dsp/SurgeVoice.h index e5aacadde04..1fed0d196e3 100644 --- a/src/common/dsp/SurgeVoice.h +++ b/src/common/dsp/SurgeVoice.h @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------------------------------- -// Copyright 2005 Claes Johanson & Vember Audio +// Copyright 2005 Claes Johanson & Vember Audio //------------------------------------------------------------------------------------------------------- #pragma once #include "SurgeStorage.h" @@ -21,7 +21,7 @@ class SurgeVoice _MM_ALIGN16 lipol_ps osclevels[7]; _MM_ALIGN16 pdata localcopy[n_scene_params]; _MM_ALIGN16 float - fmbuffer[block_size_os]; // used for the 2>1<3 FM-mode (behöver pointern tidigare) + fmbuffer[block_size_os]; // used for the 2>1<3 FM-mode (Needs the pointer earlier <- behöver pointern tidigare) SurgeVoice(SurgeStorage* storage, SurgeSceneStorage* scene, @@ -88,4 +88,4 @@ class SurgeVoice // filterblock stuff int id_cfa, id_cfb, id_kta, id_ktb, id_emoda, id_emodb, id_resoa, id_resob, id_drive, id_vca, id_vcavel, id_fbalance, id_feedback; -}; \ No newline at end of file +}; diff --git a/src/common/dsp/Wavetable.cpp b/src/common/dsp/Wavetable.cpp index 5e5ce4646a9..a61bcf9fee7 100644 --- a/src/common/dsp/Wavetable.cpp +++ b/src/common/dsp/Wavetable.cpp @@ -44,7 +44,7 @@ bool _BitScanReverse(unsigned int* result, unsigned int bits) } #endif -//! Calculate he worst-case scenario of the needed samples for a specific wavetable and see if it +//! Calculate the worst-case scenario of the needed samples for a specific wavetable and see if it //! fits bool CheckRequiredWTSize(int TableSize, int TableCount) { @@ -160,11 +160,12 @@ bool Wavetable::BuildWT(void* wdata, wt_header& wh, bool AppendSilence) { for (int j = 0; j < max_subtables; j++) { - // TODO ACHTUNG crash här vid patchbyte! - /*free(wt->TableF32WeakPointers[i][j]); - free(wt->TableI16WeakPointers[i][j]); - wt->TableF32WeakPointers[i][j] = 0; - wt->TableI16WeakPointers[i][j] = 0;*/ + // TODO ACHTUNG crash här vid patchbyte! + // TODO ACHTUNG/WARNING: Crashes here with patchbyte! + /*free(wt->TableF32WeakPointers[i][j]); + free(wt->TableI16WeakPointers[i][j]); + wt->TableF32WeakPointers[i][j] = 0; + wt->TableI16WeakPointers[i][j] = 0;*/ } } for (int j = 0; j < this->n_tables; j++) @@ -209,7 +210,7 @@ bool Wavetable::BuildWT(void* wdata, wt_header& wh, bool AppendSilence) } } - // clear any appended tables (not read, but inlcuded in table for post-silence) + // clear any appended tables (not read, but included in table for post-silence) for (int j = wdata_tables; j < this->n_tables; j++) { memset(this->TableF32WeakPointers[0][j], 0, this->size * sizeof(float)); @@ -299,10 +300,17 @@ void Wavetable::MipMapWT() } // fwrite(this->TableI16WeakPointers[l][0],lsize*sizeof(short),1,F); } - // fclose(F); - - // TODO I16 mipmaps hamnar ur fas - // knäppen kommer antagligen från att det inte är någon padding i början så att det blir ur fas - // vid mipmapbyte makes sense eftersom den skilde en hel sample vid bytet, vilket inte kan - // förklaras av halfratefiltret + // fclose(F); + + // TODO I16 mipmaps hamnar ur fas + // knäppen kommer antagligen frÃ¥n att det inte är nÃ¥gon padding i början sÃ¥ att det blir ur fas + // vid mipmapbyte makes sense eftersom den skilde en hel sample vid bytet, vilket inte kan + // förklaras av halfratefiltret + + // TRANSLATE: + // TODO I16 mipmaps end up out of phase + // The click/knot/bug probably results from the fact that there is no padding in the beginning, + // so it becomes out of phase at mipmapbyte - makes sense because it separates a whole sample + // at the exchange, which can not be explained by the semifinal filter + } diff --git a/src/common/dsp/WavetableOscillator.cpp b/src/common/dsp/WavetableOscillator.cpp index c854e82b8b9..c6d1762c2cb 100644 --- a/src/common/dsp/WavetableOscillator.cpp +++ b/src/common/dsp/WavetableOscillator.cpp @@ -454,7 +454,7 @@ template void WavetableOscillator::update_lagvals() float invt = min(1.0, (8.175798915 * note_to_pitch(pitch_t)) * dsamplerate_os_inv); float hpf2 = - min(integrator_hpf, powf(hpf_cycle_loss, 4 * invt)); // TODO !!! ACHTUNG! gör lookup-table + min(integrator_hpf, powf(hpf_cycle_loss, 4 * invt)); // TODO ACHTUNG! WARNING! Make a lookup table (gör=make?) hpf_coeff.newValue(hpf2); integrator_mult.newValue(invt); @@ -482,7 +482,7 @@ void WavetableOscillator::process_block( pitchmult_inv = max(1.0, dsamplerate_os * (1 / 8.175798915) * note_to_pitch_inv(pitch_t)); pitchmult = 1.f / - pitchmult_inv; // denna måste vara en riktig division, reciprocal-approx är inte precis nog + pitchmult_inv; // This must be a real division, reciprocal-approximation is not precise enough this->drift = drift; int k, l; @@ -493,7 +493,7 @@ void WavetableOscillator::process_block( l_clip.process(); if ((oscdata->wt.n_tables == 1) || - (tableid >= oscdata->wt.n_tables)) // tableid-range kan ha ändrats under tiden, gör koll + (tableid >= oscdata->wt.n_tables)) // TableID-range may have changed in the meantime, check it! { tableipol = 0.f; tableid = 0; @@ -663,4 +663,4 @@ void WavetableOscillator::process_block( } #endif } -} \ No newline at end of file +} diff --git a/src/common/dsp/WindowOscillator.cpp b/src/common/dsp/WindowOscillator.cpp index 71e88b21698..d70fcbbff2c 100644 --- a/src/common/dsp/WindowOscillator.cpp +++ b/src/common/dsp/WindowOscillator.cpp @@ -113,7 +113,8 @@ __forceinline unsigned int BigMULr16(unsigned int a, unsigned int b) shl edx, 16 shr eax, 16 or eax,edx - // TODO fixa return för gcc asm + // TODO fixa return för gcc asm + // TODO: Fix return for GCC ASM mov result, eax } return result; @@ -151,8 +152,9 @@ void WindowOscillator::ProcessSubOscs(bool stereo) unsigned int MipMapA = 0; unsigned int MipMapB = 0; if (Sub.Table[so] >= oscdata->wt.n_tables) - Sub.Table[so] = Table; // TableID kanske inte ‰r valid l‰ngre om en ny wavetable laddats - + Sub.Table[so] = Table; + // TableID kanske inte är valid längre om en ny wavetable laddats + // Translate: TableID may not be valid anymore if a new wavetable is loaded unsigned long MSBpos; unsigned int bs = BigMULr16(RatioA, 3 * FormantMul); if (_BitScanReverse(&MSBpos, bs)) @@ -224,7 +226,9 @@ void WindowOscillator::ProcessSubOscs(bool stereo) unsigned int MipMapA = 0; unsigned int MipMapB = 0; if (Sub.Table[so] >= oscdata->wt.n_tables) - Sub.Table[so] = Table; // TableID kanske inte ar valid langre om en ny wavetable laddats + Sub.Table[so] = Table; + // TableID kanske inte är valid längre om en ny wavetable laddats + // Translate: TableID may not be valid anymore if a new wavetable is loaded unsigned long MSBpos; unsigned int bs = BigMULr16(RatioA, 3 * FormantMul); @@ -304,8 +308,10 @@ void WindowOscillator::ProcessSubOscs(bool stereo) unsigned int MipMapA = 0; unsigned int MipMapB = 0; if (Sub.Table[so] >= oscdata->wt.n_tables) - Sub.Table[so] = Table; // TableID kanske inte ‰r valid l‰ngre om en ny wavetable laddats - + Sub.Table[so] = Table; + // TableID kanske inte är valid längre om en ny wavetable laddats + // Translate: TableID may not be valid anymore if a new wavetable is loaded + unsigned long MSBpos; unsigned int bs = BigMULr16(RatioA, 3 * FormantMul); @@ -383,19 +389,26 @@ void WindowOscillator::process_block(float pitch, float drift, bool stereo, bool float f = note_to_pitch((pitch - 57.f) + drift * Sub.DriftLFO[l][0] + Detune * (DetuneOffset + DetuneBias * (float)l)); int Ratio = Float2Int(220.f * 32768.f * f * (float)(storage->WindowWT.size) * - samplerate_inv); // (65536.f*0.5f), 0.5 fˆr oversampling + samplerate_inv); // (65536.f*0.5f), 0.5 for oversampling Sub.Ratio[l] = Ratio; } ProcessSubOscs(stereo); - // TODO idÈ: coupla tv subvoices s dom kan alternera window med varandra - // ( hÂll window i 180-phasediff) - // borde ge bra formant-trixning utan mellanrum - // kan ha en parameter som fadar vikten av den alternerande mellan -1 till +1 - - // TODO idÈ: free-run mode d‰r en omstart av fˆnstret inte Âterstartar oscillatorn? - + // TODO idé: coupla tvÃ¥ subvoices sÃ¥ dom kan alternera window med varandra + // ( hÃ¥ll window i 180-phasediff) + // TRANSLATE: TODO Idea: Couple two subvoices so they can alternate windows with + // eachother ( hold the 180-phase difference? 180-phase window? + + // borde ge bra formant-trixning utan mellanrum + // kan ha en parameter som fadar vikten av den alternerande mellan -1 till +1 + // TRANSLATE: should provide good formant trim without space + // may have a parameter that fades the weight of the alternate between -1 to +1 + + // TODO idé: free-run mode där en omstart av fönstret inte Ã¥terstartar oscillatorn? + // TRANSLATE: TODO Idea: free-run mode where a restart of the window does not restart the oscillator? + + // int32 -> float conversion #if PPC vFloat scale = (vFloat)OutAttenuation; diff --git a/src/common/dsp/effect/ConditionerEffect.cpp b/src/common/dsp/effect/ConditionerEffect.cpp index d90695e3f01..f6e7d93d4e8 100644 --- a/src/common/dsp/effect/ConditionerEffect.cpp +++ b/src/common/dsp/effect/ConditionerEffect.cpp @@ -4,7 +4,7 @@ #include #endif -/* conditioner */ +/* conditioner */ using namespace vt_dsp; @@ -99,7 +99,8 @@ void ConditionerEffect::process(float* dataL, float* dataR) width.set_target_smoothed(clamp1bp(*f[2])); postamp.set_target_smoothed(db_to_linear(*f[7])); - // gör conditioner SSE-snäll + // gör conditioner SSE-snäll + // TRANSLATE: Make a condition(er?), SSE-kind (SSE-type?) _MM_ALIGN16 float M[block_size], S[block_size]; // wb = write-buffer encodeMS(dataL, dataR, M, S, block_size_quad); @@ -158,7 +159,7 @@ void ConditionerEffect::process(float* dataL, float* dataR) vu[4] = max(vu[4], get_absmax(dataL, block_size_quad)); vu[5] = max(vu[5], get_absmax(dataR, block_size_quad)); - /* for(int i=0; ip[7].posy_offset = 11; } void ConditionerEffect::init_default_values() -{} \ No newline at end of file +{} diff --git a/src/common/dsp/effect/Effect.cpp b/src/common/dsp/effect/Effect.cpp index 43ce656719e..aed2f18bfa4 100644 --- a/src/common/dsp/effect/Effect.cpp +++ b/src/common/dsp/effect/Effect.cpp @@ -98,14 +98,15 @@ void Effect::init_ctrltypes() } } -/* eq3band */ +/* eq3band */ Eq3BandEffect::Eq3BandEffect(SurgeStorage* storage, FxStorage* fxdata, pdata* pd) : Effect(storage, fxdata, pd), band1(storage), band2(storage), band3(storage) { gain.set_blocksize(block_size); - band1.setBlockSize(block_size * slowrate); // spelar ingen roll eftersom de är lagbaserade + band1.setBlockSize(block_size * slowrate); // spelar ingen roll eftersom de är lagbaserade + // TRANSLATE: does not matter because they are team-based band2.setBlockSize(block_size * slowrate); band3.setBlockSize(block_size * slowrate); } @@ -129,7 +130,9 @@ void Eq3BandEffect::setvars(bool init) gain.set_target(1.f); // db_to_linear(fxdata->p[9].val.f)); gain.instantize(); band1.coeff_peakEQ(band1.calc_omega(fxdata->p[1].val.f * (1.f / 12.f)), fxdata->p[2].val.f, - 1.f); // sätt banden till 0dB så fades eqn in + 1.f); // sätt banden till 0dB sÃ¥ fades eqn in + // TRANSLATE1: put the bands to 0dB - then fade EQ + // TRANSLATE2: Set the bands to 0dB so the EQ fades in band2.coeff_peakEQ(band2.calc_omega(fxdata->p[4].val.f * (1.f / 12.f)), fxdata->p[5].val.f, 1.f); band3.coeff_peakEQ(band3.calc_omega(fxdata->p[7].val.f * (1.f / 12.f)), fxdata->p[8].val.f, @@ -244,7 +247,7 @@ void Eq3BandEffect::init_default_values() fxdata->p[9].val.f = 0.f; } -/* chorus */ +/* chorus */ template ChorusEffect::ChorusEffect(SurgeStorage* storage, FxStorage* fxdata, pdata* pd) diff --git a/src/common/dsp/effect/Reverb1Effect.cpp b/src/common/dsp/effect/Reverb1Effect.cpp index 0aaca899868..b9e5f202117 100644 --- a/src/common/dsp/effect/Reverb1Effect.cpp +++ b/src/common/dsp/effect/Reverb1Effect.cpp @@ -53,10 +53,10 @@ void Reverb1Effect::init() modphase = 0; update_rsize(); // mix.set_target(fxdata->p[rp_mix].val.f); - mix.set_target(1.f); // borde bli mest smooth + mix.set_target(1.f); // borde bli mest smooth -> Should be most smooth mix.instantize(); - width.set_target(1.f); // borde bli mest smooth + width.set_target(1.f); // borde bli mest smooth -> Should be most smooth width.instantize(); for (int t = 0; t < rev_taps; t++) @@ -459,4 +459,4 @@ void Reverb1Effect::init_default_values() // fxdata->p[rp_moddepth].val.f = 0.02f; // fxdata->p[rp_modrate].val.f = -2.5f; // fxdata->p[rp_variation].val.f = 0.5f; -} \ No newline at end of file +} diff --git a/src/common/dsp/effect/VocoderEffect.cpp b/src/common/dsp/effect/VocoderEffect.cpp index 6aab1527cb4..c7917beee99 100644 --- a/src/common/dsp/effect/VocoderEffect.cpp +++ b/src/common/dsp/effect/VocoderEffect.cpp @@ -1,9 +1,9 @@ #include "effect_defs.h" #include -/* vocoder */ +/* vocoder */ -// hz från http://www.sequencer.de/pix/moog/moog_vocoder_rack.jpg +// HZ from http://www.sequencer.de/pix/moog/moog_vocoder_rack.jpg // const float vocoder_freq_moog[n_vocoder_bands-1] = {50, 158, 200, 252, 317, 400, 504, 635, 800, // 1008, 1270, 1600, 2016, 2504, 3200, 4032, 5080}; const float vocoder_freq[n_vocoder_bands] = // {100, 175, 230, 290, 360, 450, 580, 700, 900, 1100, 1400, 1800, 2300, 2800, 3600, 4700}; const @@ -12,7 +12,7 @@ // 400, 504, 635, 800, 1008, 1270, 1600, 2016, 2504, 3200, 4032, 5080}; // const float vocoder_freq_vsm201[n_vocoder_bands-1] = -// {190, 290, 400, 510, 630, 760, 910, 1080, 1270, 1480, 1700, 2000, 2300, 2700, 3100, 3700, +// {190, 290, 400, 510, 630, 760, 910, 1080, 1270, 1480, 1700, 2000, 2300, 2700, 3100, 3700, // 4400, 5200, 6600, 8000}; const float vocoder_freq_vsm201[n_vocoder_bands] = {170, 240, 340, 440, // 560, 680, 820, 970, 1150, 1370, 1605, 1850, 2150, 2500, 2900, 3400, 4050, 4850, 5850, 7500}; @@ -75,7 +75,7 @@ void VocoderEffect::setvars(bool init) } /* mVoicedDetect.coeff_LP(biquadunit::calc_omega_from_Hz(1000.f), 0.707); - mUnvoicedDetect.coeff_HP(biquadunit::calc_omega_from_Hz(5000.f), 0.707); + mUnvoicedDetect.coeff_HP(biquadunit::calc_omega_from_Hz(5000.f), 0.707); if (init) { @@ -105,7 +105,7 @@ void VocoderEffect::process(float* dataL, float* dataR) // Voiced / Unvoiced detection /*{ - + mVoicedDetect.process_block_to(modulator_in, modulator_tbuf); float a = min(4.f, get_squaremax(modulator_tbuf,block_size_quad)); mVoicedLevel = mVoicedLevel * (1.f - rate) + a*rate; @@ -237,4 +237,4 @@ void VocoderEffect::init_ctrltypes() fxdata->p[KQuality].posy_offset = 3; } -//------------------------------------------------------------------------------------------------ \ No newline at end of file +//------------------------------------------------------------------------------------------------ diff --git a/src/common/gui/CLFOGui.cpp b/src/common/gui/CLFOGui.cpp index 3b91cdbe9de..f8afa036013 100644 --- a/src/common/gui/CLFOGui.cpp +++ b/src/common/gui/CLFOGui.cpp @@ -45,7 +45,11 @@ void CLFOGui::draw(CDrawContext* dc) maindisp.bottom -= 1; cdisurf->begin(); +#if MAC + cdisurf->clear(0x0090ffff); +#else cdisurf->clear(0xffff9000); +#endif int w = cdisurf->getWidth(); int h = cdisurf->getHeight(); @@ -497,4 +501,4 @@ CMouseEventResult CLFOGui::onMouseMoved(CPoint& where, const CButtonState& butto } } return kMouseEventHandled; -} \ No newline at end of file +} diff --git a/src/common/gui/CLFOGui.h b/src/common/gui/CLFOGui.h index a4be9c69268..82efb3140b5 100644 --- a/src/common/gui/CLFOGui.h +++ b/src/common/gui/CLFOGui.h @@ -67,8 +67,13 @@ class CLFOGui : public CControl 255); unsigned int a = 0xff; - coltable[i] = r | (g << 8) | (b << 16) | (a << 24); - } +#if MAC && !PPC + // MAC uses a different raw pixel byte order than windows + coltable[ i ] = ( b << 8 ) | ( g << 16 ) | ( r << 24 ) | a; +#else + coltable[i] = r | (g << 8) | (b << 16) | (a << 24); +#endif + } } // virtual void mouse (CDrawContext *pContext, CPoint &where, long buttons = -1); virtual CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons); @@ -96,4 +101,4 @@ class CLFOGui : public CControl int controlstate; CLASS_METHODS(CLFOGui, CControl) -}; \ No newline at end of file +}; diff --git a/src/common/gui/COscillatorDisplay.cpp b/src/common/gui/COscillatorDisplay.cpp index 0a4ec22511c..df57c6601c7 100644 --- a/src/common/gui/COscillatorDisplay.cpp +++ b/src/common/gui/COscillatorDisplay.cpp @@ -101,8 +101,8 @@ void COscillatorDisplay::draw(CDrawContext* dc) else if (dimax < last_imin) dimax = last_imin; } - dimin = limit_range(dimin, 0, h); - dimax = limit_range(dimax, 0, h); + dimin = limit_range(dimin, 0, h-1); + dimax = limit_range(dimax, 0, h-1); // int yp = (int)((float)(size.height() * (-osc->output[block_pos]*0.5+0.5))); // yp = limit_range(yp,0,h-1); @@ -283,11 +283,12 @@ CMouseEventResult COscillatorDisplay::onMouseDown(CPoint& where, const CButtonSt strncpy(name, storage->wt_category[c].name.c_str(), namechars); contextMenu->addEntry(subMenu, name); - subMenu->forget(); // viktigt, så att refcounter blir rätt + subMenu->forget(); // Important, so that the refcounter gets right } getFrame()->addView(contextMenu); // add to frame contextMenu->setDirty(); + contextMenu->popup(); contextMenu->onMouseDown(where, kLButton); // <-- modal menu loop is here // getFrame()->looseFocus(pContext); @@ -323,4 +324,4 @@ CMouseEventResult COscillatorDisplay::onMouseMoved(CPoint& where, const CButtonS invalid();*/ } return kMouseEventHandled; -} \ No newline at end of file +} diff --git a/src/common/gui/CPatchBrowser.cpp b/src/common/gui/CPatchBrowser.cpp index 97c96cb297c..2b35b9e0383 100644 --- a/src/common/gui/CPatchBrowser.cpp +++ b/src/common/gui/CPatchBrowser.cpp @@ -78,7 +78,7 @@ CMouseEventResult CPatchBrowser::onMouseDown(CPoint& where, const CButtonState& } } - // dela in kategorier med fler entries än splitcount i subkategorier ex. bass (1,2) etc etc + // Divide categories with more entries than splitcount into subcategories f.ex. bass (1,2) etc etc int n_subc = 1 + (max(2, (int)ctge.size()) - 1) / splitcount; for (int subc = 0; subc < n_subc; subc++) { @@ -116,7 +116,7 @@ CMouseEventResult CPatchBrowser::onMouseDown(CPoint& where, const CButtonState& if (!single_category) { contextMenu->addEntry(subMenu, name); - subMenu->forget(); // viktigt, så att refcounter blir rätt + subMenu->forget(); // Important, so that the refcounter gets it right } main_e++; } diff --git a/src/common/gui/SurgeGUIEditor.cpp b/src/common/gui/SurgeGUIEditor.cpp index 7f53d7ff01d..4d3e4a84827 100644 --- a/src/common/gui/SurgeGUIEditor.cpp +++ b/src/common/gui/SurgeGUIEditor.cpp @@ -20,8 +20,10 @@ #include "SurgeBitmaps.h" #include "CNumberField.h" -/*#if TARGET_AUDIOUNIT +#if TARGET_AUDIOUNIT #include "aulayer.h" +#endif +/* #elif TARGET_VST3 #include "surgeprocessor.h" #elif TARGET_VST2 @@ -63,6 +65,7 @@ enum special_tags tag_about, tag_mod_source0, tag_mod_source_end = tag_mod_source0 + n_modsources, + tag_mp_zoom, // tag_metaparam, // tag_metaparam_end = tag_metaparam+n_customcontrollers, start_paramtags, @@ -126,11 +129,13 @@ SurgeGUIEditor::SurgeGUIEditor(void* effect, SurgeSynthesizer* synth) : super(ef #ifdef TARGET_VST3 _idleTimer = new CVSTGUITimer([this](CVSTGUITimer* timer) { idle(); }, 50, false); #endif + zoom_callback = [](SurgeGUIEditor *f){ }; + zoomFactor = 100; } SurgeGUIEditor::~SurgeGUIEditor() { - if (frame) + if (frame ) { getFrame()->unregisterKeyboardHook(this); frame->removeAll(true); @@ -1062,6 +1067,23 @@ void SurgeGUIEditor::openOrRecreateEditor() getSurgeBitmap(IDB_BUTTON_ABOUT), nopoint, false); frame->addView(b_about); +#if TARGET_AUDIOUNIT + // ZOOM CONTROL for now is only implemented in the Audio Unit host + CHSwitch2* mp_zoom = + new CHSwitch2(CRect( 892-77, 526, 892 - 40, 526 + 12 ), this, tag_mp_zoom, 2, 12, 1, 2, + getSurgeBitmap(IDB_BUTTON_MINUSPLUS), nopoint, false); + frame->addView(mp_zoom); + CTextLabel *Comments = new + CTextLabel(CRect( 892-137, 526, 892 - 77, 526 + 12 ), "Zoom" ); + + Comments->setTransparency(true); + Comments->setFont(minifont); + Comments->setFontColor( kBlackCColor ); + Comments->setHoriAlign(kRightText); + frame->addView(Comments); + // END ZOOM CONTROL +#endif + infowindow = new CParameterTooltip(CRect(0, 0, 0, 0)); frame->addView(infowindow); @@ -1160,6 +1182,10 @@ bool PLUGIN_API SurgeGUIEditor::open(void* parent, const PlatformType& platformT void SurgeGUIEditor::close() { +#ifndef TARGET_VST3 + super::close(); +#endif + #ifdef TARGET_VST3 _idleTimer->stop(); #endif @@ -1850,6 +1876,16 @@ void SurgeGUIEditor::valueChanged(CControl* control) return; } break; + case tag_mp_zoom: + { + if (control->getValue() > 0.5f) + zoomInDir( 1 ); + else + zoomInDir( -1 ); + return; + + } + break; case tag_osc_select: { current_osc = (int)(control->getValue() * 2.f + 0.5f); @@ -2216,4 +2252,19 @@ bool SurgeGUIEditor::showPatchStoreDialog(patchdata* p, return false; } +void SurgeGUIEditor::zoomInDir( int dir ) +{ + if( dir > 0 ) + { + zoomFactor += 10; + } + else + { + zoomFactor -= 10; + } + if( zoomFactor < 50 ) zoomFactor = 50; + if( zoomFactor > 300 ) zoomFactor = 300; + zoom_callback( this ); +} + //------------------------------------------------------------------------------------------------ diff --git a/src/common/gui/SurgeGUIEditor.h b/src/common/gui/SurgeGUIEditor.h index 47f8d348117..e4f0c123100 100644 --- a/src/common/gui/SurgeGUIEditor.h +++ b/src/common/gui/SurgeGUIEditor.h @@ -86,6 +86,16 @@ class SurgeGUIEditor : public EditorType, public IControlListener, public IKeybo vector* patch_category, int startcategory); + + void zoomInDir( int dir ); + int zoomFactor; + public: + void setZoomCallback( std::function< void(SurgeGUIEditor *) > f ) { zoom_callback = f; } + int getZoomFactor() { return zoomFactor; } + void setZoomFactor( int zf ) { zoomFactor = zf; zoom_callback( this ); } + private: + std::function< void(SurgeGUIEditor *) > zoom_callback; + SurgeBitmaps bitmap_keeper; CControl* vu[16]; diff --git a/src/common/version.h b/src/common/version.h index f41797707a5..278ae11d028 100644 --- a/src/common/version.h +++ b/src/common/version.h @@ -18,7 +18,7 @@ #define BUILD_NUMBER_INT 100 // Version with build number (example "1.0.3.342") -#define FULL_VERSION_STR \ +#define FULL_VERSION_STR \ MAJOR_VERSION_STR "." SUB_VERSION_STR "." RELEASE_NUMBER_STR "." BUILD_NUMBER_STR // Version without build number (example "1.0.3") @@ -41,7 +41,7 @@ #endif #define stringCompanyName "Vember Audio\0" -#define stringLegalCopyright "© 2017 Vember Audio" +#define stringLegalCopyright "© 2017 Vember Audio" #define stringLegalTrademarks "VST is a trademark of Steinberg Media Technologies GmbH" #endif //__version__ diff --git a/src/common/vt_dsp/basic_dsp.cpp b/src/common/vt_dsp/basic_dsp.cpp index 77e9ce9be8f..76d7cda5c55 100644 --- a/src/common/vt_dsp/basic_dsp.cpp +++ b/src/common/vt_dsp/basic_dsp.cpp @@ -81,7 +81,7 @@ unsigned int Max(unsigned int a, unsigned int b) int limit_range(int x, int l, int h) { -#if _M_X64 || PPC || __linux__ +#if _M_X64 || PPC || __linux__ || MAC return max(min(x, h), l); #else __asm diff --git a/src/common/vt_dsp/basic_dsp.h b/src/common/vt_dsp/basic_dsp.h index 15fbab692ec..0cf02a80953 100644 --- a/src/common/vt_dsp/basic_dsp.h +++ b/src/common/vt_dsp/basic_dsp.h @@ -1,4 +1,3 @@ - #pragma once #include "shared.h" @@ -160,7 +159,7 @@ forceinline float saturate(float f) forceinline __m128 softclip_ss(__m128 in) { - // y = x - (4/27)*x^3, x € [-1.5 .. 1.5] + // y = x - (4/27)*x^3, x € [-1.5 .. 1.5] const __m128 a = _mm_set_ss(-4.f / 27.f); const __m128 x_min = _mm_set_ss(-1.5f); @@ -177,7 +176,7 @@ forceinline __m128 softclip_ss(__m128 in) forceinline __m128 softclip_ps(__m128 in) { - // y = x - (4/27)*x^3, x € [-1.5 .. 1.5] + // y = x - (4/27)*x^3, x € [-1.5 .. 1.5] const __m128 a = _mm_set1_ps(-4.f / 27.f); const __m128 x_min = _mm_set1_ps(-1.5f); diff --git a/src/common/vt_dsp/halfratefilter.cpp b/src/common/vt_dsp/halfratefilter.cpp index 5969f1dea2a..d6c84e0c7ed 100644 --- a/src/common/vt_dsp/halfratefilter.cpp +++ b/src/common/vt_dsp/halfratefilter.cpp @@ -117,6 +117,10 @@ void halfrate_stereo::process_block(float* __restrict floatL, float* __restrict #if 0 // software pipelining.. fin id� men kompilatorn gillade det inte alls // den andra �r ganska ok eftersom ty0 inte anv�nds f�rr�n om 2 samples, d�rf�r delas latency-dependencyn med 3 +// TRANSLATE: +// Software pipelining.. Fine idea, but the compiler does not like it one bit +// The other (?) is quite okay, because ty0 is not used (for) fewer than 2 samples, therefore the latency dependency +// is divided by 3 (?) void halfrate_stereo::process_block(float * __restrict floatL, float * __restrict floatR, int N) { int NM1 = N + M - 1; @@ -207,6 +211,7 @@ void halfrate_stereo::process_block_D2( /* // g�r s�h�r om man vill undvika downsampling + // TRANSLATE: If you want to avoid downsampling for(unsigned int k=0; k> 8) & 0x0000ff00) | ((t >> 24) & 0x000000ff); #else - // gcc verkar inte respektera att eax mÃ¥ste stämma när den returneras.. lägg till: ret eax? + // gcc verkar inte respektera att eax mÃ¥ste stämma när den returneras.. lägg till: ret eax? + // GCC does not seem to respect that eax must be correct when it is returned/when it returns: add: the correct eax? __asm { mov eax, t diff --git a/src/todo/effect_emphasize.cpp b/src/todo/effect_emphasize.cpp index cbfda8deacc..339162830fd 100644 --- a/src/todo/effect_emphasize.cpp +++ b/src/todo/effect_emphasize.cpp @@ -3,7 +3,7 @@ using namespace vt_dsp; -//görs bättre med fft +//Done better with FFT (Do this better with FFT? Should be done better with FFT?) görs bättre med fft emphasize::emphasize(sub3_storage *storage, sub3_fx *fxdata, pdata* pd) : baseeffect(storage,fxdata,pd), EQ(storage), pre(3,true), post(3,true) @@ -54,7 +54,9 @@ void emphasize::process(float *dataL, float *dataR) for(int k=0; kp[0].set_name("amount"); fxdata->p[0].set_type(ct_decibel); + fxdata->p[0].set_name("amount"); fxdata->p[0].set_type(ct_decibel); fxdata->p[1].set_name("freq"); fxdata->p[1].set_type(ct_freq_audible); - fxdata->p[2].set_name("BW"); fxdata->p[2].set_type(ct_bandwidth); - fxdata->p[3].set_name("type"); fxdata->p[3].set_type(ct_percent); + fxdata->p[2].set_name("BW"); fxdata->p[2].set_type(ct_bandwidth); + fxdata->p[3].set_name("type"); fxdata->p[3].set_type(ct_percent); fxdata->p[0].posy_offset = 1; fxdata->p[1].posy_offset = 1; @@ -113,4 +115,4 @@ void emphasize::init_ctrltypes() void emphasize::init_default_values() { fxdata->p[0].val.f = 0.f; -} \ No newline at end of file +} diff --git a/src/todo/sub3_osc_dot.cpp b/src/todo/sub3_osc_dot.cpp index 274abf1ea2e..4dc7f112f93 100644 --- a/src/todo/sub3_osc_dot.cpp +++ b/src/todo/sub3_osc_dot.cpp @@ -8,10 +8,10 @@ const __int64 large = 0x10000000000; //const float integrator_hpf = 0.99999999f; //const float integrator_hpf = 0.9992144f; // 44.1 kHz //const float integrator_hpf = 0.9964f; // 44.1 kHz -//const float integrator_hpf = 0.9982f; // 44.1 kHz magisk moog freq +//const float integrator_hpf = 0.9982f; // 44.1 kHz Magic Moog Frequency const float integrator_hpf = 0.999f; -// 290 samples för att falla 50% (british) (är nog ett 2-pole hpf) -// 202 samples (american) +// 290 samples to fall 50% (British) (is probably a 2-pole HPF) +// 202 samples (American) //const float integrator_hpf = 0.999f; //pow(ln(0.5)/(samplerate/50hz) const float hpf_cycle_loss = 0.90f; @@ -36,7 +36,7 @@ void osc_dotwave::init(float pitch, bool is_display) osc_out_2 = 0; bufpos = 0; - // init här + // init här id_shape = oscdata->p[0].param_id_in_scene; id_vskew = oscdata->p[1].param_id_in_scene; id_hskew = oscdata->p[2].param_id_in_scene; @@ -48,7 +48,7 @@ void osc_dotwave::init(float pitch, bool is_display) if(is_display) n_unison = 1; out_attenuation = 1.0f/sqrt((float)n_unison); - if(n_unison == 1) // gör dynamic honk sen.. + if(n_unison == 1) // Make dynamic baskets (?) later.. (gör dynamic honk sen..) { detune_bias = 1; detune_offset = 0; @@ -88,12 +88,12 @@ void osc_dotwave::init(float pitch, bool is_display) void osc_dotwave::init_ctrltypes() { - oscdata->p[0].set_name("shape"); oscdata->p[0].set_type(ct_percent); - oscdata->p[1].set_name("skew v"); oscdata->p[1].set_type(ct_percent_bidirectional); - oscdata->p[2].set_name("skew h"); oscdata->p[2].set_type(ct_percent_bidirectional); - oscdata->p[3].set_name("formant"); oscdata->p[3].set_type(ct_syncpitch); - oscdata->p[4].set_name("sync"); oscdata->p[4].set_type(ct_syncpitch); - oscdata->p[5].set_name("detune"); oscdata->p[5].set_type(ct_percent); + oscdata->p[0].set_name("shape"); oscdata->p[0].set_type(ct_percent); + oscdata->p[1].set_name("skew v"); oscdata->p[1].set_type(ct_percent_bidirectional); + oscdata->p[2].set_name("skew h"); oscdata->p[2].set_type(ct_percent_bidirectional); + oscdata->p[3].set_name("formant"); oscdata->p[3].set_type(ct_syncpitch); + oscdata->p[4].set_name("sync"); oscdata->p[4].set_type(ct_syncpitch); + oscdata->p[5].set_name("detune"); oscdata->p[5].set_type(ct_percent); oscdata->p[6].set_name("osc count"); oscdata->p[6].set_type(ct_osccount); } void osc_dotwave::init_default_values() @@ -173,7 +173,7 @@ void osc_dotwave::convolute(int voice) return; } } - dt = max(0.000001,dt); // temp, så den inte hänger sig + dt = max(0.000001,dt); // Temporary, so it doesn't hang/crash(?) (temp, sÃ¥ den inte hänger sig) float newlevel = distort_level((1-shape)*dotwave[0][(state[voice]+1) % n_steps][1] + (shape)*dotwave[1][(state[voice]+1) % n_steps][1]); //float newlevel = distort_level((1-shape)*dotwave[0][(state[voice]) % n_steps][1] + (shape)*dotwave[1][(state[voice]) % n_steps][1]); @@ -215,8 +215,10 @@ void osc_dotwave::update_lagvals() l_formant.newValue(max(0.f,localcopy[id_formant].f)); float invt = min(1.0,(8.175798915 * storage->note_to_pitch(pitch + l_sync.v)) / storage->dsamplerate_os); - float hpf2 = min(integrator_hpf,powf(hpf_cycle_loss,4*invt)); // ACHTUNG! gör lookup-table - + float hpf2 = min(integrator_hpf,powf(hpf_cycle_loss,4*invt)); + // ACHTUNG! gör lookup-table + // ACHTUNG!/WARNING!: Make a lookup table + hpf_coeff.newValue(hpf2); integrator_mult.newValue(invt); @@ -301,4 +303,4 @@ template void osc_dotwave::process_blockT(float pitch,float depth) bufpos++; bufpos = bufpos&(ob_length-1); } -} \ No newline at end of file +} diff --git a/src/todo/sub3_osc_sample.cpp b/src/todo/sub3_osc_sample.cpp index 520c1f4f0ad..83b39d13a9b 100644 --- a/src/todo/sub3_osc_sample.cpp +++ b/src/todo/sub3_osc_sample.cpp @@ -15,28 +15,29 @@ osc_sample::~osc_sample() void osc_sample::init(float pitch, bool is_display) { assert(storage); - - // init här + + //Init(ialize) here //id_shape = oscdata->p[0].param_id_in_scene; - + this->pitch = pitch; update_lagvals(); } void osc_sample::init_ctrltypes() { - //oscdata->p[0].set_name("correlation"); oscdata->p[0].set_type(ct_percent_bidirectional); - + //oscdata->p[0].set_name("correlation"); + //oscdata->p[0].set_type(ct_percent_bidirectional); } + void osc_sample::init_default_values() { - //oscdata->p[0].val.f = 0.f; + //oscdata->p[0].val.f = 0.f; } template void osc_sample::update_lagvals() { -// l_sync.newValue(max(0.f,localcopy[id_sync].f)); + // l_sync.newValue(max(0.f,localcopy[id_sync].f)); if(is_init) { } @@ -49,15 +50,15 @@ template void osc_sample::process_blockT(float pitch,float depth) this->pitch = pitch; if (FM) FMdepth.newValue(depth); - float pitchcorrection = 0;//wave->smpl_chunk. + float pitchcorrection = 0;//wave->smpl_chunk. resample_ratio = (unsigned int)((double)((wave->sample_rate * storage->dsamplerate_os_inv)*16777216.0*storage->note_to_pitch(pitch-pitchcorrection))); - + update_lagvals(); for(int k=0; k>16)&0xff)*FIRipol_N; float lipol0 = (float)((uint32)(sample_subpos&0xffff)); - - } -} \ No newline at end of file + + } +} diff --git a/src/todo/sub3_osc_wavetable2.cpp b/src/todo/sub3_osc_wavetable2.cpp index 7fec9a250ce..f0584a6f4a5 100644 --- a/src/todo/sub3_osc_wavetable2.cpp +++ b/src/todo/sub3_osc_wavetable2.cpp @@ -22,7 +22,7 @@ void osc_wavetable2::init(float pitch, bool is_display) osc_out = _mm_set1_ps(0.f); bufpos = 0; - // init här + // init här id_shape = oscdata->p[0].param_id_in_scene; id_vskew = oscdata->p[1].param_id_in_scene; id_clip = oscdata->p[2].param_id_in_scene; @@ -46,7 +46,7 @@ void osc_wavetable2::init(float pitch, bool is_display) if(is_display) n_unison = 1; out_attenuation = 1.0f/sqrt((float)n_unison); - if(n_unison == 1) // gör dynamic honk sen.. + if(n_unison == 1) // Make dynamic baskets (?) later... (gör dynamic honk sen..) { detune_bias = 1; detune_offset = 0; @@ -101,11 +101,11 @@ void osc_wavetable2::init(float pitch, bool is_display) void osc_wavetable2::init_ctrltypes() { - oscdata->p[0].set_name("shape"); oscdata->p[0].set_type(ct_percent); - oscdata->p[1].set_name("skew v"); oscdata->p[1].set_type(ct_percent_bidirectional); - oscdata->p[2].set_name("saturate"); oscdata->p[2].set_type(ct_percent); - oscdata->p[3].set_name("formant"); oscdata->p[3].set_type(ct_syncpitch); - oscdata->p[4].set_name("skew h"); oscdata->p[4].set_type(ct_percent_bidirectional); + oscdata->p[0].set_name("shape"); oscdata->p[0].set_type(ct_percent); + oscdata->p[1].set_name("skew v"); oscdata->p[1].set_type(ct_percent_bidirectional); + oscdata->p[2].set_name("saturate"); oscdata->p[2].set_type(ct_percent); + oscdata->p[3].set_name("formant"); oscdata->p[3].set_type(ct_syncpitch); + oscdata->p[4].set_name("skew h"); oscdata->p[4].set_type(ct_percent_bidirectional); oscdata->p[5].set_name("osc spread"); oscdata->p[5].set_type(ct_percent); oscdata->p[6].set_name("osc count"); oscdata->p[6].set_type(ct_osccount); } @@ -165,7 +165,7 @@ void osc_wavetable2::convolute(int voice, bool FM) else { tableid = oscdata->wt.n_tables-2; - oscstate[voice] = 100000000000.f; // rather large number + oscstate[voice] = 100000000000.f; // rather large number return; } } @@ -276,7 +276,7 @@ void osc_wavetable2::update_lagvals() formant_t = max(0.f,localcopy[id_formant].f); float invt = min(1.0,(8.175798915 * storage->note_to_pitch(pitch_t)) / storage->dsamplerate_os); - float hpf2 = min(integrator_hpf,powf(hpf_cycle_loss,4*invt)); // ACHTUNG! gör lookup-table + float hpf2 = min(integrator_hpf,powf(hpf_cycle_loss,4*invt)); // ACHTUNG!/WARNING! Make a lookup-table hpf_coeff.newValue(hpf2); integrator_mult.newValue(invt); @@ -303,7 +303,7 @@ template void osc_wavetable2::process_blockT(float pitch0,float depth,f pitch_last = pitch_t; pitch_t = min(148.f,pitch0); pitchmult_inv = max(1.0,storage->dsamplerate_os * (1 / 8.175798915) * storage->note_to_pitch_inv(pitch_t)); - pitchmult = 1.f / pitchmult_inv; // try to hide the latency + pitchmult = 1.f / pitchmult_inv; // try to hide the latency this->drift = drift; int k,l; @@ -425,4 +425,4 @@ template void osc_wavetable2::process_blockT(float pitch0,float depth,f _mm_store_ps(&oscbuffer[ob_length+k],zero); } } -} \ No newline at end of file +} diff --git a/src/vst3/SurgeVst3EditController.cpp b/src/vst3/SurgeVst3EditController.cpp index a7f419324c2..76551d32258 100644 --- a/src/vst3/SurgeVst3EditController.cpp +++ b/src/vst3/SurgeVst3EditController.cpp @@ -2,7 +2,7 @@ #include "pluginterfaces/base/ustring.h" -#if !TARGET_AUDIOUNIT +#if !TARGET_AUDIOUNIT && !MAC tresult PLUGIN_API SurgeVst3EditController::initialize(FUnknown* context) { tresult result = EditControllerEx1::initialize(context); diff --git a/src/vst3/SurgeVst3EditController.h b/src/vst3/SurgeVst3EditController.h index ce045e0cb95..4b035e6380f 100644 --- a/src/vst3/SurgeVst3EditController.h +++ b/src/vst3/SurgeVst3EditController.h @@ -4,7 +4,7 @@ using namespace Steinberg; using namespace Steinberg::Vst; class SurgeEditorView; -#if !TARGET_AUDIOUNIT +#if !TARGET_AUDIOUNIT && !MAC class SurgeVst3EditController : public EditControllerEx1, public IMidiMapping { diff --git a/surge.pdf b/surge.pdf new file mode 100644 index 00000000000..a1b2ead7eb9 Binary files /dev/null and b/surge.pdf differ