From 39bb8fa340442ba6bb75916c7ce92b3821c4a54c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 10 Jun 2022 11:58:40 +0100 Subject: [PATCH 001/222] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d3751f33..142eaddf4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ FrameLib currently consists of: Where to start: --------------------------------- -- To get the Max package: https://github.com/AlexHarker/FrameLib/releases/ +- To get the Max package download it from the Package Manager via the Max application - To compile FrameLib clone this repo and start in the XCode project or VS solution - For max builds you will require https://github.com/Cycling74/max-sdk-base (to be placed alongside this repo in the same enclosing folder) - If you wish to code new objects read the (limited) doxygen documentation of the framework source code From 1487d8ecf26c3f1c7aed792ccc6ba17a16b89889 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 10 Jun 2022 14:24:45 +0100 Subject: [PATCH 002/222] Correct normalised smoothing amounts --- FrameLib_Objects/Vector/FrameLib_KernelSmooth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Objects/Vector/FrameLib_KernelSmooth.cpp b/FrameLib_Objects/Vector/FrameLib_KernelSmooth.cpp index 819c61041..6f95b6ca5 100644 --- a/FrameLib_Objects/Vector/FrameLib_KernelSmooth.cpp +++ b/FrameLib_Objects/Vector/FrameLib_KernelSmooth.cpp @@ -137,8 +137,8 @@ void FrameLib_KernelSmooth::process() if (mParameters.getEnum(kScale) == kNormalised) { - width_lo /= static_cast(sizeIn1); - width_hi /= static_cast(sizeIn1); + width_lo *= static_cast(sizeIn1); + width_hi *= static_cast(sizeIn1); } mSmoother.smooth(output, input, kernel, sizeIn1, sizeIn2, width_lo, width_hi, symmetric, edges); From 9650f11c9d9ed64a878f992123a050c40e9355d9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 30 Jun 2022 11:26:39 +0100 Subject: [PATCH 003/222] Const updates from HISSTools Library --- FrameLib_Dependencies/Statistics.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FrameLib_Dependencies/Statistics.hpp b/FrameLib_Dependencies/Statistics.hpp index fc9455532..fd95df900 100644 --- a/FrameLib_Dependencies/Statistics.hpp +++ b/FrameLib_Dependencies/Statistics.hpp @@ -162,7 +162,7 @@ double stat_sum(const T input, size_t size) template double stat_sum_abs(const T input, size_t size) { - return stat_sum(impl::modified_data(input), size); + return stat_sum(impl::modified_data(input), size); } template @@ -345,30 +345,30 @@ double stat_kurtosis(const T input, size_t size) template double stat_log_centroid(const T input, size_t size) { - return exp2(stat_weighted_sum(impl::log_indices(), impl::log_width(input), size) / (stat_sum(impl::log_width(input), size))); + return exp2(stat_weighted_sum(impl::log_indices(), impl::log_width(input), size) / (stat_sum(impl::log_width(input), size))); } template double stat_log_spread(const T input, size_t size) { double centroid = stat_log_centroid(input, size); - return sqrt(stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / (stat_sum(impl::log_width(input)), size)); + return sqrt(stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / stat_sum(impl::log_width(input), size)); } template double stat_log_skewness(const T input, size_t size) { double centroid = stat_log_centroid(input, size); - double denominator = impl::pow3()(stat_log_spread(input, size)) * statSum(impl::log_width(input), size); - return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / denominator : 0.0; + double denominator = impl::pow3()(stat_log_spread(input, size)) * stat_sum(impl::log_width(input), size); + return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / denominator : 0.0; } template double stat_log_kurtosis(const T input, size_t size) { double centroid = stat_centroid(input, size); - double denominator = impl::pow4()(stat_log_spread(input, size)) * stat_sum(impl::log_width(input), size); - return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / denominator : std::numeric_limits::infinity(); + double denominator = impl::pow4()(stat_log_spread(input, size)) * stat_sum(impl::log_width(input), size); + return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / denominator : std::numeric_limits::infinity(); } // Flatness From e47bb965386652f10dc0fb2f60b4153fd6cb4295 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 12 Jul 2022 17:03:09 +0100 Subject: [PATCH 004/222] Fix helpfile still using numbers to set an enum --- .../help_files/internal_tabs/fl.shift~.maxhelp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/Max Documentation/content/help_files/internal_tabs/fl.shift~.maxhelp b/Documentation/Max Documentation/content/help_files/internal_tabs/fl.shift~.maxhelp index 4eefe4d1a..6c19ded6f 100644 --- a/Documentation/Max Documentation/content/help_files/internal_tabs/fl.shift~.maxhelp +++ b/Documentation/Max Documentation/content/help_files/internal_tabs/fl.shift~.maxhelp @@ -4,7 +4,7 @@ "appversion" : { "major" : 8, "minor" : 3, - "revision" : 0, + "revision" : 1, "architecture" : "x64", "modernui" : 1 } @@ -51,7 +51,7 @@ "appversion" : { "major" : 8, "minor" : 3, - "revision" : 0, + "revision" : 1, "architecture" : "x64", "modernui" : 1 } @@ -113,7 +113,7 @@ "appversion" : { "major" : 8, "minor" : 3, - "revision" : 0, + "revision" : 1, "architecture" : "x64", "modernui" : 1 } @@ -298,7 +298,7 @@ "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, - "patching_rect" : [ 336.5, 195.0, 138.0, 25.0 ], + "patching_rect" : [ 312.75, 195.0, 138.0, 25.0 ], "text" : "Set edge behaviour", "textjustification" : 1 } @@ -355,7 +355,7 @@ "numoutlets" : 3, "outlettype" : [ "int", "", "" ], "parameter_enable" : 0, - "patching_rect" : [ 263.5, 195.0, 66.5, 23.0 ] + "patching_rect" : [ 239.75, 195.0, 66.5, 23.0 ] } } @@ -518,7 +518,7 @@ , { "patchline" : { "destination" : [ "obj-5", 0 ], - "source" : [ "obj-31", 0 ] + "source" : [ "obj-31", 1 ] } } From c16398dfe0e46322b032380001e9a4d38e8248d9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 20 Jul 2022 20:16:59 +0100 Subject: [PATCH 005/222] Ensure that radii cannot be negative to avoid NaNs and make behaviour of 2D/3D consistent --- FrameLib_Objects/Spatial/FrameLib_Poltocar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Objects/Spatial/FrameLib_Poltocar.h b/FrameLib_Objects/Spatial/FrameLib_Poltocar.h index 5405363ca..3d385c60d 100644 --- a/FrameLib_Objects/Spatial/FrameLib_Poltocar.h +++ b/FrameLib_Objects/Spatial/FrameLib_Poltocar.h @@ -15,12 +15,12 @@ namespace FrameLib_Spatial_Ops Value2D operator()(const Value2D& v) { - return std::polar(v.real(), v.imag() * mAngleFactor); + return std::polar(std::max(0.0, v.real()), v.imag() * mAngleFactor); } Value3D operator()(const Value3D& v) { - const double radius = std::get<0>(v); + const double radius = std::max(0.0, std::get<0>(v)); const double theta = std::get<1>(v) * mAngleFactor; const double psi = mAngleFactor * (mAngleOffset - std::get<2>(v)); From 7f42b250571677bdc4076f46a37d46054f519239 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 28 Jul 2022 17:06:57 +0100 Subject: [PATCH 006/222] Formatting --- FrameLib_Dependencies/TableReader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Dependencies/TableReader.hpp b/FrameLib_Dependencies/TableReader.hpp index 9ff389079..c318e5637 100644 --- a/FrameLib_Dependencies/TableReader.hpp +++ b/FrameLib_Dependencies/TableReader.hpp @@ -322,7 +322,7 @@ void table_read(Table fetcher, T *out, const U *positions, intptr_t n_samps, T m case InterpType::Linear: table_read(fetcher, out, positions, n_samps, mul); break; case InterpType::CubicHermite: table_read(fetcher, out,positions, n_samps, mul); break; case InterpType::CubicLagrange: table_read(fetcher, out, positions, n_samps, mul); break; - case InterpType::CubicBSpline: table_read(fetcher, out, positions, n_samps, mul); break; + case InterpType::CubicBSpline: table_read(fetcher, out, positions, n_samps, mul); break; } } From c5ff683c138be63b4a5684e19a2bed64a7253522 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 28 Jul 2022 17:07:07 +0100 Subject: [PATCH 007/222] Correct pdf percentile --- FrameLib_Dependencies/Statistics.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Dependencies/Statistics.hpp b/FrameLib_Dependencies/Statistics.hpp index fd95df900..e0882361d 100644 --- a/FrameLib_Dependencies/Statistics.hpp +++ b/FrameLib_Dependencies/Statistics.hpp @@ -303,7 +303,7 @@ double stat_pdf_percentile(const T input, double centile, size_t size) { sum += input[i]; if (sum >= target) - return static_cast(1 + i - ((sum - target) / input[i])); + return static_cast(i - ((sum - target) / input[i])); } return static_cast(size - 1); From c6deb0bdda4b9c217673a822152a61daf1bb6153 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 28 Jul 2022 17:13:29 +0100 Subject: [PATCH 008/222] Updates from HISSTools_Library --- FrameLib_Dependencies/RandomGenerator.hpp | 22 +++--------- FrameLib_Dependencies/SpectralProcessor.hpp | 39 +++++++++++++++++++++ FrameLib_Dependencies/Statistics.hpp | 28 ++++----------- 3 files changed, 51 insertions(+), 38 deletions(-) diff --git a/FrameLib_Dependencies/RandomGenerator.hpp b/FrameLib_Dependencies/RandomGenerator.hpp index ea1b3b16f..066e4f5dc 100755 --- a/FrameLib_Dependencies/RandomGenerator.hpp +++ b/FrameLib_Dependencies/RandomGenerator.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace random_generators { @@ -68,24 +69,11 @@ namespace random_generators { uint32_t seeds[cmwc_lag_size]; - #ifdef __APPLE__ - for (uint32_t i = 0; i < cmwc_lag_size; i++) - seeds[i] = arc4random(); - #elif defined (__linux__) - srandom(time(nullptr)); - for (uint32_t i = 0; i < cmwc_lag_size; i++) - seeds[i] = random(); - #else - HCRYPTPROV hProvider = 0; - const DWORD dwLength = 4 * cmwc_lag_size; - BYTE *pbBuffer = (BYTE *) seeds; - - if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return; + std::random_device rd; - CryptGenRandom(hProvider, dwLength, pbBuffer); - CryptReleaseContext(hProvider, 0); - #endif + for (uint32_t i = 0; i < cmwc_lag_size; i++) + seeds[i] = rd(); + seed(seeds); } diff --git a/FrameLib_Dependencies/SpectralProcessor.hpp b/FrameLib_Dependencies/SpectralProcessor.hpp index b94fd8beb..1e49aeadb 100644 --- a/FrameLib_Dependencies/SpectralProcessor.hpp +++ b/FrameLib_Dependencies/SpectralProcessor.hpp @@ -61,6 +61,35 @@ class spectral_processor set_max_fft_size(0); } + // Not Copyable + + spectral_processor(const spectral_processor&) = delete; + spectral_processor &operator =(const spectral_processor&) = delete; + + // Moveable (subject to the allocator being moveable) + + template ::value> = 0> + spectral_processor(spectral_processor&& b) + : m_allocator(std::move(b.m_allocator)) + , m_fft_setup(std::move(b.m_fft_setup)) + , m_max_fft_size_log2(b.m_max_fft_size_log2) + { + b.m_fft_setup = nullptr; + } + + template ::value> = 0> + spectral_processor &operator =(spectral_processor&& b) + { + m_allocator = std::move(b.m_allocator); + m_fft_setup = std::move(b.m_fft_setup); + m_max_fft_size_log2 = b.m_max_fft_size_log2; + b.m_fft_setup = nullptr; + + return *this; + } + + // Destructor + ~spectral_processor() { if (m_max_fft_size_log2) @@ -165,6 +194,16 @@ class spectral_processor return calc_conv_corr_size(size1, size2, mode); } + uintptr_t required_fft_size(uintptr_t size1, uintptr_t size2) const + { + if (!size1 || !size2) + return 0; + + op_sizes sizes(size1, size2, EdgeMode::Linear); + + return sizes.fft(); + } + static uintptr_t calc_fft_size_log2(uintptr_t size) { uintptr_t count = 0; diff --git a/FrameLib_Dependencies/Statistics.hpp b/FrameLib_Dependencies/Statistics.hpp index e0882361d..ef6f48789 100644 --- a/FrameLib_Dependencies/Statistics.hpp +++ b/FrameLib_Dependencies/Statistics.hpp @@ -20,14 +20,6 @@ namespace impl struct indices { template double operator[](T a) const { return static_cast(a); } }; struct log_indices { template double operator[](T a) const { return a ? log2(static_cast(a)) : 0.0; } }; - template - struct log_width - { - log_width(T& data) : m_data(data) {} - double operator[](size_t i) const { return i ? m_data[i] * (log2(i + 0.5) - log2(i - 0.5)) : m_data[i] * 0.0; } - const T m_data; - }; - template struct modified_data { @@ -216,12 +208,6 @@ double stat_weighted_sum_logs(const T input, size_t size) // Weighted Sums (by weights) -template -double stat_weighted_sum(const T input, const T weights, size_t size) -{ - return stat_weighted_sum(input, weights, size); -} - template double stat_weighted_sum_abs(const T input, const T weights, size_t size) { @@ -345,30 +331,30 @@ double stat_kurtosis(const T input, size_t size) template double stat_log_centroid(const T input, size_t size) { - return exp2(stat_weighted_sum(impl::log_indices(), impl::log_width(input), size) / (stat_sum(impl::log_width(input), size))); + return exp2(stat_weighted_sum(impl::log_indices(), input, size) / (stat_sum(input, size))); } template double stat_log_spread(const T input, size_t size) { double centroid = stat_log_centroid(input, size); - return sqrt(stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / stat_sum(impl::log_width(input), size)); + return sqrt(stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), input, size) / stat_sum(input, size)); } template double stat_log_skewness(const T input, size_t size) { double centroid = stat_log_centroid(input, size); - double denominator = impl::pow3()(stat_log_spread(input, size)) * stat_sum(impl::log_width(input), size); - return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / denominator : 0.0; + double denominator = impl::pow3()(stat_log_spread(input, size)) * stat_sum(input, size); + return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), input, size) / denominator : 0.0; } template double stat_log_kurtosis(const T input, size_t size) { - double centroid = stat_centroid(input, size); - double denominator = impl::pow4()(stat_log_spread(input, size)) * stat_sum(impl::log_width(input), size); - return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), impl::log_width(input), size) / denominator : std::numeric_limits::infinity(); + double centroid = stat_log_centroid(input, size); + double denominator = impl::pow4()(stat_log_spread(input, size)) * stat_sum(input, size); + return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), input, size) / denominator : std::numeric_limits::infinity(); } // Flatness From e99043dd1621cbe862caad57270898ccc5ebd92c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 28 Jul 2022 19:14:11 +0100 Subject: [PATCH 009/222] Capitalise header guards --- FrameLib_Framework/FrameLib_SerialiseGraph.h | 4 ++-- FrameLib_Framework/FrameLib_Threading.h | 4 ++-- .../Spatial/FrameLib_Spatial_Convertor_Template.h | 4 ++-- FrameLib_Objects/Time_Smoothing/FrameLib_TimeMean.h | 4 ++-- FrameLib_Objects/Vector/FrameLib_Join.h | 4 ++-- FrameLib_Objects/Vector/FrameLib_NanFilter.h | 5 +++-- FrameLib_Objects/Vector/FrameLib_Prioritise.h | 4 ++-- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/FrameLib_Framework/FrameLib_SerialiseGraph.h b/FrameLib_Framework/FrameLib_SerialiseGraph.h index 9ad8fb141..d2486d01f 100644 --- a/FrameLib_Framework/FrameLib_SerialiseGraph.h +++ b/FrameLib_Framework/FrameLib_SerialiseGraph.h @@ -1,6 +1,6 @@ -#ifndef FrameLib_SerialiseGraph_h -#define FrameLib_SerialiseGraph_h +#ifndef FRAMELIB_SERIALISEGRAPH_H +#define FRAMELIB_SERIALISEGRAPH_H #include "FrameLib_Multistream.h" diff --git a/FrameLib_Framework/FrameLib_Threading.h b/FrameLib_Framework/FrameLib_Threading.h index cea027415..9b5de1c7d 100644 --- a/FrameLib_Framework/FrameLib_Threading.h +++ b/FrameLib_Framework/FrameLib_Threading.h @@ -1,6 +1,6 @@ -#ifndef FrameLib_THREADING_H -#define FrameLib_THREADING_H +#ifndef FRAMELIB_THREADING_H +#define FRAMELIB_THREADING_H #include "FrameLib_Types.h" diff --git a/FrameLib_Objects/Spatial/FrameLib_Spatial_Convertor_Template.h b/FrameLib_Objects/Spatial/FrameLib_Spatial_Convertor_Template.h index 46439190d..f8cc02d68 100644 --- a/FrameLib_Objects/Spatial/FrameLib_Spatial_Convertor_Template.h +++ b/FrameLib_Objects/Spatial/FrameLib_Spatial_Convertor_Template.h @@ -1,6 +1,6 @@ -#ifndef FrameLib_SPATIAL_CONVERTOR_TEMPLATE_H -#define FrameLib_SPATIAL_CONVERTOR_TEMPLATE_H +#ifndef FRAMELIB_SPATIAL_CONVERTOR_TEMPLATE_H +#define FRAMELIB_SPATIAL_CONVERTOR_TEMPLATE_H #include "FrameLib_DSP.h" diff --git a/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMean.h b/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMean.h index 4adf28bdc..72d6b8314 100644 --- a/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMean.h +++ b/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMean.h @@ -1,6 +1,6 @@ -#ifndef FrameLib_TimeMean_H -#define FrameLib_TimeMean_H +#ifndef FRAMELIB_TIMEMEAN_H +#define FRAMELIB_TIMEMEAN_H #include "FrameLib_TimeBuffer_Template.h" #include "FrameLib_NeumaierSum.h" diff --git a/FrameLib_Objects/Vector/FrameLib_Join.h b/FrameLib_Objects/Vector/FrameLib_Join.h index 6f9432f8f..6111d099b 100644 --- a/FrameLib_Objects/Vector/FrameLib_Join.h +++ b/FrameLib_Objects/Vector/FrameLib_Join.h @@ -1,6 +1,6 @@ -#ifndef FrameLib_Join_H -#define FrameLib_Join_H +#ifndef FRAMELIB_JOIN_H +#define FRAMELIB_JOIN_H #include "FrameLib_DSP.h" diff --git a/FrameLib_Objects/Vector/FrameLib_NanFilter.h b/FrameLib_Objects/Vector/FrameLib_NanFilter.h index 8a663bd03..212c6396b 100644 --- a/FrameLib_Objects/Vector/FrameLib_NanFilter.h +++ b/FrameLib_Objects/Vector/FrameLib_NanFilter.h @@ -1,5 +1,6 @@ -#ifndef FrameLib_NanFilter_h -#define FrameLib_NanFilter_h + +#ifndef FRAMELIB_NANFILTER_H +#define FRAMELIB_NANFILTER_H #include "FrameLib_DSP.h" diff --git a/FrameLib_Objects/Vector/FrameLib_Prioritise.h b/FrameLib_Objects/Vector/FrameLib_Prioritise.h index e412282f9..caff6c4ef 100644 --- a/FrameLib_Objects/Vector/FrameLib_Prioritise.h +++ b/FrameLib_Objects/Vector/FrameLib_Prioritise.h @@ -1,6 +1,6 @@ -#ifndef FrameLib_Prioritise_H -#define FrameLib_Prioritise_H +#ifndef FRAMELIB_PRIORITISE_H +#define FRAMELIB_PRIORITISE_H #include "FrameLib_DSP.h" From fcafea01a6a8e1283abb296f53ddc76a7f1da9f0 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 20:11:42 +0100 Subject: [PATCH 010/222] Link with Accelerate framework --- framelib.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/framelib.xcodeproj/project.pbxproj b/framelib.xcodeproj/project.pbxproj index 22423b9d6..4f577c744 100644 --- a/framelib.xcodeproj/project.pbxproj +++ b/framelib.xcodeproj/project.pbxproj @@ -381,6 +381,7 @@ B88B484E2729683200D33BBE /* (null) in Frameworks */ = {isa = PBXBuildFile; }; B88B48562729689D00D33BBE /* fl.makestring~.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B88B48552729689C00D33BBE /* fl.makestring~.cpp */; }; B88C0A3921733CA6007A65C0 /* FrameLib_SC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B88C0A1E21732710007A65C0 /* FrameLib_SC.cpp */; }; + B88EBA112894681A0030DEC0 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B88F558E207AB15C007774AD /* Accelerate.framework */; }; B88F5559207A58DA007774AD /* FrameLib_Reverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B88F5558207A5873007774AD /* FrameLib_Reverse.cpp */; }; B88F555A207A58F2007774AD /* framelib_pd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B83E029220667499005925DD /* framelib_pd.cpp */; }; B88F5564207A5903007774AD /* libframelib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B89ABA901FA73483006DAD53 /* libframelib.a */; }; @@ -4216,6 +4217,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B88EBA112894681A0030DEC0 /* Accelerate.framework in Frameworks */, B8E6E9DF207904F7004AB73F /* libframelib_objects.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; From 391ebe3e36c1ab6567aabca0b86941afb26051fd Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 20:29:10 +0100 Subject: [PATCH 011/222] Header guards and static methods --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index abb0904c2..c94241c6c 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1,4 +1,7 @@ +#ifndef FRAMELIB_PD_CLASS_H +#define FRAMELIB_PD_CLASS_H + #include "PDClass_Base.h" #include "FrameLib_Global.h" @@ -1236,7 +1239,7 @@ class FrameLib_PDClass : public PDClass_Base return std::min(maxCount, number); } - long getStreamCount(t_atom *a) + static long getStreamCount(t_atom *a) { if (atom_gettype(a) == A_SYMBOL) { @@ -1365,7 +1368,7 @@ class FrameLib_PDClass : public PDClass_Base // Input Parsing - unsigned long inputNumber(t_symbol *sym) + static unsigned long inputNumber(t_symbol *sym) { return safeCount(sym->s_name + 1, 16384) - 1; } @@ -1451,3 +1454,5 @@ class FrameLib_PDClass : public PDClass_Base template using FrameLib_PDClass_Expand = FrameLib_PDClass, argsMode>; + +#endif From f1c1abf97cd099eded3918c198a5219b094ed4ba Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 20:33:12 +0100 Subject: [PATCH 012/222] Missing static on method --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index c94241c6c..a90a72aac 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1233,7 +1233,7 @@ class FrameLib_PDClass : public PDClass_Base // Parameter Parsing - unsigned long safeCount(char *str, unsigned long maxCount) + static unsigned long safeCount(char *str, unsigned long maxCount) { unsigned long number = std::max(1, atoi(str)); return std::min(maxCount, number); From f399cc214bed470a68081735e118a24cd40db38e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 20:34:08 +0100 Subject: [PATCH 013/222] Shorter method names --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index a90a72aac..82393343d 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -533,8 +533,8 @@ class FrameLib_PDClass : public PDClass_Base addMethod, &FrameLib_PDClass::sync>(c, "sync"); addMethod, &FrameLib_PDClass::dsp>(c); addMethod(c, (t_method) &externalResolveConnections, "__fl.resolve_connections"); - addMethod(c, (t_method) &externalAutoOrderingConnections, "__fl.auto_ordering_connections"); - addMethod(c, (t_method) &externalClearAutoOrderingConnections, "__fl.clear_auto_ordering_connections"); + addMethod(c, (t_method) &externalAutoOrdering, "__fl.auto_ordering_connections"); + addMethod(c, (t_method) &externalClearAutoOrdering, "__fl.clear_auto_ordering_connections"); addMethod(c, (t_method) &externalIsConnected, "__fl.is_connected"); addMethod(c, (t_method) &externalConnectionConfirm, "__fl.connection_confirm"); addMethod(c, (t_method) &externalGetInternalObject, "__fl.get_internal_object"); @@ -913,12 +913,12 @@ class FrameLib_PDClass : public PDClass_Base x->resolveConnections(); } - static void externalAutoOrderingConnections(FrameLib_PDClass *x) + static void externalAutoOrdering(FrameLib_PDClass *x) { x->mObject->makeAutoOrderingConnections(); } - static void externalClearAutoOrderingConnections(FrameLib_PDClass *x) + static void externalClearAutoOrdering(FrameLib_PDClass *x) { x->mObject->clearAutoOrderingConnections(); } From 21e39f4bc731787aa7d959ccf65960caf0821fd8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 20:49:56 +0100 Subject: [PATCH 014/222] Updates from the Max wrapper --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 71 ++++++++++--------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 82393343d..5c4ddab37 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -751,16 +751,21 @@ class FrameLib_PDClass : public PDClass_Base } } - // IO Helpers + // Helpers (IO / context / mode / streams) - bool supportsOrderingConnections() { return mObject->supportsOrderingConnections(); } + ObjectType getType() const { return mObject->getType(); } - bool handlesAudio() { return T::sHandlesAudio; } + FrameLib_Context getContext() const { return mObject->getContext(); } - long getNumAudioIns() { return (long) mObject->getNumAudioIns() + (handlesAudio() ? 1 : 0); } - long getNumAudioOuts() { return (long) mObject->getNumAudioOuts() + (handlesAudio() ? 1 : 0); } - long getNumIns() { return (long) mObject->getNumIns(); } - long getNumOuts() { return (long) mObject->getNumOuts(); } + bool handlesAudio() const { return T::sHandlesAudio; } + bool supportsOrderingConnections() const { return mObject->supportsOrderingConnections(); } + + long audioIOSize(long chans) const { return chans + (handlesAudio() ? 1 : 0); } + + long getNumIns() const { return static_cast(mObject->getNumIns()); } + long getNumOuts() const { return static_cast(mObject->getNumOuts()); } + long getNumAudioIns() const { return audioIOSize(mObject->getNumAudioIns()); } + long getNumAudioOuts() const { return audioIOSize(mObject->getNumAudioOuts()); } // Perform and DSP @@ -1211,13 +1216,16 @@ class FrameLib_PDClass : public PDClass_Base void postSplit(const char *text, const char *firstLineTag, const char *lineTag) { std::string str(text); - size_t oldPos, pos; + size_t prev = 0; - for (oldPos = 0, pos = str.find_first_of(":."); oldPos < str.size(); pos = str.find_first_of(":.", pos + 1)) + for (size_t pos = str.find_first_of(":."); prev < str.size(); pos = str.find_first_of(":.", pos + 1)) { + if ((pos != std::string::npos) && (str[pos + 1] != ' ')) + continue; + pos = pos == std::string::npos ? str.size() : pos; - post("%s%s", oldPos ? lineTag : firstLineTag, str.substr(oldPos, (pos - oldPos) + 1).c_str()); - oldPos = pos + 1; + post("%s%s", prev ? lineTag : firstLineTag, str.substr(prev, (pos - prev) + 1).c_str()); + prev = pos + 1; } } @@ -1225,9 +1233,10 @@ class FrameLib_PDClass : public PDClass_Base { switch (type) { - case FrameType::Any: return "either"; - case FrameType::Vector: return "vector"; - case FrameType::Tagged: return "tagged"; + case FrameType::Vector: return "vector"; + case FrameType::Tagged: return "tagged"; + // kFrameAny + default: return "either"; } } @@ -1279,15 +1288,12 @@ class FrameLib_PDClass : public PDClass_Base // Collect doubles - for ( ; idx < argc; idx++) + for ( ; idx < argc && !isTag(argv + idx); idx++) { - if (isTag(argv + idx)) - break; - - if (atom_gettype(argv + idx) == A_SYMBOL) - pd_error(mUserObject, "string %s in entry list where value expected", atom_getsymbol(argv + idx)->s_name); - values.push_back(atom_getfloat(argv + idx)); + + if (atom_gettype(argv + idx) == A_SYMBOL && !values.back()) + pd_error(mUserObject, "string %s in entry list where value expected", atom_getsymbol(argv + idx)->s_name); } return idx; @@ -1301,25 +1307,19 @@ class FrameLib_PDClass : public PDClass_Base // Parse arguments - for (i = 0; i < argc; i++) + for (i = 0; i < argc && !isTag(argv + i); i++) { - if (isTag(argv + i)) - break; - if (argsMode == kAsParams) { - char argNames[64]; - sprintf(argNames, "%ld", i); - if (atom_gettype(argv + i) == A_SYMBOL) { t_symbol *str = atom_getsymbol(argv + i); - serialisedParameters.write(argNames, str->s_name); + serialisedParameters.write(std::to_string(i).c_str(), str->s_name); } else { double value = atom_getfloat(argv + i); - serialisedParameters.write(argNames, &value, 1); + serialisedParameters.write(std::to_string(i).c_str(), &value, 1); } } } @@ -1383,19 +1383,20 @@ class FrameLib_PDClass : public PDClass_Base if (argsMode == kAllInputs || argsMode == kDistribute) { i = parseNumericalList(values, argv, argc, 0); - if(argsMode == kAllInputs) + + if (argsMode == kAllInputs) { - for (unsigned long j = 0; i && j < getNumIns(); j++) - mObject->setFixedInput(j, values.data(), values.size()); + for (long j = 0; i && j < getNumIns(); j++) + mObject->setFixedInput(j, values.data(), static_cast(values.size())); } else { - for (unsigned long j = 0; j < i && (j + 1) < getNumIns(); j++) + for (long j = 0; j < i && (j + 1) < getNumIns(); j++) mObject->setFixedInput(j + 1, &values[j], 1); } } - // Parse tags + // Parse input tags while (i < argc) { From de8a7b0501344c5898237edf6beec7474434bd5c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 20:54:50 +0100 Subject: [PATCH 015/222] Move tag checks --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 5c4ddab37..9f2fd24ee 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -546,6 +546,29 @@ class FrameLib_PDClass : public PDClass_Base dspInit(c); } + // Tag checks + + static bool isParameterTag(t_symbol *sym) + { + return strlen(sym->s_name) > 1 && sym->s_name[0] == '/'; + } + + static bool isInputTag(t_symbol *sym) + { + size_t len = strlen(sym->s_name); + + if (len > 2) + return (sym->s_name[0] == '[' && sym->s_name[len - 1] == ']'); + + return false; + } + + static bool isTag(t_atom *a) + { + t_symbol *sym = atom_getsymbol(a); + return atom_gettype(a) == A_SYMBOL && (isParameterTag(sym) || isInputTag(sym)); + } + // Constructor and Destructor FrameLib_PDClass(t_symbol *s, long argc, t_atom *argv, FrameLib_PDProxy *proxy = new FrameLib_PDProxy()) @@ -1261,27 +1284,6 @@ class FrameLib_PDClass : public PDClass_Base return 0; } - bool isParameterTag(t_symbol *sym) - { - return strlen(sym->s_name) > 1 && sym->s_name[0] == '/'; - } - - bool isInputTag(t_symbol *sym) - { - size_t len = strlen(sym->s_name); - - if (len > 2) - return (sym->s_name[0] == '[' && sym->s_name[len - 1] == ']'); - - return false; - } - - bool isTag(t_atom *a) - { - t_symbol *sym = atom_getsymbol(a); - return atom_gettype(a) == A_SYMBOL && (isParameterTag(sym) || isInputTag(sym)); - } - long parseNumericalList(std::vector &values, t_atom *argv, long argc, long idx) { values.resize(0); From ddb1c609bb75d4dedeec3894496d6dcdb3462270 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 21:03:31 +0100 Subject: [PATCH 016/222] Shorter method names --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 9f2fd24ee..1276a2fc4 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -233,9 +233,9 @@ template addMethod, &Wrapper::anything>(c, "anything"); addMethod, &Wrapper::sync>(c, "sync"); addMethod, &Wrapper::dsp>(c); - addMethod(c, (t_method) &externalPatchLineUpdate, "patchlineupdate"); - addMethod(c, (t_method) &externalConnectionAccept, "connectionaccept"); - addMethod(c, (t_method) &externalWrapperInternalObject, "__fl.wrapper_internal_object"); + addMethod(c, (t_method) &extPatchLineUpdate, "patchlineupdate"); + addMethod(c, (t_method) &extConnectionAccept, "connectionaccept"); + addMethod(c, (t_method) &extWrapperInternalObject, "__fl.wrapper_internal_object"); // N.B. MUST add signal handling after dspInit to override the builtin responses @@ -407,22 +407,22 @@ template // External methods (A_CANT) - static t_max_err externalPatchLineUpdate(Wrapper *x, t_object *patchline, long updatetype, t_object *src, long srcout, t_object *dst, long dstin) + static t_max_err extPatchLineUpdate(Wrapper *x, t_object *patchline, long updatetype, t_object *src, long srcout, t_object *dst, long dstin) { if ((t_object *) x == dst) - return T::externalPatchLineUpdate(x->internalObject(), patchline, updatetype, src, srcout, x->mObject, dstin + 1); + return T::extPatchLineUpdate(x->internalObject(), patchline, updatetype, src, srcout, x->mObject, dstin + 1); else - return T::externalPatchLineUpdate(x->internalObject(), patchline, updatetype, x->mObject, srcout + 1, dst, dstin); + return T::extPatchLineUpdate(x->internalObject(), patchline, updatetype, x->mObject, srcout + 1, dst, dstin); } - static t_ptr_int externalConnectionAccept(Wrapper *src, t_object *dst, long srcout, long dstin, t_object *outlet, t_object *inlet) + static t_ptr_int extConnectionAccept(Wrapper *src, t_object *dst, long srcout, long dstin, t_object *outlet, t_object *inlet) { // Only called for sources / account for internal sync connections - return T::externalConnectionAccept(src->internalObject(), dst, srcout + 1, dstin, outlet, inlet); + return T::extConnectionAccept(src->internalObject(), dst, srcout + 1, dstin, outlet, inlet); } - static void *externalWrapperInternalObject(Wrapper *x) + static void *extWrapperInternalObject(Wrapper *x) { return x->mObject; } @@ -532,15 +532,15 @@ class FrameLib_PDClass : public PDClass_Base addMethod, &FrameLib_PDClass::frame>(c, "frame"); addMethod, &FrameLib_PDClass::sync>(c, "sync"); addMethod, &FrameLib_PDClass::dsp>(c); - addMethod(c, (t_method) &externalResolveConnections, "__fl.resolve_connections"); - addMethod(c, (t_method) &externalAutoOrdering, "__fl.auto_ordering_connections"); - addMethod(c, (t_method) &externalClearAutoOrdering, "__fl.clear_auto_ordering_connections"); - addMethod(c, (t_method) &externalIsConnected, "__fl.is_connected"); - addMethod(c, (t_method) &externalConnectionConfirm, "__fl.connection_confirm"); - addMethod(c, (t_method) &externalGetInternalObject, "__fl.get_internal_object"); - addMethod(c, (t_method) &externalIsOutput, "__fl.is_output"); - addMethod(c, (t_method) &externalGetNumAudioIns, "__fl.get_num_audio_ins"); - addMethod(c, (t_method) &externalGetNumAudioOuts, "__fl.get_num_audio_outs"); + addMethod(c, (t_method) &extResolveConnections, "__fl.resolve_connections"); + addMethod(c, (t_method) &extAutoOrdering, "__fl.auto_ordering_connections"); + addMethod(c, (t_method) &extClearAutoOrdering, "__fl.clear_auto_ordering_connections"); + addMethod(c, (t_method) &extIsConnected, "__fl.is_connected"); + addMethod(c, (t_method) &extConnectionConfirm, "__fl.connection_confirm"); + addMethod(c, (t_method) &extGetInternalObject, "__fl.get_internal_object"); + addMethod(c, (t_method) &extIsOutput, "__fl.is_output"); + addMethod(c, (t_method) &extGetNumAudioIns, "__fl.get_num_audio_ins"); + addMethod(c, (t_method) &extGetNumAudioOuts, "__fl.get_num_audio_outs"); class_addmethod(c, (t_method) &codeexport, gensym("export"), A_SYMBOL, A_SYMBOL, 0); dspInit(c); @@ -866,7 +866,7 @@ class FrameLib_PDClass : public PDClass_Base void sync() { - FrameLib_PDGlobals::SyncCheck::Action action = mSyncChecker(this, handlesAudio(), externalIsOutput(this)); + FrameLib_PDGlobals::SyncCheck::Action action = mSyncChecker(this, handlesAudio(), extIsOutput(this)); if (action != FrameLib_PDGlobals::SyncCheck::kSyncComplete && handlesAudio() && mNeedsResolve) { @@ -936,47 +936,47 @@ class FrameLib_PDClass : public PDClass_Base // External methods (A_CANT) - static void externalResolveConnections(FrameLib_PDClass *x) + static void extResolveConnections(FrameLib_PDClass *x) { x->resolveConnections(); } - static void externalAutoOrdering(FrameLib_PDClass *x) + static void extAutoOrdering(FrameLib_PDClass *x) { x->mObject->makeAutoOrderingConnections(); } - static void externalClearAutoOrdering(FrameLib_PDClass *x) + static void extClearAutoOrdering(FrameLib_PDClass *x) { x->mObject->clearAutoOrderingConnections(); } - static uintptr_t externalIsConnected(FrameLib_PDClass *x, unsigned long index) + static uintptr_t extIsConnected(FrameLib_PDClass *x, unsigned long index) { return x->confirmConnection(index, ConnectionInfo::kConfirm); } - static void externalConnectionConfirm(FrameLib_PDClass *x, unsigned long index, FrameLib_PDGlobals::ConnectionInfo::Mode mode) + static void extConnectionConfirm(FrameLib_PDClass *x, unsigned long index, FrameLib_PDGlobals::ConnectionInfo::Mode mode) { x->makeConnection(index, mode); } - static FrameLib_Multistream *externalGetInternalObject(FrameLib_PDClass *x) + static FrameLib_Multistream *extGetInternalObject(FrameLib_PDClass *x) { return x->mObject.get(); } - static uintptr_t externalIsOutput(FrameLib_PDClass *x) + static uintptr_t extIsOutput(FrameLib_PDClass *x) { return x->handlesAudio() && (x->getNumAudioOuts() > 1); } - static uintptr_t externalGetNumAudioIns(FrameLib_PDClass *x) + static uintptr_t extGetNumAudioIns(FrameLib_PDClass *x) { return x->getNumAudioIns(); } - static uintptr_t externalGetNumAudioOuts(FrameLib_PDClass *x) + static uintptr_t extGetNumAudioOuts(FrameLib_PDClass *x) { return x->getNumAudioOuts(); } From 2057007d198a8d78c46d84c890cfaa9df5128a41 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 21:03:38 +0100 Subject: [PATCH 017/222] Cast --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 1276a2fc4..4bd16518c 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1362,7 +1362,7 @@ class FrameLib_PDClass : public PDClass_Base else { i = parseNumericalList(values, argv, argc, i); - serialisedParameters.write(sym->s_name + 1, values.data(), values.size()); + serialisedParameters.write(sym->s_name + 1, values.data(), static_cast(values.size())); } } } From 06ff8743ec63f76382ad729d1984aef9d837f518 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 21:03:49 +0100 Subject: [PATCH 018/222] Refactor safeCount() --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 4bd16518c..0cce24667 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1265,9 +1265,9 @@ class FrameLib_PDClass : public PDClass_Base // Parameter Parsing - static unsigned long safeCount(char *str, unsigned long maxCount) + static unsigned long safeCount(char *str, unsigned long minCount, unsigned long maxCount) { - unsigned long number = std::max(1, atoi(str)); + unsigned long number = std::max(minCount, static_cast(atoi(str))); return std::min(maxCount, number); } @@ -1278,7 +1278,7 @@ class FrameLib_PDClass : public PDClass_Base t_symbol *sym = atom_getsymbol(a); if (strlen(sym->s_name) > 1 && sym->s_name[0] == '=') - return safeCount(sym->s_name + 1, 1024); + return safeCount(sym->s_name + 1, 1, 1024); } return 0; @@ -1372,7 +1372,7 @@ class FrameLib_PDClass : public PDClass_Base static unsigned long inputNumber(t_symbol *sym) { - return safeCount(sym->s_name + 1, 16384) - 1; + return safeCount(sym->s_name + 1, 0, 16384) - 1; } void parseInputs(long argc, t_atom *argv) From 1191b2242fc001be862eb081c7cc732370085049 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 21:06:00 +0100 Subject: [PATCH 019/222] Better naming of template parameter --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index e6053d433..8f8d95bcc 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -2816,7 +2816,7 @@ class FrameLib_MaxClass : public MaxClass_Base // Convenience for Objects Using FrameLib_Expand (use FrameLib_MaxClass_Expand::makeClass() to create) -template -using FrameLib_MaxClass_Expand = FrameLib_MaxClass, argsSetAllInputs>; +template +using FrameLib_MaxClass_Expand = FrameLib_MaxClass, argsMode>; #endif From d714ae377b33419d8651b9f74ad1215dfcd08e60 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 22:12:07 +0100 Subject: [PATCH 020/222] Specified streams --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 0cce24667..dfab747a4 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -582,21 +582,21 @@ class FrameLib_PDClass : public PDClass_Base , mNeedsResolve(true) , mUserObject(*this) { - // Object creation with parameters and arguments (N.B. the object is not a member due to size restrictions) - - unsigned long nStreams = 1; + // Stream count if (argc && getStreamCount(argv)) { - nStreams = getStreamCount(argv); + mSpecifiedStreams = getStreamCount(argv); argv++; argc--; } + // Object creation with parameters and arguments (N.B. the object is not a member due to size restrictions) + FrameLib_Parameters::AutoSerial serialisedParameters; parseParameters(serialisedParameters, argc, argv); mFrameLibProxy->mMaxObject = *this; - mObject.reset(new T(FrameLib_Context(mGlobal->getGlobal(), mCanvas), &serialisedParameters, mFrameLibProxy.get(), nStreams)); + mObject.reset(new T(FrameLib_Context(mGlobal->getGlobal(), mCanvas), &serialisedParameters, mFrameLibProxy.get(), mSpecifiedStreams)); parseInputs(argc, argv); long numIns = getNumIns() + (supportsOrderingConnections() ? 1 : 0); @@ -790,6 +790,8 @@ class FrameLib_PDClass : public PDClass_Base long getNumAudioIns() const { return audioIOSize(mObject->getNumAudioIns()); } long getNumAudioOuts() const { return audioIOSize(mObject->getNumAudioOuts()); } + unsigned long getSpecifiedStreams() const { return mSpecifiedStreams; } + // Perform and DSP void perform(int vec_size) @@ -1446,6 +1448,8 @@ class FrameLib_PDClass : public PDClass_Base t_glist *mCanvas; t_object *mSyncIn; + unsigned long mSpecifiedStreams; + bool mNeedsResolve; public: From 74efb80383d3703763c904d0b0d122330af375ed Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 22:18:58 +0100 Subject: [PATCH 021/222] Types / use helpers / info / method name --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index dfab747a4..3634ee922 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -533,7 +533,7 @@ class FrameLib_PDClass : public PDClass_Base addMethod, &FrameLib_PDClass::sync>(c, "sync"); addMethod, &FrameLib_PDClass::dsp>(c); addMethod(c, (t_method) &extResolveConnections, "__fl.resolve_connections"); - addMethod(c, (t_method) &extAutoOrdering, "__fl.auto_ordering_connections"); + addMethod(c, (t_method) &extMakeAutoOrdering, "__fl.auto_ordering_connections"); addMethod(c, (t_method) &extClearAutoOrdering, "__fl.clear_auto_ordering_connections"); addMethod(c, (t_method) &extIsConnected, "__fl.is_connected"); addMethod(c, (t_method) &extConnectionConfirm, "__fl.connection_confirm"); @@ -685,7 +685,7 @@ class FrameLib_PDClass : public PDClass_Base // FIX - user object should be used here.... - post("********* %s *********", class_getname(*getClassPointer())); + post("------------------ %s ------------------", class_getname(*getClassPointer())); // Description @@ -703,10 +703,10 @@ class FrameLib_PDClass : public PDClass_Base if (argsMode == kAllInputs) post("N.B. - arguments set the fixed array values for all inputs."); if (argsMode == kDistribute) - post("N.B - arguments are distributed one per input."); - for (long i = 0; i < mObject->getNumAudioIns(); i++) + post("N.B - arguments are distributed one per input from the second input."); + for (long i = 0; i < static_cast(mObject->getNumAudioIns()); i++) post("Audio Input %ld: %s", i + 1, mObject->audioInfo(i, verbose).c_str()); - for (long i = 0; i < mObject->getNumIns(); i++) + for (long i = 0; i < getNumIns(); i++) post("Frame Input %ld [%s]: %s", i + 1, frameTypeString(mObject->inputType(i)), mObject->inputInfo(i, verbose).c_str()); if (supportsOrderingConnections()) post("Ordering Input [%s]: Connect to ensure ordering", frameTypeString(FrameType::Any)); @@ -715,9 +715,9 @@ class FrameLib_PDClass : public PDClass_Base if (flags & kInfoOutputs) { post("--- Output List ---"); - for (long i = 0; i < mObject->getNumAudioOuts(); i++) + for (long i = 0; i < static_cast(mObject->getNumAudioOuts()); i++) post("Audio Output %ld: %s", i + 1, mObject->audioInfo(i, verbose).c_str()); - for (long i = 0; i < mObject->getNumOuts(); i++) + for (long i = 0; i < getNumOuts(); i++) post("Frame Output %ld [%s]: %s", i + 1, frameTypeString(mObject->outputType(i)), mObject->outputInfo(i, verbose).c_str()); } @@ -732,7 +732,7 @@ class FrameLib_PDClass : public PDClass_Base // Loop over parameters - for (long i = 0; params && i < params->size(); i++) + for (unsigned long i = 0; params && i < params->size(); i++) { FrameLib_Parameters::Type type = params->getType(i); FrameLib_Parameters::NumericType numericType = params->getNumericType(i); @@ -762,7 +762,7 @@ class FrameLib_PDClass : public PDClass_Base } } if (type == FrameLib_Parameters::Type::Enum) - for (long j = 0; j <= params->getMax(i); j++) + for (unsigned long j = 0; j <= static_cast(params->getMax(i)); j++) post(" [%ld] - %s", j, params->getItemString(i, j)); else if (type == FrameLib_Parameters::Type::Array) post("- Array Size: %ld", params->getArraySize(i)); @@ -943,7 +943,7 @@ class FrameLib_PDClass : public PDClass_Base x->resolveConnections(); } - static void extAutoOrdering(FrameLib_PDClass *x) + static void extMakeAutoOrdering(FrameLib_PDClass *x) { x->mObject->makeAutoOrderingConnections(); } From e0f9646b5bb0a0ced51a4f9d8874e2e1fbebb3c1 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 22:19:54 +0100 Subject: [PATCH 022/222] Remove code export --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 3634ee922..0f4d776b6 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -541,7 +541,6 @@ class FrameLib_PDClass : public PDClass_Base addMethod(c, (t_method) &extIsOutput, "__fl.is_output"); addMethod(c, (t_method) &extGetNumAudioIns, "__fl.get_num_audio_ins"); addMethod(c, (t_method) &extGetNumAudioOuts, "__fl.get_num_audio_outs"); - class_addmethod(c, (t_method) &codeexport, gensym("export"), A_SYMBOL, A_SYMBOL, 0); dspInit(c); } @@ -642,23 +641,6 @@ class FrameLib_PDClass : public PDClass_Base //object_free(mSyncIn); } - static void codeexport(FrameLib_PDClass *x, t_symbol *className, t_symbol *path) - { - char conformedPath[MAXPDSTRING]; - - if (strlen(path->s_name) > MAXPDSTRING) - conformedPath[0] = 0; - else - sys_bashfilename(path->s_name, conformedPath); - - ExportError error = exportGraph(x->mObject.get(), conformedPath, className->s_name); - - if (error == ExportError::PathError) - pd_error(x->mUserObject, "couldn't write to or find specified path"); - else if (error == ExportError::WriteError) - pd_error(x->mUserObject, "couldn't write file"); - } - void info(t_symbol *sym, long ac, t_atom *av) { // Determine what to post From c967109d30816d21eac5994a1139a347aa1a7d19 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 22:31:48 +0100 Subject: [PATCH 023/222] Remove unused classes --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 278 ------------------ 1 file changed, 278 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 0f4d776b6..9375f2468 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -174,284 +174,6 @@ class FrameLib_PDGlobals : public PDClass_Base SyncCheck *mSyncCheck; }; -////////////////////////////////////////////////////////////////////////// -////////////////////// Mutator for Synchronisation /////////////////////// -////////////////////////////////////////////////////////////////////////// -/* -class Mutator : public PDClass_Base -{ -public: - - Mutator(t_symbol *sym, long ac, t_atom *av) - { - mObject = ac ? atom_getobj(av) : nullptr; - mMode = object_method(mObject, gensym("__fl.is_output")) ? FrameLib_PDGlobals::SyncCheck::kDownOnly : FrameLib_PDGlobals::SyncCheck::kDown; - } - - static void classInit(t_class *c, const char *classname) - { - addMethod(c, "signal"); - } - - void mutate(t_symbol *sym, long ac, t_atom *av) - { - // FIX - clock_getlogicaltime?? - mSyncChecker.sync(mObject, gettime(), mMode); - object_method(mObject, gensym("sync")); - mSyncChecker.sync(); - } - -private: - - FrameLib_PDGlobals::SyncCheck mSyncChecker; - FrameLib_PDGlobals::SyncCheck::Mode mMode; - void *mObject; -}; -*/ -////////////////////////////////////////////////////////////////////////// -////////////////////// Wrapper for Synchronisation /////////////////////// -////////////////////////////////////////////////////////////////////////// -/* -template - class Wrapper : public PDClass_Base -{ -public: - - // Initialise Class - - static t_method *sigMethodCache() - { - static t_method sigMethod; - - return &sigMethod; - } - - static void classInit(t_class *c, const char *classname) - { - addMethod, &Wrapper::subpatcher>(c, "subpatcher"); - addMethod, &Wrapper::assist>(c, "assist"); - addMethod, &Wrapper::anything>(c, "anything"); - addMethod, &Wrapper::sync>(c, "sync"); - addMethod, &Wrapper::dsp>(c); - addMethod(c, (t_method) &extPatchLineUpdate, "patchlineupdate"); - addMethod(c, (t_method) &extConnectionAccept, "connectionaccept"); - addMethod(c, (t_method) &extWrapperInternalObject, "__fl.wrapper_internal_object"); - - // N.B. MUST add signal handling after dspInit to override the builtin responses - - dspInit(c); - *sigMethodCache() = class_method(c, gensym("signal")); - addMethod, &Wrapper::anything>(c, "signal"); - - // Make sure the mutator class exists - - const char mutatorClassName[] = "__fl.signal.mutator"; - - if (!class_findbyname(CLASS_NOBOX, gensym(mutatorClassName))) - Mutator::makeClass(CLASS_NOBOX, mutatorClassName); - } - - // Constructor and Destructor - - Wrapper(t_symbol *s, long argc, t_atom *argv) - { - // Create patcher (you must report this as a subpatcher to get audio working) - - t_dictionary *d = dictionary_new(); - t_atom a; - t_atom *av = nullptr; - long ac = 0; - - atom_setparse(&ac, &av, "@defrect 0 0 300 300"); - attr_args_dictionary(d, ac, av); - atom_setobj(&a, d); - mPatch = (t_object *)object_new_typed(CLASS_NOBOX, gensym("jpatcher"),1, &a); - - // Get box text (and strip object name from the top - relace with stored name in case the object name is an alias) - - t_object *textfield = nullptr; - const char *text = nullptr; - std::string newObjectText = accessClassName()->c_str(); - - object_obex_lookup(this, gensym("#B"), &textfield); - - if ((textfield = jbox_get_textfield(textfield))) - { - text = (char *)object_method(textfield, gensym("getptr")); - text = strchr(text, ' '); - - if (text) - newObjectText += text; - } - - // Make internal object - - mObject = jbox_get_object((t_object *) newobject_sprintf(mPatch, "@maxclass newobj @text \"unsynced.%s\" @patching_rect 0 0 30 10", newObjectText.c_str())); - - // Make Mutator (with argument referencing the internal object) - - atom_setobj(&a, mObject); - mMutator = (t_object *) object_new_typed(CLASS_NOBOX, gensym("__fl.signal.mutator"), 1, &a); - - // Free the dictionary - - object_free(d); - - // Get the object itself (typed) - - T *internal = internalObject(); - - long numIns = internal->getNumIns() + (internal->supportsOrderingConnections() ? 1 : 0); - long numOuts = internal->getNumOuts(); - long numAudioIns = internal->getNumAudioIns(); - long numAudioOuts = internal->getNumAudioOuts(); - - internal->mUserObject = *this; - - // Create I/O - - mInOutlets.resize(numIns + numAudioIns - 1); - mProxyIns.resize(numIns + numAudioIns - 1); - mAudioOuts.resize(numAudioOuts - 1); - mOuts.resize(numOuts); - - // Inlets for messages/signals (we need one audio in for the purposes of sync) - - dspSetup(1); - - for (long i = numIns + numAudioIns - 2; i >= 0 ; i--) - { - mInOutlets[i] = (t_object *) outlet_new(nullptr, nullptr); - mProxyIns[i] = (t_object *) (i ? proxy_new(this, i, &mProxyNum) : nullptr); - } - - // Outlets for messages/signals - - for (long i = numOuts - 1; i >= 0 ; i--) - mOuts[i] = (t_object *) outlet_new(this, nullptr); - for (long i = numAudioOuts - 2; i >= 0 ; i--) - mAudioOuts[i] = (t_object *) outlet_new(this, "signal"); - - // Connect first signal outlet to the mutator - - outlet_add(outlet_nth(mObject, 0), inlet_nth(mMutator, 0)); - - // Connect inlets (all types) - - for (long i = 0; i < numAudioIns + numIns - 1; i++) - outlet_add(mInOutlets[i], inlet_nth(mObject, i + 1)); - - // Connect non-audio outlets - - for (long i = 0; i < numOuts; i++) - outlet_add(outlet_nth(mObject, i + numAudioOuts), mOuts[i]); - } - - ~Wrapper() - { - // Delete ins and proxies - - for (auto it = mProxyIns.begin(); it != mProxyIns.end(); it++) - object_free(*it); - - for (auto it = mInOutlets.begin(); it != mInOutlets.end(); it++) - object_free(*it); - - // Free objects - N.B. - free the patch, but not the object within it (which will be freed by deleting the patch) - - object_free(mMutator); - object_free(mPatch); - } - - // Standard methods - - void *subpatcher(long index, void *arg) - { - return ((t_ptr_uint) arg > 1 && !NOGOOD(arg) && index == 0) ? (void *) mPatch : nullptr; - } - - void assist(void *b, long m, long a, char *s) - { - internalObject()->assist(b, m, a + 1, s); - } - - void sync() - { - // Must set the order of the wrapper after the internal object before calling internal sync - - (*sigMethodCache())(this); - - internalObject()->sync(); - } - - void dsp(t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags) - { - if (internalObject()->getType() == kOutput) - addPerform::perform>(dsp64); - } - - void perform(t_object *dsp64, double **ins, long numins, double **outs, long numouts, long vec_size, long flags, void *userparam) - { - std::vector &internalOuts = internalObject()->getAudioOuts(); - - // Copy to output - - for (long i = 0; i < internalOuts.size(); i++) - std::copy(internalOuts[i], internalOuts[i] + vec_size, outs[i]); - } - - void anything(t_symbol *sym, long ac, t_atom *av) - { - outlet_anything(mInOutlets[getInlet()], sym, ac, av); - } - - // External methods (A_CANT) - - static t_max_err extPatchLineUpdate(Wrapper *x, t_object *patchline, long updatetype, t_object *src, long srcout, t_object *dst, long dstin) - { - if ((t_object *) x == dst) - return T::extPatchLineUpdate(x->internalObject(), patchline, updatetype, src, srcout, x->mObject, dstin + 1); - else - return T::extPatchLineUpdate(x->internalObject(), patchline, updatetype, x->mObject, srcout + 1, dst, dstin); - } - - static t_ptr_int extConnectionAccept(Wrapper *src, t_object *dst, long srcout, long dstin, t_object *outlet, t_object *inlet) - { - // Only called for sources / account for internal sync connections - - return T::extConnectionAccept(src->internalObject(), dst, srcout + 1, dstin, outlet, inlet); - } - - static void *extWrapperInternalObject(Wrapper *x) - { - return x->mObject; - } - -private: - - T *internalObject() { return (T *) mObject; } - - // Objects (need freeing except the internal object which is owned by the patch) - - t_object *mPatch; - t_object *mObject; - t_object *mMutator; - - // Inlets (must be freed) - - std::vector mInOutlets; - std::vector mProxyIns; - - // Outlets (don't need to free) - - std::vector mAudioOuts; - std::vector mOuts; - - // Dummy for stuffloc on proxies - - long mProxyNum; -}; -*/ ////////////////////////////////////////////////////////////////////////// /////////////////////// FrameLib PD Object Class ///////////////////////// ////////////////////////////////////////////////////////////////////////// From 37fd1ae72f203249ce6d2523e4c37d6e77ebb757 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 22:32:08 +0100 Subject: [PATCH 024/222] Rework proxy --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 9375f2468..b53685c80 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -293,7 +293,7 @@ class FrameLib_PDClass : public PDClass_Base // Constructor and Destructor FrameLib_PDClass(t_symbol *s, long argc, t_atom *argv, FrameLib_PDProxy *proxy = new FrameLib_PDProxy()) - : mFrameLibProxy(proxy) + : mProxy(proxy) , mConfirmObject(nullptr) , mConfirmInIndex(-1) , mConfirmOutIndex(-1) @@ -316,8 +316,8 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_Parameters::AutoSerial serialisedParameters; parseParameters(serialisedParameters, argc, argv); - mFrameLibProxy->mMaxObject = *this; - mObject.reset(new T(FrameLib_Context(mGlobal->getGlobal(), mCanvas), &serialisedParameters, mFrameLibProxy.get(), mSpecifiedStreams)); + mProxy->mMaxObject = *this; + mObject.reset(new T(FrameLib_Context(mGlobal->getGlobal(), mCanvas), &serialisedParameters, mProxy.get(), mSpecifiedStreams)); parseInputs(argc, argv); long numIns = getNumIns() + (supportsOrderingConnections() ? 1 : 0); @@ -1123,12 +1123,15 @@ class FrameLib_PDClass : public PDClass_Base } } + protected: - std::unique_ptr mFrameLibProxy; + // Proxy + + std::unique_ptr mProxy; private: - + // Data - N.B. - the order is crucial for safe deconstruction FrameLib_PDGlobals::ManagedPointer mGlobal; From f9ece91a906a92cb187865f4cb05b00ede656a7f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 29 Jul 2022 22:36:41 +0100 Subject: [PATCH 025/222] Parameter parsing from Max class --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 53 ++++++++----------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index b53685c80..b42877c34 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1009,7 +1009,6 @@ class FrameLib_PDClass : public PDClass_Base void parseParameters(FrameLib_Parameters::AutoSerial& serialisedParameters, long argc, t_atom *argv) { - t_symbol *sym = nullptr; std::vector values; long i; @@ -1036,35 +1035,27 @@ class FrameLib_PDClass : public PDClass_Base while (i < argc) { - // Strip stray items + t_symbol *sym = atom_getsymbol(argv + i++); - for (long j = 0; i < argc; i++, j++) + if (isParameterTag(sym)) { - if (isTag(argv + i)) + // Check for missing values + + if ((i >= argc) || isTag(argv + i)) { - sym = atom_getsymbol(argv + i); - break; + pd_error(mUserObject, "no values given for parameter %s", sym->s_name); + continue; } - if (j == 0) - pd_error(mUserObject, "stray items after entry %s", sym->s_name); - } - - // Check for lack of values or end of list - - if ((++i >= argc) || isTag(argv + i)) - { - if (i < (argc + 1)) - pd_error(mUserObject, "no values given for entry %s", sym->s_name); - continue; - } - - if (isParameterTag(sym)) - { - // Do strings or values + // Add to parameters with stray item detection - if (atom_gettype(argv + i) == A_SYMBOL && atom_getsymbol(argv + i)) + if (atom_getsymbol(argv + i) != gensym("")) + { serialisedParameters.write(sym->s_name + 1, atom_getsymbol(argv + i++)->s_name); + + if (i < argc && !isTag(argv + i)) + pd_error(mUserObject, "stray items after parameter %s", sym->s_name); + } else { i = parseNumericalList(values, argv, argc, i); @@ -1108,17 +1099,15 @@ class FrameLib_PDClass : public PDClass_Base while (i < argc) { - // Advance to next input tag - - for ( ; i < argc && !isInputTag(atom_getsymbol(argv + i)); i++); + t_symbol *sym = atom_getsymbol(argv + i++); - // If there are values to read then do so - - if ((i + 1) < argc && !isTag(argv + i + 1)) + if (isInputTag(sym)) { - t_symbol *sym = atom_getsymbol(argv + i); - i = parseNumericalList(values, argv, argc, i + 1); - mObject->setFixedInput(inputNumber(sym), values.data(), values.size()); + i = parseNumericalList(values, argv, argc, i); + mObject->setFixedInput(inputNumber(sym), values.data(), static_cast(values.size())); + + if (inputNumber(sym) >= static_cast(getNumIns())) + pd_error(mUserObject, "input %s out of bounds", sym->s_name); } } } From 74329a473cf498c58b3711ef700cc7565aa14675 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 11:47:12 +0100 Subject: [PATCH 026/222] Type aliases --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index b42877c34..5d7e377ae 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -188,12 +188,15 @@ struct FrameLib_PDProxy : public virtual FrameLib_Proxy template class FrameLib_PDClass : public PDClass_Base { - typedef FrameLib_Object::Connection FrameLibConnection; - typedef FrameLib_Object::Connection PDConnection; - typedef FrameLib_PDGlobals::ConnectionInfo ConnectionInfo; - - using ClipMode = FrameLib_Parameters::ClipMode; + //using ConnectionMode = FrameLib_PDGlobals::ConnectionMode; + using FLObject = FrameLib_Multistream; + using FLConnection = FrameLib_Object::Connection; + using PDConnection = FrameLib_Object::Connection; + using LockHold = FrameLib_LockHolder; using NumericType = FrameLib_Parameters::NumericType; + using ClipMode = FrameLib_Parameters::ClipMode; + + using ConnectionInfo = FrameLib_PDGlobals::ConnectionInfo; static t_atomtype atom_gettype(t_atom* a) { return a->a_type; } @@ -861,7 +864,7 @@ class FrameLib_PDClass : public PDClass_Base bool isConnected(long index) const { return mObject->isConnected(index); } - PDConnection getPDConnection(const FrameLibConnection& connection) const + PDConnection getPDConnection(const FLConnection& connection) const { FrameLib_PDProxy *proxy = dynamic_cast(connection.mObject->getProxy()); t_object *object = proxy->mMaxObject; @@ -902,9 +905,9 @@ class FrameLib_PDClass : public PDClass_Base ConnectionResult result; if (isOrderingInput(inIdx)) - result = mObject->addOrderingConnection(FrameLibConnection(object, outIdx)); + result = mObject->addOrderingConnection(FLConnection(object, outIdx)); else - result = mObject->addConnection(FrameLibConnection(object, outIdx), inIdx); + result = mObject->addConnection(FLConnection(object, outIdx), inIdx); switch (result) { @@ -935,7 +938,7 @@ class FrameLib_PDClass : public PDClass_Base return; if (isOrderingInput(inIdx)) - mObject->deleteOrderingConnection(FrameLibConnection(object, outIdx)); + mObject->deleteOrderingConnection(FLConnection(object, outIdx)); else mObject->deleteConnection(inIdx); } @@ -1126,7 +1129,7 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_PDGlobals::ManagedPointer mGlobal; FrameLib_PDGlobals::SyncCheck mSyncChecker; - std::unique_ptr mObject; + std::unique_ptr mObject; std::vector mInputs; std::vector mOutputs; From 2bd0976f9c70232c65f2455f8eeb86a8f89afd27 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 11:48:27 +0100 Subject: [PATCH 027/222] Fix type --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 5d7e377ae..78f4d95d1 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1128,8 +1128,8 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_PDGlobals::ManagedPointer mGlobal; FrameLib_PDGlobals::SyncCheck mSyncChecker; - - std::unique_ptr mObject; + + std::unique_ptr mObject; std::vector mInputs; std::vector mOutputs; From 07bf42c9a8cd9058fb9479e1dc7c6cb463c53948 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:22:51 +0100 Subject: [PATCH 028/222] Formatting/style --- FrameLib_PD_Objects/Common/pd_buffer.h | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/FrameLib_PD_Objects/Common/pd_buffer.h b/FrameLib_PD_Objects/Common/pd_buffer.h index 2572dc258..2f10199fd 100644 --- a/FrameLib_PD_Objects/Common/pd_buffer.h +++ b/FrameLib_PD_Objects/Common/pd_buffer.h @@ -6,7 +6,6 @@ class pd_buffer { - struct fetch : public table_fetcher { fetch(t_word *data, intptr_t size) @@ -22,29 +21,29 @@ class pd_buffer public: - pd_buffer() : mArray(nullptr), mTable(nullptr), mLength(0) {} + pd_buffer() : m_array(nullptr), m_table(nullptr), m_length(0) {} - pd_buffer(t_symbol *name) : mTable(nullptr), mLength(0) + pd_buffer(t_symbol *name) : m_table(nullptr), m_length(0) { - mArray = (t_garray *) pd_findbyclass(name, garray_class); + m_array = (t_garray *) pd_findbyclass(name, garray_class); - if (mArray) - garray_getfloatwords(mArray, &mLength, &mTable); + if (m_array) + garray_getfloatwords(m_array, &m_length, &m_table); } - bool is_valid() const { return mTable && (mLength > 0); } - int get_length() const { return mLength; } + bool is_valid() const { return m_table && (m_length > 0); } + int get_length() const { return m_length; } void read(double *output, const double *positions, unsigned long size, double amp, InterpType interp, EdgeMode edges, bool bound) { - table_read_edges(fetch(mTable, mLength), output, positions, size, amp, interp, edges, bound); + table_read_edges(fetch(m_table, m_length), output, positions, size, amp, interp, edges, bound); } private: - t_garray *mArray; - t_word *mTable; - int mLength; + t_garray *m_array; + t_word *m_table; + int m_length; }; #endif From 8e2d6971c0efc6da5b875414b376e976e6c78963 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:23:10 +0100 Subject: [PATCH 029/222] Formatting / naming --- .../Common/FrameLib_MaxClass.h | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 8f8d95bcc..2be7704cc 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -32,7 +32,7 @@ struct FrameLib_MaxPrivate { return 1000; } - + // A constant representing the max wrapper and framework versions. // The versions are combined in a manner that they are both easily readable when viewed in decimal format @@ -40,7 +40,7 @@ struct FrameLib_MaxPrivate { return static_cast(FrameLib_FrameworkVersion) * 1000000000 + static_cast(maxWrapperVersion()); } - + struct VersionString { VersionString(const char *str) : mString(str) @@ -55,15 +55,15 @@ struct FrameLib_MaxPrivate VersionString& operator=(const VersionString&) = delete; VersionString(VersionString&&) = default; VersionString& operator=(VersionString&&) = default; - + operator const char *() { return mString.c_str(); } std::string mString; }; - + static inline t_symbol *FLNamespace() { return gensym("__fl.framelib_private"); } static inline t_symbol *globalTag() { return gensym(VersionString("__fl.max_global_tag")); } - + static inline VersionString objectGlobal() { return "__fl.max_global_items"; } static inline VersionString objectMessageHandler() { return "__fl.message.handler"; } static inline VersionString objectMutator() { return "__fl.signal.mutator"; } @@ -402,7 +402,7 @@ class MessageHandler : public MaxClass_Base private: - static void output(const Message& message, t_atom *output) + static void output(const Message& message, t_atom *data) { FrameLib_MaxMessageProxy *proxy = message.mInfo.mProxy; @@ -414,9 +414,9 @@ class MessageHandler : public MaxClass_Base unsigned long N = limit(static_cast(message.mVector.size())); for (unsigned long i = 0; i < N; i++) - atom_setfloat(output + i, message.mVector[i]); + atom_setfloat(data + i, message.mVector[i]); - proxy->sendMessage(message.mInfo.mStream, nullptr, static_cast(N), output); + proxy->sendMessage(message.mInfo.mStream, nullptr, static_cast(N), data); } else { @@ -433,15 +433,15 @@ class MessageHandler : public MaxClass_Base size = limit(size); for (unsigned long i = 0; i < size; i++) - atom_setfloat(output + i, vector[i]); + atom_setfloat(data + i, vector[i]); } else { size = 1; - atom_setsym(output, gensym(it.getString())); + atom_setsym(data, gensym(it.getString())); } - proxy->sendMessage(message.mInfo.mStream, tag, static_cast(size), output); + proxy->sendMessage(message.mInfo.mStream, tag, static_cast(size), data); } } } @@ -2358,7 +2358,7 @@ class FrameLib_MaxClass : public MaxClass_Base MaxConnection getConnection(long index) { return toMaxConnection(mObject->getConnection(index)); } MaxConnection getOrderingConnection(long index) { return toMaxConnection(mObject->getOrderingConnection(index)); } - long getNumOrderingConnections() const { return static_cast(mObject->getNumOrderingConnections()); } + long getNumOrderingConnections() const { return static_cast(mObject->getNumOrderingConnections()); } static MaxConnection toMaxConnection(FLConnection c) { return MaxConnection(toMaxObject(c.mObject), c.mIndex); } static FLConnection toFLConnection(MaxConnection c) { return FLConnection(toFLObject(c.mObject), c.mIndex); } From 84faa12b28f31efd5d1598b37cab2a8c50d08737 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:23:29 +0100 Subject: [PATCH 030/222] Add helpers --- FrameLib_PD_Objects/Common/PDClass_Base.h | 55 +++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index f1055b200..84b8ae088 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -66,6 +66,54 @@ class PDClass_Base dsp_add(callPerform, 2, this, sp[0]->s_vecsize); } + // Atom helpers + + static void atom_setfloat(t_atom *a, double v) + { + a->a_type = A_FLOAT; + a->a_w.w_float = v; + } + + static void atom_setsymbol(t_atom *a, t_symbol *sym) + { + a->a_type = A_SYMBOL; + a->a_w.w_symbol = sym; + } + + // C++ style variadic call to object methods + + template + static ReturnType objectMethod(t_object *object, const char* theMethodName, Args...args) + { + return objectMethod((t_pd *)object, gensym(theMethodName), args...); + } + + template + static ReturnType objectMethod(t_pd *object, t_symbol* theMethod, Args...args) + { + void *pad = nullptr; + return objectMethod(object, theMethod, args..., pad); + } + + // Specialisation to prevent infinite padding + + template + static ReturnType objectMethod(t_pd *object, t_symbol* theMethod, S s, T t, U u, V v, W w) + { + typedef void *(*t_fn5)(void *x, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5); + + t_fn5 *m = (t_fn5 *) zgetfn(object, theMethod); + + void *ret = (*m)(object, + objectMethodArg(s), + objectMethodArg(t), + objectMethodArg(u), + objectMethodArg(v), + objectMethodArg(w)); + + return static_cast(ret); + } + // Static Methods for class initialisation, object creation and deletion template static t_class **getClassPointer() @@ -139,6 +187,13 @@ class PDClass_Base private: + template + static void *objectMethodArg(T a) + { + static_assert(sizeof(T) == sizeof(void *), "Argument is not the correct size"); + return reinterpret_cast(a); + } + // Deleted PDClass_Base(const PDClass_Base&) = delete; From 5b37c94fd0531c88e8de3ad0af4e2c8a0bca6d6c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:24:30 +0100 Subject: [PATCH 031/222] Updates to construction / proxies / include private messages and message handler --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 495 ++++++++++++++---- FrameLib_PD_Objects/Common/PDClass_Base.h | 2 +- FrameLib_PD_Objects/framelib_pd.cpp | 26 +- 3 files changed, 415 insertions(+), 108 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 78f4d95d1..062c4693c 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -13,8 +13,14 @@ #include "g_canvas.h" +#include +#include +#include +#include #include +#include #include +#include extern "C" { @@ -22,6 +28,339 @@ extern "C" void signal_makereusable(t_signal *sig); } +// Deal with private strings and versioning + +struct FrameLib_PDPrivate +{ + // A constant representing the pd wrapper version. + // The version is stored as a decimal with major version changes as multiples of 1000 + + static inline constexpr uint32_t pdWrapperVersion() + { + return 1000; + } + + // A constant representing the max wrapper and framework versions. + // The versions are combined in a manner that they are both easily readable when viewed in decimal format + + static inline constexpr uint64_t version() + { + return static_cast(FrameLib_FrameworkVersion) * 1000000000 + static_cast(pdWrapperVersion()); + } + + struct VersionString + { + VersionString(const char *str) : mString(str) + { + mString.append(".v"); + mString.append(std::to_string(version())); + } + + // Non-copyable but moveable + + VersionString(const VersionString&) = delete; + VersionString& operator=(const VersionString&) = delete; + VersionString(VersionString&&) = default; + VersionString& operator=(VersionString&&) = default; + + operator const char *() { return mString.c_str(); } + + std::string mString; + }; + + static inline t_symbol *FLNamespace() { return gensym("__fl.framelib_private"); } + static inline t_symbol *globalTag() { return gensym(VersionString("__fl.max_global_tag")); } + + static inline VersionString objectGlobal() { return "__fl.max_global_items"; } + static inline VersionString objectMessageHandler() { return "__fl.message.handler"; } + static inline VersionString objectMutator() { return "__fl.signal.mutator"; } + + static inline const char *messageGetUserObject() { return "__fl.get_user_object"; } + static inline const char *messageUnwrap() { return "__fl.unwrap"; } + static inline const char *messageIsWrapper() { return "__fl.is_wrapper"; } + static inline const char *messageFindAudioObjects() { return "__fl.find_audio_objects"; } + static inline const char *messageResolveContext() { return "__fl.resolve_context"; } + static inline const char *messageResolveConnections() { return "__fl.resolve_connections"; } + static inline const char *messageMarkUnresolved() { return "__fl.mark_unresolved"; } + static inline const char *messageMakeAutoOrdering() { return "__fl.make_auto_ordering"; } + static inline const char *messageClearAutoOrdering() { return "__fl.clear_auto_ordering"; } + static inline const char *messageReset() { return "__fl.reset"; } + static inline const char *messageIsDirectlyConnected() { return "__fl.is_directly_connected"; } + static inline const char *messageConnectionConfirm() { return "__fl.connection_confirm"; } + static inline const char *messageConnectionUpdate() { return "__fl.connection_update"; } + static inline const char *messageGetFrameLibObject() { return "__fl.get_framelib_object"; } + static inline const char *messageGetNumAudioIns() { return "__fl.get_num_audio_ins"; } + static inline const char *messageGetNumAudioOuts() { return "__fl.get_num_audio_outs"; } + + static FrameLib_Multistream *toFrameLibObject(t_object *object, uint64_t& versionCheck) + { + if (!object) + return nullptr; + + return PDClass_Base::objectMethod(object, messageGetFrameLibObject(), &versionCheck); + } + + static FrameLib_Multistream *toFrameLibObject(t_object *object) + { + uint64_t versionCheck = 0; + FrameLib_Multistream *internalObject = toFrameLibObject(object, versionCheck); + return versionCheck == version() ? internalObject : nullptr; + } + + static bool versionMismatch(t_object *object) + { + uint64_t versionCheck = 0; + toFrameLibObject(object, versionCheck); + return versionCheck && versionCheck != version(); + } +}; + +// Other pd-specific structures + +struct FrameLib_PDProxy : public virtual FrameLib_Proxy +{ + FrameLib_PDProxy(t_object *x) + { + setOwner(x); + } + + // Override for object proxies that need to know about the patch hierarchy + + //virtual void contextPatchUpdated(t_object *patch, unsigned long depth) {} +}; + +struct FrameLib_PDMessageProxy : FrameLib_PDProxy +{ + FrameLib_PDMessageProxy(t_object *x) : FrameLib_PDProxy(x) {} + + // Override for objects that require max messages to be sent from framelib + + virtual void sendMessage(unsigned long stream, t_symbol *s, short ac, t_atom *av) {} + + // Store context patch info + + //void contextPatchUpdated(t_object *patch, unsigned long depth) override { mDepth = depth; } +}; + +////////////////////////////////////////////////////////////////////////// +/////////////////////////// Messaging Classes //////////////////////////// +////////////////////////////////////////////////////////////////////////// +/* +struct MessageInfo +{ + MessageInfo(FrameLib_PDMessageProxy* proxy, FrameLib_TimeFormat time, unsigned long stream) + : mProxy(proxy), mTime(time), mStream(stream) {} + + FrameLib_PDMessageProxy* mProxy; + FrameLib_TimeFormat mTime; + unsigned long mStream; +}; + +struct Message +{ + Message(const MessageInfo& info, const double *values, unsigned long N) + : mInfo(info), mType(FrameType::Vector), mVector(values, values + N) {} + + Message(const MessageInfo& info, const FrameLib_Parameters::Serial *serial) + : mInfo(info), mType(FrameType::Tagged), mSerial(*serial) {} + + Message(const Message&) = delete; + Message& operator=(const Message&) = delete; + Message(Message&&) = default; + Message& operator=(Message&&) = default; + + MessageInfo mInfo; + FrameType mType; + std::vector mVector; + FrameLib_Parameters::AutoSerial mSerial; +}; + +class MessageHandler : public PDClass_Base +{ + struct MessageCompare + { + bool operator()(const Message& a, const Message& b) const + { + // FIX - ordering comparison + + // Use time + + if (a.mInfo.mTime != b.mInfo.mTime) + return a.mInfo.mTime > b.mInfo.mTime; + + // Use streams - N.B. Streams run in reverse order + + if (a.mInfo.mProxy == b.mInfo.mProxy) + return a.mInfo.mStream < b.mInfo.mStream; + + return a.mInfo.mProxy < b.mInfo.mProxy; + } + }; + + struct MessageBlock + { + class Queue : public std::priority_queue, MessageCompare> + { + friend MessageBlock; + std::vector& container() { return c; } + }; + + Queue mQueue; + unsigned long mMaxSize = 1; + + void flush(FrameLib_PDProxy *proxy) + { + for (auto it = mQueue.container().begin(); it != mQueue.container().end(); it++) + it->mInfo.mProxy = it->mInfo.mProxy == proxy ? nullptr : it->mInfo.mProxy; + } + }; + +public: + + MessageHandler(t_object *x, t_symbol *sym, long ac, t_atom *av) {} + + void add(const MessageInfo& info, const double *values, unsigned long N) + { + // Lock, get vector size and copy + + FrameLib_LockHolder lock(&mLock); + mData.mMaxSize = std::max(limit(N), mData.mMaxSize); + mData.mQueue.emplace(info, values, N); + } + + void add(const MessageInfo& info, const FrameLib_Parameters::Serial *serial) + { + // Lock, determine maximum vector size and copy + + FrameLib_LockHolder lock(&mLock); + + for (auto it = serial->begin(); it != serial->end(); it++) + { + if (it.getType() == DataType::Vector) + { + unsigned long size = it.getVectorSize(); + mData.mMaxSize = std::max(limit(size), mData.mMaxSize); + } + } + + mData.mQueue.emplace(info, serial); + } + + void ready() + { + // Lock and copy onto the output queue + + FrameLib_LockHolder lock(&mLock); + + if (!mData.mQueue.size()) + return; + + mOutput.emplace_back(); + std::swap(mData, mOutput.back()); + lock.destroy(); + } + + void schedule() + { + ready(); + schedule_delay(*this, (t_method) &service, 0, nullptr, 0, nullptr); + } + + void flush(FrameLib_PDProxy *proxy) + { + FrameLib_LockHolder flushLock(&mFlushLock); + FrameLib_LockHolder lock(&mLock); + + mData.flush(proxy); + + for (auto it = mOutput.begin(); it != mOutput.end(); it++) + it->flush(proxy); + } + + static void service(MessageHandler* handler, t_symbol *s, short ac, t_atom *av) + { + MessageBlock messages; + + // Swap data + + FrameLib_LockHolder flushLock(&handler->mFlushLock); + FrameLib_LockHolder lock(&handler->mLock); + + if (!handler->mOutput.empty()) + { + std::swap(handler->mOutput.front(), messages); + handler->mOutput.pop_front(); + } + + lock.destroy(); + flushLock.destroy(); + + // Allocate temporary t_atoms and output + + std::vector out(messages.mMaxSize); + + while (!messages.mQueue.empty()) + { + output(messages.mQueue.top(), out.data()); + messages.mQueue.pop(); + } + } + +private: + + static void output(const Message& message, t_atom *data) + { + FrameLib_PDMessageProxy *proxy = message.mInfo.mProxy; + + if (!proxy) + return; + + if (message.mType == FrameType::Vector) + { + unsigned long N = limit(static_cast(message.mVector.size())); + + for (unsigned long i = 0; i < N; i++) + atom_setfloat(data + i, message.mVector[i]); + + proxy->sendMessage(message.mInfo.mStream, nullptr, static_cast(N), data); + } + else + { + // Iterate over tags + + for (auto it = message.mSerial.begin(); it != message.mSerial.end(); it++) + { + t_symbol *tag = gensym(it.getTag()); + unsigned long size = 0; + + if (it.getType() == DataType::Vector) + { + const double *vector = it.getVector(&size); + size = limit(size); + + for (unsigned long i = 0; i < size; i++) + atom_setfloat(data + i, vector[i]); + } + else + { + size = 1; + atom_setsymbol(data, gensym(it.getString())); + } + + proxy->sendMessage(message.mInfo.mStream, tag, static_cast(size), data); + } + } + } + + static unsigned long limit(unsigned long N) { return std::min(N, 32767UL); } + + mutable FrameLib_Lock mLock; + mutable FrameLib_Lock mFlushLock; + + MessageBlock mData; + std::deque mOutput; +}; +*/ ////////////////////////////////////////////////////////////////////////// //////////////////////////// PD Globals Class //////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -122,7 +461,7 @@ class FrameLib_PDGlobals : public PDClass_Base // Constructor and Destructor (public for the PD API, but use the ManagedPointer for use from outside this class) - FrameLib_PDGlobals(t_symbol *sym, long ac, t_atom *av) + FrameLib_PDGlobals(t_object *x, t_symbol *sym, long ac, t_atom *av) : mGlobal(nullptr), mConnectionInfo(nullptr), mSyncCheck(nullptr) {} ~FrameLib_PDGlobals() { if (mGlobal) FrameLib_Global::release(&mGlobal); } @@ -180,11 +519,6 @@ class FrameLib_PDGlobals : public PDClass_Base enum PDObjectArgsMode { kAsParams, kAllInputs, kDistribute }; -struct FrameLib_PDProxy : public virtual FrameLib_Proxy -{ - t_object *mMaxObject; -}; - template class FrameLib_PDClass : public PDClass_Base { @@ -217,7 +551,7 @@ class FrameLib_PDClass : public PDClass_Base addMethod(c, "frame"); } - PDProxy(t_symbol *sym, long ac, t_atom *av) : mOwner(nullptr), mIndex(-1) {} + PDProxy(t_object *x, t_symbol *sym, long ac, t_atom *av) : mOwner(nullptr), mIndex(-1) {} void frame() { @@ -295,8 +629,8 @@ class FrameLib_PDClass : public PDClass_Base // Constructor and Destructor - FrameLib_PDClass(t_symbol *s, long argc, t_atom *argv, FrameLib_PDProxy *proxy = new FrameLib_PDProxy()) - : mProxy(proxy) + FrameLib_PDClass(t_object *x, t_symbol *s, long argc, t_atom *argv, FrameLib_PDProxy *proxy = nullptr) + : mProxy(proxy ? proxy : new FrameLib_PDProxy(x)) , mConfirmObject(nullptr) , mConfirmInIndex(-1) , mConfirmOutIndex(-1) @@ -319,7 +653,6 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_Parameters::AutoSerial serialisedParameters; parseParameters(serialisedParameters, argc, argv); - mProxy->mMaxObject = *this; mObject.reset(new T(FrameLib_Context(mGlobal->getGlobal(), mCanvas), &serialisedParameters, mProxy.get(), mSpecifiedStreams)); parseInputs(argc, argv); @@ -598,11 +931,11 @@ class FrameLib_PDClass : public PDClass_Base { for (unsigned long i = 0; i < getNumIns(); i++) if (isConnected(i)) - callMethod(getConnection(i).mObject, gensym("sync")); + objectMethod(getConnection(i).mObject, "sync"); if (supportsOrderingConnections()) for (unsigned long i = 0; i < getNumOrderingConnections(); i++) - callMethod(getOrderingConnection(i).mObject, gensym("sync")); + objectMethod(getOrderingConnection(i).mObject, "sync"); mSyncChecker.restoreMode(); } @@ -690,53 +1023,6 @@ class FrameLib_PDClass : public PDClass_Base return x->getNumAudioOuts(); } - static uintptr_t intMethod(t_object *object, t_symbol *methodName) - { - // FIX - look at vmess - - typedef uintptr_t (*func)(t_object *); - - t_gotfn f = zgetfn(&object->ob_pd, methodName); - - if (!f) - return 0; - - func f2 = (func)f; - return f2(object); - } - - static void *ptrMethod(t_object *object, t_symbol *methodName) - { - // FIX - look at vmess - - typedef void *(*func)(t_object *); - - t_gotfn f = zgetfn(&object->ob_pd, methodName); - - if (!f) - return 0; - - func f2 = (func)f; - return f2(object); - } - - static void callMethod(t_object *object, t_symbol *methodName) - { - //vmess((t_pd *) g, method, ""); - - // FIX - look at vmess - - typedef void (*func)(t_object *); - - t_gotfn f = zgetfn(&object->ob_pd, methodName); - - if (!f) - return; - - func f2 = (func)f; - return f2(object); - } - static void confirmMethod(t_object *object, t_symbol *methodName, long index, ConnectionInfo::Mode mode) { //vmess((t_pd *) g, method, ""); @@ -773,7 +1059,7 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_Multistream *getInternalObject(t_object *x) { - return (FrameLib_Multistream *) ptrMethod(x, gensym("__fl.get_internal_object")); + return objectMethod(x, "__fl.get_internal_object"); } // Private connection methods @@ -821,6 +1107,59 @@ class FrameLib_PDClass : public PDClass_Base mGlobal->setConnectionInfo(); } + // Convert from framelib object to pd object and vice versa + + static FLObject *toFLObject(t_object *x) + { + return FrameLib_PDPrivate::toFrameLibObject(x); + } + + static t_object *toPDObject(FLObject *object) + { + return object ? object->getProxy()->getOwner() : nullptr; + } + + // Get the number of audio ins/outs safely from a generic pointer + +// static long getNumAudioIns(t_object *x) +// { +// t_ptr_int numAudioIns = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioIns()); +// return static_cast(numAudioIns); +// } +// +// static long getNumAudioOuts(t_object *x) +// { +// t_ptr_int numAudioOuts = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioOuts()); +// return static_cast(numAudioOuts); +// } + + // Helpers for connection methods + + static bool isOrderingInput(long index, FLObject *object) + { + return object && object->supportsOrderingConnections() && index == static_cast(object->getNumIns()); + } + + bool isOrderingInput(long index) const { return isOrderingInput(index, mObject.get()); } + bool isConnected(long index) const { return mObject->isConnected(index); } + + static bool validIO(long index, unsigned long count) { return index >= 0 && index < static_cast(count); } + static bool validInput(long index, FLObject *object) { return object && validIO(index, object->getNumIns()); } + static bool validOutput(long index, FLObject *object) { return object && validIO(index, object->getNumOuts()); } + + bool validInput(long index) const { return validInput(index, mObject.get()); } + bool validOutput(long index) const { return validOutput(index, mObject.get()); } + + PDConnection getConnection(long index) { return toPDConnection(mObject->getConnection(index)); } + PDConnection getOrderingConnection(long index) { return toPDConnection(mObject->getOrderingConnection(index)); } + + long getNumOrderingConnections() const { return static_cast(mObject->getNumOrderingConnections()); } + + static PDConnection toPDConnection(FLConnection c) { return PDConnection(toPDObject(c.mObject), c.mIndex); } + static FLConnection toFLConnection(PDConnection c) { return FLConnection(toFLObject(c.mObject), c.mIndex); } + + // Private connection methods + bool confirmConnection(unsigned long inIndex, ConnectionInfo::Mode mode) { if (!validInput(inIndex)) @@ -855,41 +1194,7 @@ class FrameLib_PDClass : public PDClass_Base return result; } - bool validInput(long index, FrameLib_Multistream *object) const { return object && index >= 0 && index < object->getNumIns(); } - bool validOutput(long index, FrameLib_Multistream *object) const { return object && index >= 0 && index < object->getNumOuts(); } - bool isOrderingInput(long index, FrameLib_Multistream *object) const { return object && object->supportsOrderingConnections() && index == object->getNumIns(); } - bool validInput(long index) const { return validInput(index, mObject.get()); } - bool validOutput(long index) const { return validOutput(index, mObject.get()); } - bool isOrderingInput(long index) const { return isOrderingInput(index, mObject.get()); } - - bool isConnected(long index) const { return mObject->isConnected(index); } - - PDConnection getPDConnection(const FLConnection& connection) const - { - FrameLib_PDProxy *proxy = dynamic_cast(connection.mObject->getProxy()); - t_object *object = proxy->mMaxObject; - return PDConnection(object, connection.mIndex); - } - - PDConnection getConnection(long index) const - { - if (isConnected(index)) - return getPDConnection(mObject->getConnection(index)); - else - return PDConnection(); - } - - unsigned long getNumOrderingConnections() const - { - return mObject->getNumOrderingConnections(); - } - - PDConnection getOrderingConnection(long index) const - { - return getPDConnection(mObject->getOrderingConnection(index)); - } - - bool matchConnection(t_object *src, long outIdx, long inIdx) const + bool matchConnection(t_object *src, long outIdx, long inIdx) { PDConnection connection = getConnection(inIdx); return connection.mObject == src && connection.mIndex == outIdx; diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 84b8ae088..bfdb740e2 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -143,7 +143,7 @@ class PDClass_Base template static void *create(t_symbol *sym, long ac, t_atom *av) { void *x = pd_new(*getClassPointer()); - new(x) T(sym, ac, av); + new(x) T(reinterpret_cast(x), sym, ac, av); return x; } diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 4a6a7c524..8011f81c6 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -12,6 +12,8 @@ class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand { struct ReadProxy : public FrameLib_Read::Proxy, public FrameLib_PDProxy { + ReadProxy(t_object *x) : FrameLib_PDProxy(x) {} + void update(const char *name) override { mBufferName = gensym(name); @@ -49,19 +51,19 @@ class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand // Constructor - FrameLib_PDClass_Read(t_symbol *s, long argc, t_atom *argv) - : FrameLib_PDClass(s, argc, argv, new ReadProxy()) {} + FrameLib_PDClass_Read(t_object *x, t_symbol *s, long argc, t_atom *argv) + : FrameLib_PDClass(x, s, argc, argv, new ReadProxy(x)) {} }; // PD Expression Classes // The expression objects parses arguments differently to normal, which is handled by pre-parsing the atoms into a different format -class ArgumentParser +class ExprArgumentParser { public: - ArgumentParser(t_symbol *s, long argc, t_atom *argv, bool complex) : mSymbol(s), mComplex(complex) + ExprArgumentParser(t_symbol *s, long argc, t_atom *argv, bool complex) : mSymbol(s), mComplex(complex) { concatenate(argc, argv); @@ -149,8 +151,8 @@ class ArgumentParser struct FrameLib_PDClass_Expression_Parsed : public FrameLib_PDClass_Expand { - FrameLib_PDClass_Expression_Parsed(const ArgumentParser &parsed) : - FrameLib_PDClass(parsed.symbol(), parsed.count(), parsed.args(), new FrameLib_PDProxy()) {} + FrameLib_PDClass_Expression_Parsed(t_object *x, const ExprArgumentParser &parsed) : + FrameLib_PDClass(x, parsed.symbol(), parsed.count(), parsed.args()) {} }; // Expression PD Class (inherits from the parsed version which inherits the standard pd class) @@ -159,16 +161,16 @@ struct FrameLib_PDClass_Expression : public FrameLib_PDClass_Expression_Parsed { // Constructor - FrameLib_PDClass_Expression(t_symbol *s, long argc, t_atom *argv) : - FrameLib_PDClass_Expression_Parsed(ArgumentParser(s, argc, argv, false)) {} + FrameLib_PDClass_Expression(t_object *x, t_symbol *s, long argc, t_atom *argv) : + FrameLib_PDClass_Expression_Parsed(x, ExprArgumentParser(s, argc, argv, false)) {} }; // This complex expression class is a wrapper that allows the parsing to happen correctly struct FrameLib_PDClass_ComplexExpression_Parsed : public FrameLib_PDClass_Expand { - FrameLib_PDClass_ComplexExpression_Parsed(const ArgumentParser &parsed) : - FrameLib_PDClass(parsed.symbol(), parsed.count(), parsed.args(), new FrameLib_PDProxy()) {} + FrameLib_PDClass_ComplexExpression_Parsed(t_object *x, const ExprArgumentParser &parsed) : + FrameLib_PDClass(x, parsed.symbol(), parsed.count(), parsed.args()) {} }; // Complex Expression PD Class (inherits from the parsed version which inherits the standard pd class) @@ -177,8 +179,8 @@ struct FrameLib_PDClass_ComplexExpression : public FrameLib_PDClass_ComplexExpre { // Constructor - FrameLib_PDClass_ComplexExpression(t_symbol *s, long argc, t_atom *argv) : - FrameLib_PDClass_ComplexExpression_Parsed(ArgumentParser(s, argc, argv, true)) {} + FrameLib_PDClass_ComplexExpression(t_object *x, t_symbol *s, long argc, t_atom *argv) : + FrameLib_PDClass_ComplexExpression_Parsed(x, ExprArgumentParser(s, argc, argv, true)) {} }; // Main setup routine From 3e89908f525f742c89a8c86c8e4a6444f54f04f8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:54:11 +0100 Subject: [PATCH 032/222] Reinstate calls using objectMethod --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 062c4693c..fbf61f7a9 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1121,17 +1121,17 @@ class FrameLib_PDClass : public PDClass_Base // Get the number of audio ins/outs safely from a generic pointer -// static long getNumAudioIns(t_object *x) -// { -// t_ptr_int numAudioIns = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioIns()); -// return static_cast(numAudioIns); -// } -// -// static long getNumAudioOuts(t_object *x) -// { -// t_ptr_int numAudioOuts = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioOuts()); -// return static_cast(numAudioOuts); -// } + static long getNumAudioIns(t_object *x) + { + intptr_t numAudioIns = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioIns()); + return static_cast(numAudioIns); + } + + static long getNumAudioOuts(t_object *x) + { + intptr_t numAudioOuts = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioOuts()); + return static_cast(numAudioOuts); + } // Helpers for connection methods From b03d1d38d2d6b1c8763fb1c945add2d5d5d51bbf Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:54:58 +0100 Subject: [PATCH 033/222] Add more code from the max wrapper --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index fbf61f7a9..bc7f1484f 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -533,6 +533,25 @@ class FrameLib_PDClass : public PDClass_Base using ConnectionInfo = FrameLib_PDGlobals::ConnectionInfo; static t_atomtype atom_gettype(t_atom* a) { return a->a_type; } + struct ConnectionConfirmation + { + ConnectionConfirmation(PDConnection connection, long inIdx) + : mConfirm(false), mConnection(connection), mInIndex(inIdx) {} + + bool confirm(PDConnection connection, long inIdx) + { + bool result = inIdx == mInIndex && connection == mConnection; + + if (result) + mConfirm = true; + + return result; + } + + bool mConfirm; + PDConnection mConnection; + long mInIndex; + }; struct PDProxy : public PDClass_Base { @@ -1118,7 +1137,17 @@ class FrameLib_PDClass : public PDClass_Base { return object ? object->getProxy()->getOwner() : nullptr; } - + +// bool versionMismatch(t_object *object, long inIdx, bool report) const +// { +// bool mismatch = FrameLib_PDPrivate::versionMismatch(object); +// +// if (mismatch && report) +// mInputs[inIdx].reportError(mUserObject, Input::kVersion); +// +// return mismatch; +// } + // Get the number of audio ins/outs safely from a generic pointer static long getNumAudioIns(t_object *x) From 117c24c3fad46756d15fda97951a067a9a831448 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:58:27 +0100 Subject: [PATCH 034/222] Header order --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index bc7f1484f..8ffe4f61b 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -4,6 +4,8 @@ #include "PDClass_Base.h" +#include "g_canvas.h" + #include "FrameLib_Global.h" #include "FrameLib_Context.h" #include "FrameLib_Parameters.h" @@ -11,8 +13,6 @@ #include "FrameLib_Multistream.h" #include "FrameLib_SerialiseGraph.h" -#include "g_canvas.h" - #include #include #include From 94961e5d55930715efedfd6e605150046a9df7c4 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 22:58:42 +0100 Subject: [PATCH 035/222] Add more structs to support connections for pd --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 8ffe4f61b..4c9dab9e1 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -142,6 +142,24 @@ struct FrameLib_PDMessageProxy : FrameLib_PDProxy //void contextPatchUpdated(t_object *patch, unsigned long depth) override { mDepth = depth; } }; +struct FrameLib_PDNRTAudio +{ + FrameLib_Multistream *mObject; + t_symbol *mBuffer; +}; + +struct FrameLib_PDContext +{ + bool mRealtime; + t_object *mPatch; + t_symbol *mName; + + bool operator == (const FrameLib_PDContext& b) const + { + return mRealtime == b.mRealtime && mPatch == b.mPatch && mName == b.mName; + } +}; + ////////////////////////////////////////////////////////////////////////// /////////////////////////// Messaging Classes //////////////////////////// ////////////////////////////////////////////////////////////////////////// From 18b26bd94a2a6cac85fb49aa878d7883c481beb9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 23:23:53 +0100 Subject: [PATCH 036/222] Move to private messages to avoid errors --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 4c9dab9e1..54c9752be 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -69,9 +69,9 @@ struct FrameLib_PDPrivate }; static inline t_symbol *FLNamespace() { return gensym("__fl.framelib_private"); } - static inline t_symbol *globalTag() { return gensym(VersionString("__fl.max_global_tag")); } + static inline t_symbol *globalTag() { return gensym(VersionString("__fl.pd_global_tag")); } - static inline VersionString objectGlobal() { return "__fl.max_global_items"; } + static inline VersionString objectGlobal() { return "__fl.pd_global_items"; } static inline VersionString objectMessageHandler() { return "__fl.message.handler"; } static inline VersionString objectMutator() { return "__fl.signal.mutator"; } @@ -628,16 +628,17 @@ class FrameLib_PDClass : public PDClass_Base addMethod, &FrameLib_PDClass::frame>(c, "frame"); addMethod, &FrameLib_PDClass::sync>(c, "sync"); addMethod, &FrameLib_PDClass::dsp>(c); - addMethod(c, (t_method) &extResolveConnections, "__fl.resolve_connections"); - addMethod(c, (t_method) &extMakeAutoOrdering, "__fl.auto_ordering_connections"); - addMethod(c, (t_method) &extClearAutoOrdering, "__fl.clear_auto_ordering_connections"); + + addMethod(c, (t_method) &extResolveConnections, FrameLib_PDPrivate::messageResolveConnections()); + addMethod(c, (t_method) &extMakeAutoOrdering, FrameLib_PDPrivate::messageMakeAutoOrdering()); + addMethod(c, (t_method) &extClearAutoOrdering, FrameLib_PDPrivate::messageClearAutoOrdering()); + addMethod(c, (t_method) &extConnectionConfirm, FrameLib_PDPrivate::messageConnectionConfirm()); + addMethod(c, (t_method) &extGetNumAudioIns, FrameLib_PDPrivate::messageGetNumAudioIns()); + addMethod(c, (t_method) &extGetNumAudioOuts, FrameLib_PDPrivate::messageGetNumAudioOuts()); addMethod(c, (t_method) &extIsConnected, "__fl.is_connected"); - addMethod(c, (t_method) &extConnectionConfirm, "__fl.connection_confirm"); addMethod(c, (t_method) &extGetInternalObject, "__fl.get_internal_object"); addMethod(c, (t_method) &extIsOutput, "__fl.is_output"); - addMethod(c, (t_method) &extGetNumAudioIns, "__fl.get_num_audio_ins"); - addMethod(c, (t_method) &extGetNumAudioOuts, "__fl.get_num_audio_outs"); - + dspInit(c); } @@ -894,7 +895,7 @@ class FrameLib_PDClass : public PDClass_Base { // Resolve connections (in case there are no schedulers left in the patch) and mark unresolved for next time - iterateCanvas(mCanvas, gensym("__fl.resolve_connections")); + iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageResolveConnections())); //resolveConnections(); mNeedsResolve = true; @@ -949,9 +950,9 @@ class FrameLib_PDClass : public PDClass_Base if (action != FrameLib_PDGlobals::SyncCheck::kSyncComplete && handlesAudio() && mNeedsResolve) { - iterateCanvas(mCanvas, gensym("__fl.resolve_connections")); - iterateCanvas(mCanvas, gensym("__fl.clear_auto_ordering_connections")); - iterateCanvas(mCanvas, gensym("__fl.auto_ordering_connections")); + iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageResolveConnections())); + iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageClearAutoOrdering())); + iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageMakeAutoOrdering())); } // FIX From 7b6b23b9e2ce618ab496420dfd0f0ef6284bfdf3 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 23:52:11 +0100 Subject: [PATCH 037/222] Move helper to base --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1 - FrameLib_PD_Objects/Common/PDClass_Base.h | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 54c9752be..8c4d645ee 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -550,7 +550,6 @@ class FrameLib_PDClass : public PDClass_Base using ConnectionInfo = FrameLib_PDGlobals::ConnectionInfo; - static t_atomtype atom_gettype(t_atom* a) { return a->a_type; } struct ConnectionConfirmation { ConnectionConfirmation(PDConnection connection, long inIdx) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index bfdb740e2..b26b5971c 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -68,6 +68,11 @@ class PDClass_Base // Atom helpers + static t_atomtype atom_gettype(t_atom* a) + { + return a->a_type; + } + static void atom_setfloat(t_atom *a, double v) { a->a_type = A_FLOAT; From 052b8e55dc471fa99662d3463f86042856ae756d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 23:52:58 +0100 Subject: [PATCH 038/222] Rework connection confirmation --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 8c4d645ee..1c4e1f1a2 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -448,7 +448,7 @@ class FrameLib_PDGlobals : public PDClass_Base struct ConnectionInfo { - enum Mode { kConnect, kConfirm, kDoubleCheck }; + enum class Mode : intptr_t { kConnect, kConfirm, kDoubleCheck }; ConnectionInfo(t_object *object, unsigned long index, Mode mode) : mObject(object), mIndex(index), mMode(mode) {} @@ -996,17 +996,17 @@ class FrameLib_PDClass : public PDClass_Base switch (info->mMode) { - case ConnectionInfo::kConnect: + case ConnectionInfo::Mode::kConnect: connect(info->mObject, info->mIndex, index); break; - case ConnectionInfo::kConfirm: - case ConnectionInfo::kDoubleCheck: + case ConnectionInfo::Mode::kConfirm: + case ConnectionInfo::Mode::kDoubleCheck: if (index == mConfirmInIndex && mConfirmObject == info->mObject && mConfirmOutIndex == info->mIndex) { mConfirm = true; - if (info->mMode == ConnectionInfo::kDoubleCheck) + if (info->mMode == ConnectionInfo::Mode::kDoubleCheck) pd_error(mUserObject, "extra connection to input %ld", index + 1); } break; @@ -1032,7 +1032,7 @@ class FrameLib_PDClass : public PDClass_Base static uintptr_t extIsConnected(FrameLib_PDClass *x, unsigned long index) { - return x->confirmConnection(index, ConnectionInfo::kConfirm); + return x->confirmConnection(index, ConnectionInfo::Mode::kConfirm); } static void extConnectionConfirm(FrameLib_PDClass *x, unsigned long index, FrameLib_PDGlobals::ConnectionInfo::Mode mode) @@ -1059,24 +1059,7 @@ class FrameLib_PDClass : public PDClass_Base { return x->getNumAudioOuts(); } - - static void confirmMethod(t_object *object, t_symbol *methodName, long index, ConnectionInfo::Mode mode) - { - //vmess((t_pd *) g, method, ""); - - // FIX - look at vmess - - typedef void (*func)(t_object *, long, ConnectionInfo::Mode); - - t_gotfn f = zgetfn(&object->ob_pd, methodName); - - if (!f) - return; - - func f2 = (func)f; - return f2(object, index, mode); - } - + private: // Unwrapping connections @@ -1119,17 +1102,17 @@ class FrameLib_PDClass : public PDClass_Base // Confirm input connections for (unsigned long i = 0; i < getNumIns(); i++) - confirmConnection(i, ConnectionInfo::kConfirm); + confirmConnection(i, ConnectionInfo::Mode::kConfirm); // Confirm ordering connections for (unsigned long i = 0; i < getNumOrderingConnections(); i++) - confirmConnection(getOrderingConnection(i), getNumIns(), ConnectionInfo::kConfirm); + confirmConnection(getOrderingConnection(i), getNumIns(), ConnectionInfo::Mode::kConfirm); // Make output connections for (unsigned long i = getNumOuts(); i > 0; i--) - makeConnection(i - 1, ConnectionInfo::kConnect); + makeConnection(i - 1, ConnectionInfo::Mode::kConnect); mNeedsResolve = false; } @@ -1228,7 +1211,7 @@ class FrameLib_PDClass : public PDClass_Base // Check for connection *only* if the internal object is connected (otherwise assume the previously connected object has been deleted) if (mConfirmObject) - confirmMethod(mConfirmObject, gensym("__fl.connection_confirm"), mConfirmOutIndex, mode); + objectMethod(mConfirmObject, FrameLib_PDPrivate::messageConnectionConfirm(), mConfirmOutIndex, mode); if (mConfirmObject && !mConfirm) disconnect(mConfirmObject, mConfirmOutIndex, mConfirmInIndex); @@ -1251,7 +1234,7 @@ class FrameLib_PDClass : public PDClass_Base { FrameLib_Multistream *object = getInternalObject(src); - if (!isOrderingInput(inIdx) && (!validInput(inIdx) || !validOutput(outIdx, object) || matchConnection(src, outIdx, inIdx) || confirmConnection(inIdx, ConnectionInfo::kDoubleCheck))) + if (!isOrderingInput(inIdx) && (!validInput(inIdx) || !validOutput(outIdx, object) || matchConnection(src, outIdx, inIdx) || confirmConnection(inIdx, ConnectionInfo::Mode::kDoubleCheck))) return; ConnectionResult result; From dddae6e748ddd8807170ae3d441da7240d3abac7 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 30 Jul 2022 23:53:11 +0100 Subject: [PATCH 039/222] Remove unused method --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 1c4e1f1a2..25f9d87db 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1062,19 +1062,6 @@ class FrameLib_PDClass : public PDClass_Base private: - // Unwrapping connections - - void unwrapConnection(t_object *& object, long& connection) - { - /*t_object *wrapped = (t_object *) object_method(object, gensym("__fl.wrapper_internal_object")); - - if (wrapped) - { - object = wrapped; - connection++; - }*/ - } - // Get an internal object from a generic pointer safely FrameLib_Multistream *getInternalObject(t_object *x) From cd787c662c758419efa6b4f055154ae734af2853 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 11:05:03 +0100 Subject: [PATCH 040/222] Formatting --- .../Common/FrameLib_MaxClass.h | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 2be7704cc..b9243956a 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -632,7 +632,13 @@ class FrameLib_MaxGlobals : public MaxClass_Base // Constructor and Destructor (public for max API, but use ManagedPointer from outside this class) FrameLib_MaxGlobals(t_object *x, t_symbol *sym, long ac, t_atom *av) - : mReportContextErrors(false), mRTNotifier(&mRTGlobal), mNRTNotifier(&mNRTGlobal), mRTGlobal(nullptr), mNRTGlobal(nullptr), mQelem(*this, (method) &serviceContexts), mSyncCheck(nullptr) + : mReportContextErrors(false) + , mRTNotifier(&mRTGlobal) + , mNRTNotifier(&mNRTGlobal) + , mRTGlobal(nullptr) + , mNRTGlobal(nullptr) + , mQelem(*this, (method) &serviceContexts) + , mSyncCheck(nullptr) {} // Max global item methods @@ -2158,7 +2164,7 @@ class FrameLib_MaxClass : public MaxClass_Base if (mObject) { FrameLib_Context context = mGlobal->makeContext(mMaxContext); - + if (context != mObject->getContext()) { mGlobal->addContextToResolve(context, *this); @@ -2166,7 +2172,7 @@ class FrameLib_MaxClass : public MaxClass_Base } // N.B. release because otherwise it is retained twice - + mGlobal->releaseContext(context); } } @@ -2178,7 +2184,7 @@ class FrameLib_MaxClass : public MaxClass_Base FrameLib_MaxContext maxContext = mGlobal->getMaxContext(context); FrameLib_Context current = getContext(); bool mismatchedPatch = mGlobal->getMaxContext(current).mPatch != maxContext.mPatch; - + unsigned long size = 0; if ((!force && mismatchedPatch) || current == context) @@ -2193,7 +2199,7 @@ class FrameLib_MaxClass : public MaxClass_Base for (unsigned long i = 0; i < mObject->getNumIns(); i++) if (const double *values = mObject->getFixedInput(i, &size)) newObject->setFixedInput(i, values, size); - + if (mGlobal->isRealtime(context) || mGlobal->isRealtime(current)) dspSetBroken(); @@ -2209,7 +2215,7 @@ class FrameLib_MaxClass : public MaxClass_Base object_attr_touch(mUserObject, gensym("rt")); if (idChanged) object_attr_touch(mUserObject, gensym("id")); - + mObject.reset(newObject); } @@ -2795,13 +2801,13 @@ class FrameLib_MaxClass : public MaxClass_Base long mProxyNum; ConnectionConfirmation *mConfirmation; - + unique_object_ptr mSyncIn; t_object *mUserObject; unsigned long mSpecifiedStreams; - + bool mConnectionsUpdated; bool mContextPatchConfirmed; bool mResolved; From cb9e59e508157593f00249655b18ac4df30af76c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 11:05:23 +0100 Subject: [PATCH 041/222] Remove unnecessary object scope --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index b9243956a..4d3c8efdf 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -1304,7 +1304,7 @@ class FrameLib_MaxClass : public MaxClass_Base enum Error { kNone = 0x00, kVersion = 0x01, kContext = 0x02, kExtra= 0x04, kFeedback = 0x08, kDirect = 0x10 }; Input(void *proxy, long index) - : mProxy(MaxClass_Base::toUnique(proxy)) + : mProxy(toUnique(proxy)) , mIndex(index) , mErrorTime(-1) , mErrorFlags(0) From 295347f08dd45e052031a7b6b91fb4a4b5ff8c31 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 11:33:18 +0100 Subject: [PATCH 042/222] Whitespace --- .../Common/FrameLib_MaxClass.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 4d3c8efdf..7b54a6eda 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -450,7 +450,7 @@ class MessageHandler : public MaxClass_Base mutable FrameLib_Lock mLock; mutable FrameLib_Lock mFlushLock; - + MessageBlock mData; std::deque mOutput; }; @@ -610,7 +610,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base long mTime; Mode mMode; }; - + // Convenience Pointer for automatic deletion and RAII struct ManagedPointer @@ -620,10 +620,10 @@ class FrameLib_MaxGlobals : public MaxClass_Base ManagedPointer(const ManagedPointer&) = delete; ManagedPointer& operator=(const ManagedPointer&) = delete; - + FrameLib_MaxGlobals *operator->() { return mPointer; } const FrameLib_MaxGlobals *operator->() const { return mPointer; } - + private: FrameLib_MaxGlobals *mPointer; @@ -640,7 +640,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base , mQelem(*this, (method) &serviceContexts) , mSyncCheck(nullptr) {} - + // Max global item methods void clearQueue() { mQueue.clear(); } @@ -655,7 +655,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base return object; } - + void addContextToResolve(FrameLib_Context context, t_object *object) { mUnresolvedContexts[context] = object; @@ -698,7 +698,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); // Set timeouts - + if (key.mRealtime) (*(std::get(*item).get()))->setTimeOuts(16.0, 1.0); else @@ -712,15 +712,15 @@ class FrameLib_MaxGlobals : public MaxClass_Base void retainContext(FrameLib_Context c) { data(c)++; } void releaseContext(FrameLib_Context c) { if (--data(c) == 0) mContextRefs.erase(data(c)); } - + void flushContext(FrameLib_Context c, FrameLib_MaxProxy *proxy) { ErrorNotifier::flush(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal); getHandler(c)->flush(proxy); - + auto it = mUnresolvedContexts.find(c); - + if (it != mUnresolvedContexts.end()) { objectMethod(it->second, FrameLib_MaxPrivate::messageResolveContext()); @@ -732,19 +732,19 @@ class FrameLib_MaxGlobals : public MaxClass_Base { ErrorNotifier::flushIgnore(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal, object); } - + FrameLib_MaxContext getMaxContext(FrameLib_Context c) { return data(c); } - + bool isRealtime(FrameLib_Context c) const { return c.getGlobal() == mRTGlobal; } Lock *getLock(FrameLib_Context c) { return &data(c); } t_object *&finalObject(FrameLib_Context c) { return data(c); } - + void setReportContextErrors(bool report) { mReportContextErrors = report; } bool getReportContextErrors() const { return mReportContextErrors; } - + void setConnection(MaxConnection c) { mConnection = c; } void setConnectionMode(ConnectionMode m) { mConnectionMode = m; } MaxConnection getConnection() const { return mConnection; } @@ -764,7 +764,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base { for (auto it = x->mUnresolvedContexts.begin(); it != x->mUnresolvedContexts.end(); it++) objectMethod(it->second, FrameLib_MaxPrivate::messageResolveContext()); - + x->mUnresolvedContexts.clear(); } From d7c88fb2ee32c30853eef77393fb7d5f77f90ea4 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 12:32:13 +0100 Subject: [PATCH 043/222] Add a unique pd object handler --- FrameLib_PD_Objects/Common/PDClass_Base.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index b26b5971c..b5641c1a0 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -11,8 +11,18 @@ class PDClass_Base { + struct ObjectFree + { + void operator()(t_pd *ptr) { pd_free(ptr); } + }; + public: + // Unique pointers to t_objects + + using unique_pd_ptr = std::unique_ptr; + static unique_pd_ptr toUnique(void *ptr) { return unique_pd_ptr(reinterpret_cast(ptr)); } + // Default Constructor PDClass_Base() {} From 94fe59db05ffea95c3f74d586405221a08b2c364 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 14:55:24 +0100 Subject: [PATCH 044/222] Default arg types --- FrameLib_PD_Objects/Common/PDClass_Base.h | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index b5641c1a0..57c9642ef 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -11,6 +11,15 @@ class PDClass_Base { + template + struct DefaultArg + { + DefaultArg(T value) : mValue(value) {} + operator T() { return mValue; } + + T mValue; + }; + struct ObjectFree { void operator()(t_pd *ptr) { pd_free(ptr); } @@ -18,10 +27,31 @@ class PDClass_Base public: + // Types for defining methods with DEFLONG or DEFFLOAT arguments + + //using def_int = DefaultArg; + using def_double = DefaultArg; + + // Unique pointers to t_objects using unique_pd_ptr = std::unique_ptr; - static unique_pd_ptr toUnique(void *ptr) { return unique_pd_ptr(reinterpret_cast(ptr)); } + static unique_pd_ptr toUnique(t_pd *ptr) { return unique_pd_ptr(ptr); } + + // Qelem struct for C++-style usage + + struct Qelem + { + Qelem(void *x, t_method fn) {} + ~Qelem() { } + + void set() { qelem_set(mQelem); } + void front() { qelem_front(mQelem); } + + private: + + t_qelem *mQelem; + }; // Default Constructor From 7481dd7033b3aad1b8ff91b6ab04a789cf39a57b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 14:55:37 +0100 Subject: [PATCH 045/222] Better objectMAthod() support --- FrameLib_PD_Objects/Common/PDClass_Base.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 57c9642ef..1483de139 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -130,11 +130,11 @@ class PDClass_Base template static ReturnType objectMethod(t_object *object, const char* theMethodName, Args...args) { - return objectMethod((t_pd *)object, gensym(theMethodName), args...); + return objectMethod(object, gensym(theMethodName), args...); } template - static ReturnType objectMethod(t_pd *object, t_symbol* theMethod, Args...args) + static ReturnType objectMethod(t_object *object, t_symbol* theMethod, Args...args) { void *pad = nullptr; return objectMethod(object, theMethod, args..., pad); @@ -143,11 +143,11 @@ class PDClass_Base // Specialisation to prevent infinite padding template - static ReturnType objectMethod(t_pd *object, t_symbol* theMethod, S s, T t, U u, V v, W w) + static ReturnType objectMethod(t_object *object, t_symbol* theMethod, S s, T t, U u, V v, W w) { typedef void *(*t_fn5)(void *x, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5); - t_fn5 *m = (t_fn5 *) zgetfn(object, theMethod); + t_fn5 *m = (t_fn5 *) zgetfn((t_pd *) object, theMethod); void *ret = (*m)(object, objectMethodArg(s), From 875d7d96a0ad996d56c598659b259d12d3ded695 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 14:55:54 +0100 Subject: [PATCH 046/222] Formatting --- FrameLib_PD_Objects/Common/PDClass_Base.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 1483de139..c4a10c09a 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -95,7 +95,8 @@ class PDClass_Base return w + 3; } - template ::MethodPerform F> void addPerform(t_signal **sp) + template ::MethodPerform F> + void addPerform(t_signal **sp) { for (size_t i = 0; i < mSigIns.size(); i++) mSigIns[i] = sp[i]->s_vec; @@ -175,7 +176,8 @@ class PDClass_Base return &str; } - template static void makeClass(const char *classname) + template + static void makeClass(const char *classname) { t_class **C = getClassPointer(); @@ -185,14 +187,16 @@ class PDClass_Base class_sethelpsymbol(*C, gensym(classname)); } - template static void *create(t_symbol *sym, long ac, t_atom *av) + template + static void *create(t_symbol *sym, long ac, t_atom *av) { void *x = pd_new(*getClassPointer()); new(x) T(reinterpret_cast(x), sym, ac, av); return x; } - template static void destroy(t_object * x) + template + static void destroy(t_object * x) { ((T *)x)->~T(); } From 80bb278d4e77504ffffef44ea2c74af7be1a53e0 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 14:56:03 +0100 Subject: [PATCH 047/222] dsp helpers --- FrameLib_PD_Objects/Common/PDClass_Base.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index c4a10c09a..23d1247b8 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -223,6 +223,20 @@ class PDClass_Base outlet_new(*this, gensym("signal")); } + bool dspIsRunning() + { + return canvas_dspstate; + } + + bool dspSetBroken() + { + if (!dspIsRunning()) + return false; + + canvas_update_dsp(); + return true; + } + const t_sample *getAudioIn(unsigned long idx) { return mSigIns[idx]; } t_sample *getAudioOut(unsigned long idx) { return mSigOuts[idx]; } From 99e536c6fd93dada71452d330ed6353187287390 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 14:56:10 +0100 Subject: [PATCH 048/222] Whitespace --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 7b54a6eda..f10835a25 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -1883,7 +1883,7 @@ class FrameLib_MaxClass : public MaxClass_Base return; LockHold lock(mGlobal->getLock(getContext())); - + resolveNRTGraph(0.0, false); // Retrieve all the audio objects in a list @@ -2274,7 +2274,7 @@ class FrameLib_MaxClass : public MaxClass_Base traversePatch(FrameLib_MaxPrivate::messageResolveConnections(), &updated); traversePatch(FrameLib_MaxPrivate::messageConnectionUpdate(), t_ptr_int(false)); mGlobal->setReportContextErrors(false); - + // If updated then redo auto ordering connections if (updated) From 6ea29a788e2ba70f4da8bfe0e1af8f3cf4ce37f7 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 15:00:57 +0100 Subject: [PATCH 049/222] Whitespace --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index f10835a25..9eecb3a19 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -325,7 +325,7 @@ class MessageHandler : public MaxClass_Base void add(const MessageInfo& info, const FrameLib_Parameters::Serial *serial) { // Lock, determine maximum vector size and copy - + FrameLib_LockHolder lock(&mLock); for (auto it = serial->begin(); it != serial->end(); it++) @@ -342,7 +342,7 @@ class MessageHandler : public MaxClass_Base void ready() { - // Lock and copy onto the output queue + // Lock and copy onto the output queue FrameLib_LockHolder lock(&mLock); @@ -376,7 +376,7 @@ class MessageHandler : public MaxClass_Base MessageBlock messages; // Swap data - + FrameLib_LockHolder flushLock(&handler->mFlushLock); FrameLib_LockHolder lock(&handler->mLock); @@ -850,7 +850,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base std::deque mQueue; ResolveMap mUnresolvedContexts; RefMap mContextRefs; - + FrameLib_Global *mRTGlobal; FrameLib_Global *mNRTGlobal; From 34fc38569d7941d390c2d11eff3bc36da568c680 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 15:40:54 +0100 Subject: [PATCH 050/222] Support default float arguments --- FrameLib_PD_Objects/Common/PDClass_Base.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 23d1247b8..b6c80c67d 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -73,6 +73,11 @@ class PDClass_Base template ::MethodFloat F> static void call(T *x, double v) { ((x)->*F)(v); } template ::MethodFloat F> static void addMethod(t_class *c, const char *name) { class_addmethod(c, (t_method) call, gensym(name), A_FLOAT, 0); } + template struct DefFloat { typedef void (T::*MethodDefFloat)(def_double v); }; + template ::MethodDefFloat F> static void call(T *x, double v) { (x->*F)(v); } + template ::MethodDefFloat F> + static void addMethod(t_class *c, const char *name) { auto f = call; class_addmethod(c, (t_method) f, gensym(name), A_DEFFLOAT, 0); } + template struct Sym { typedef void (T::*MethodSym)(t_symbol *s); }; template ::MethodSym F> static void call(T *x, t_symbol *s) { ((x)->*F)(s); } template ::MethodSym F> static void addMethod(t_class *c, const char *name) { class_addmethod(c, (t_method) call, gensym(name), A_DEFSYM, 0); } From e839d62034a6798c9575f18244a7bc4d525815e9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 15:41:03 +0100 Subject: [PATCH 051/222] Clock and queue support --- FrameLib_PD_Objects/Common/PDClass_Base.h | 43 ++++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index b6c80c67d..d25750153 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -38,19 +38,52 @@ class PDClass_Base using unique_pd_ptr = std::unique_ptr; static unique_pd_ptr toUnique(t_pd *ptr) { return unique_pd_ptr(ptr); } + // Clock struct for C++-style usage + + struct Clock + { + Clock(void *x, t_method fn) { mClock = clock_new(x, fn); } + ~Clock() { clock_free(mClock); } + + void delay(double delaytime = 0.0) { clock_delay(mClock, delaytime); } + + private: + + t_clock *mClock; + }; + // Qelem struct for C++-style usage struct Qelem { - Qelem(void *x, t_method fn) {} - ~Qelem() { } + typedef void (*IntMethod)(void *x); + + Qelem(void *x, t_method fn) + : mClock(this, (t_method) &call) + , mMethod((IntMethod) fn) + , mOwner(x) + {} + + void set() + { + bool expected = false; + + if (mFlag.compare_exchange_strong(expected, true)) + mClock.delay(); + } - void set() { qelem_set(mQelem); } - void front() { qelem_front(mQelem); } + static void call(Qelem *a) + { + mFlag.store(false); + (*a->mMethod)(a->mOwner); + } private: - t_qelem *mQelem; + Clock mClock; + IntMethod mMethod; + void *mOwner; + std::atomic_bool mFlag; }; // Default Constructor From 7fa4d1a5adf49f8f2ef4a4a461afb00315448aaf Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 15:41:34 +0100 Subject: [PATCH 052/222] Fix access to class member in static method --- FrameLib_PD_Objects/Common/PDClass_Base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index d25750153..ac75d0235 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -74,7 +74,7 @@ class PDClass_Base static void call(Qelem *a) { - mFlag.store(false); + a->mFlag.store(false); (*a->mMethod)(a->mOwner); } From 5d21f75a2f8ec0ad78891b99e57227a83183bede Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 15:42:31 +0100 Subject: [PATCH 053/222] Refactor pd wrapper to reflact current Max wrapper design and features (builds but incomplete) --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1095 ++++++++++++----- 1 file changed, 786 insertions(+), 309 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 25f9d87db..e7526eee5 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -68,7 +68,6 @@ struct FrameLib_PDPrivate std::string mString; }; - static inline t_symbol *FLNamespace() { return gensym("__fl.framelib_private"); } static inline t_symbol *globalTag() { return gensym(VersionString("__fl.pd_global_tag")); } static inline VersionString objectGlobal() { return "__fl.pd_global_items"; } @@ -151,19 +150,19 @@ struct FrameLib_PDNRTAudio struct FrameLib_PDContext { bool mRealtime; - t_object *mPatch; + t_glist *mCanvas; t_symbol *mName; bool operator == (const FrameLib_PDContext& b) const { - return mRealtime == b.mRealtime && mPatch == b.mPatch && mName == b.mName; + return mRealtime == b.mRealtime && mCanvas == b.mCanvas && mName == b.mName; } }; ////////////////////////////////////////////////////////////////////////// /////////////////////////// Messaging Classes //////////////////////////// ////////////////////////////////////////////////////////////////////////// -/* + struct MessageInfo { MessageInfo(FrameLib_PDMessageProxy* proxy, FrameLib_TimeFormat time, unsigned long stream) @@ -235,7 +234,8 @@ class MessageHandler : public PDClass_Base public: - MessageHandler(t_object *x, t_symbol *sym, long ac, t_atom *av) {} + MessageHandler(t_object *x, t_symbol *sym, long ac, t_atom *av) + : mClock(x, (t_method) &service) {} void add(const MessageInfo& info, const double *values, unsigned long N) { @@ -281,7 +281,7 @@ class MessageHandler : public PDClass_Base void schedule() { ready(); - schedule_delay(*this, (t_method) &service, 0, nullptr, 0, nullptr); + mClock.delay(); } void flush(FrameLib_PDProxy *proxy) @@ -377,8 +377,10 @@ class MessageHandler : public PDClass_Base MessageBlock mData; std::deque mOutput; + + Clock mClock; }; -*/ + ////////////////////////////////////////////////////////////////////////// //////////////////////////// PD Globals Class //////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -387,77 +389,94 @@ class FrameLib_PDGlobals : public PDClass_Base { public: - // Sync Check Class + enum ConnectionMode : intptr_t { kConnect, kConfirm, kDoubleCheck }; + + using PDConnection = FrameLib_Connection; + //using ConnectAccept = FrameLib_MaxConnectAccept; + using Lock = FrameLib_Lock; + +private: - class SyncCheck + struct Hash { - public: - - enum Mode { kDownOnly, kDown, kAcross }; - enum Action { kSyncComplete, kSync, kAttachAndSync }; - - SyncCheck() : mGlobal(get()), mObject(nullptr), mTime(-1), mMode(kDownOnly) {} - ~SyncCheck() { mGlobal->release(); } - - Action operator()(void *object, bool handlesAudio, bool isOutput) + size_t operator()(void *a, void *b) const { - const SyncCheck *info = mGlobal->getSyncCheck(); - - if (info && (info->mTime != mTime || info->mObject != mObject)) - { - set(info->mObject, info->mTime, info->mMode); - return handlesAudio && object != mObject && (mMode != kAcross || isOutput) ? kAttachAndSync : kSync; - } - - if (info && mMode == kAcross && info->mMode == kDown) - { - mMode = kDown; - return handlesAudio && object != mObject && !isOutput ? kAttachAndSync : kSync; - } + size_t hash = 0; + hash ^= std::hash()(a) + 0x9e3779b9 + (hash << 6) + (hash >> 2); + hash ^= std::hash()(b) + 0x9e3779b9 + (hash << 6) + (hash >> 2); - return kSyncComplete; + return hash; } - void sync(void *object = nullptr, long time = -1, Mode mode = kDownOnly) + size_t operator()(const FrameLib_Context& context) const { - set(object, time, mode); - mGlobal->setSyncCheck(object ? this : nullptr); + return operator()(context.getGlobal(), context.getReference()); } - bool upwardsMode() { return setMode(mGlobal->getSyncCheck(), kAcross); } - void restoreMode() { setMode(mGlobal->getSyncCheck(), mMode); } - - private: - - void set(void *object, long time, Mode mode) + size_t operator()(const FrameLib_PDContext& key) const { - mObject = object; - mTime = time; - mMode = mode; + // N.B. Realtime state isn't used in the hash, but used during full lookup + + return operator()(key.mCanvas, key.mName); } - - bool setMode(SyncCheck *info, Mode mode) { return info && info->mMode != kDownOnly && ((info->mMode = mode) == mode); } - - FrameLib_PDGlobals *mGlobal; - void *mObject; - long mTime; - Mode mMode; }; + + enum RefDataItem { kKey, kCount, kLock, kFinal, kHandler, kQueuePtr }; - // ConnectionInfo Struct + using QueuePtr = std::unique_ptr; + using RefData = std::tuple; + using RefMap = std::unordered_map, Hash>; + using ResolveMap = std::unordered_map; + +public: - struct ConnectionInfo + // Error Notification Class + + struct ErrorNotifier : public FrameLib_ErrorReporter::HostNotifier { - enum class Mode : intptr_t { kConnect, kConfirm, kDoubleCheck }; - - ConnectionInfo(t_object *object, unsigned long index, Mode mode) : mObject(object), mIndex(index), mMode(mode) {} + ErrorNotifier(FrameLib_Global **globalHandle) + : mQelem(globalHandle, (t_method) &flush) {} - t_object *mObject; - unsigned long mIndex; - Mode mMode; + bool notify(const FrameLib_ErrorReporter::ErrorReport& report) override + { + mQelem.set(); + return false; + } - }; + static void flushIgnore(FrameLib_Global **globalHandle, t_object *ignore = nullptr) + { + auto reports = (*globalHandle)->getErrors(); + + for (auto it = reports->begin(); it != reports->end(); it++) + { + std::string errorText; + t_object *object = it->getReporter() ? it->getReporter()->getOwner() : nullptr; + t_object *userObject = object ? objectMethod(object, FrameLib_PDPrivate::messageGetUserObject()) : nullptr; + + it->getErrorText(errorText); + + if (userObject) + { + if (object == ignore) + continue; + pd_error(userObject, "%s", errorText.c_str()); + } + else + error("%s", errorText.c_str()); + } + + if (reports->isFull()) + error("*** FrameLib - too many errors - reporting only some ***"); + } + + static void flush(FrameLib_Global **globalHandle) + { + flushIgnore(globalHandle); + } + Qelem mQelem; + }; + // Convenience Pointer for automatic deletion and RAII struct ManagedPointer @@ -465,39 +484,172 @@ class FrameLib_PDGlobals : public PDClass_Base ManagedPointer() : mPointer(get()) {} ~ManagedPointer() { mPointer->release(); } + ManagedPointer(const ManagedPointer&) = delete; + ManagedPointer& operator=(const ManagedPointer&) = delete; + FrameLib_PDGlobals *operator->() { return mPointer; } + const FrameLib_PDGlobals *operator->() const { return mPointer; } private: - // Deleted - - ManagedPointer(const ManagedPointer&) = delete; - ManagedPointer& operator=(const ManagedPointer&) = delete; - FrameLib_PDGlobals *mPointer; }; - // Constructor and Destructor (public for the PD API, but use the ManagedPointer for use from outside this class) + // Constructor and Destructor (public for pd API, but use ManagedPointer from outside this class) FrameLib_PDGlobals(t_object *x, t_symbol *sym, long ac, t_atom *av) - : mGlobal(nullptr), mConnectionInfo(nullptr), mSyncCheck(nullptr) {} - ~FrameLib_PDGlobals() { if (mGlobal) FrameLib_Global::release(&mGlobal); } - - // Getters and setters for max global items + : mReportContextErrors(false) + , mRTNotifier(&mRTGlobal) + , mNRTNotifier(&mNRTGlobal) + , mRTGlobal(nullptr) + , mNRTGlobal(nullptr) + , mQelem(*this, (t_method) &serviceContexts) + {} + + // Max global item methods + + void clearQueue() { mQueue.clear(); } + void pushToQueue(t_object * object) { return mQueue.push_back(object); } + + t_object *popFromQueue() + { + t_object *object = mQueue.empty() ? nullptr : mQueue.front(); + + if (object) + mQueue.pop_front(); + + return object; + } + + void addContextToResolve(FrameLib_Context context, t_object *object) + { + mUnresolvedContexts[context] = object; + mQelem.set(); + } - FrameLib_Global *getGlobal() const { return mGlobal; } + void contextMessages(FrameLib_Context c) + { + MessageHandler *handler = getHandler(c); + + handler->ready(); + MessageHandler::service(handler, nullptr, 0, nullptr); + } - const ConnectionInfo *getConnectionInfo() const { return mConnectionInfo; } - void setConnectionInfo(ConnectionInfo *info = nullptr) { mConnectionInfo = info; } + void contextMessages(FrameLib_Context c, t_object *object) + { + if (data(c) == object) + getHandler(c)->schedule(); + } - SyncCheck *getSyncCheck() const { return mSyncCheck; } - void setSyncCheck(SyncCheck *check = nullptr) { mSyncCheck = check; } + MessageHandler *getHandler(FrameLib_Context c) + { + return reinterpret_cast(data(c).get()); + } + + FrameLib_Context makeContext(const FrameLib_PDContext& key) + { + std::unique_ptr& item = mContextRefs[key]; + + if (!item) + { + t_symbol *handlerSym = gensym(FrameLib_PDPrivate::objectMessageHandler()); + item.reset(new RefData()); + FrameLib_Context context(key.mRealtime ? mRTGlobal : mNRTGlobal, item.get()); + + std::get(*item) = key; + std::get(*item) = 1; + std::get(*item) = nullptr; + std::get(*item) = unique_pd_ptr(pd_new(*FrameLib_PDGlobals::getClassPointer())); + std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); + + // Set timeouts + + if (key.mRealtime) + (*(std::get(*item).get()))->setTimeOuts(16.0, 1.0); + else + (*(std::get(*item).get()))->setTimeOuts(100.0, 30.0); + } + else + std::get(*item)++; + + return FrameLib_Context(key.mRealtime ? mRTGlobal : mNRTGlobal, item.get()); + } + + void retainContext(FrameLib_Context c) { data(c)++; } + void releaseContext(FrameLib_Context c) { if (--data(c) == 0) mContextRefs.erase(data(c)); } + + void flushContext(FrameLib_Context c, FrameLib_PDProxy *proxy) + { + ErrorNotifier::flush(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal); + + getHandler(c)->flush(proxy); + + auto it = mUnresolvedContexts.find(c); + + if (it != mUnresolvedContexts.end()) + { + objectMethod(it->second, FrameLib_PDPrivate::messageResolveContext()); + mUnresolvedContexts.erase(it); + } + } + + void flushErrors(FrameLib_Context c, t_object *object) + { + ErrorNotifier::flushIgnore(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal, object); + } + + FrameLib_PDContext getPDContext(FrameLib_Context c) + { + return data(c); + } + + bool isRealtime(FrameLib_Context c) const { return c.getGlobal() == mRTGlobal; } + Lock *getLock(FrameLib_Context c) { return &data(c); } + t_object *&finalObject(FrameLib_Context c) { return data(c); } + + void setReportContextErrors(bool report) { mReportContextErrors = report; } + bool getReportContextErrors() const { return mReportContextErrors; } + + void setConnection(PDConnection c) { mConnection = c; } + void setConnectionMode(ConnectionMode m) { mConnectionMode = m; } + PDConnection getConnection() const { return mConnection; } + ConnectionMode getConnectionMode() const { return mConnectionMode; } + +// void setConnectAccept(ConnectAccept ca) { mConnectAccept = ca; } +// bool checkAccept(ConnectAccept ca) const { return mConnectAccept == ca; } private: - void retain() { FrameLib_Global::get(&mGlobal, FrameLib_Thread::defaultPriorities()); } - void release() { FrameLib_Global::release(&mGlobal); } - + // Context methods + + static void serviceContexts(FrameLib_PDGlobals *x) + { + for (auto it = x->mUnresolvedContexts.begin(); it != x->mUnresolvedContexts.end(); it++) + objectMethod(it->second, FrameLib_PDPrivate::messageResolveContext()); + + x->mUnresolvedContexts.clear(); + } + + template + typename std::tuple_element::type& data(FrameLib_Context context) + { + return std::get(*static_cast(context.getReference())); + } + + // Generate some relevant thread priorities + + static FrameLib_Thread::Priorities priorities(bool realtime) + { + if (!realtime) +#if defined __linux__ || defined __APPLE__ + return { 31, 31, 31, SCHED_OTHER, true }; +#else + return { THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL, 0, true }; +#endif + + return FrameLib_Thread::defaultPriorities(); + } + static FrameLib_PDGlobals **getPDGlobalsPtr() { return (FrameLib_PDGlobals **) &gensym("__fl.pd_global_items")->s_thing; @@ -507,28 +659,80 @@ class FrameLib_PDGlobals : public PDClass_Base static FrameLib_PDGlobals *get() { - // Make sure the max globals class exists + auto maxGlobalClass = FrameLib_PDPrivate::objectGlobal(); + auto messageClassName = FrameLib_PDPrivate::objectMessageHandler(); + + /* + t_symbol *globalTag = FrameLib_MaxPrivate::globalTag(); + + // Make sure the pd globals and message handler classes exist + + if (!class_findbyname(CLASS_NOBOX, gensym(maxGlobalClass))) + makeClass(CLASS_NOBOX, maxGlobalClass); + + if (!class_findbyname(CLASS_NOBOX, gensym(messageClassName))) + MessageHandler::makeClass(CLASS_NOBOX, messageClassName); + + // See if an object is registered (otherwise make object and register it...) + + FrameLib_MaxGlobals *x = (FrameLib_MaxGlobals *) object_findregistered(nameSpace, globalTag); + + if (!x) + x = (FrameLib_MaxGlobals *) object_register(nameSpace, globalTag, object_new_typed(CLASS_NOBOX, gensym(maxGlobalClass), 0, nullptr)); + */ + + // Make sure the pd globals class exists FrameLib_PDGlobals *x = *getPDGlobalsPtr(); if (!x) { - makeClass("__fl.pd_global_items"); + makeClass(maxGlobalClass); + MessageHandler::makeClass(messageClassName); x = (FrameLib_PDGlobals *) pd_new(*FrameLib_PDGlobals::getClassPointer()); *getPDGlobalsPtr() = x; } - - if (x) - x->retain(); + + FrameLib_Global::get(&x->mRTGlobal, priorities(true), &x->mRTNotifier); + FrameLib_Global::get(&x->mNRTGlobal, priorities(false), &x->mNRTNotifier); return x; } - // Pointers + void release() + { + FrameLib_Global::release(&mRTGlobal); + FrameLib_Global::release(&mNRTGlobal); + + if (!mRTGlobal) + { + assert(!mNRTGlobal && "Reference counting error"); + + *getPDGlobalsPtr() = nullptr; + pd_free((t_pd *)this); + } + } + + // Connection Info + + PDConnection mConnection; + ConnectionMode mConnectionMode; + //ConnectAccept mConnectAccept; + bool mReportContextErrors; - FrameLib_Global *mGlobal; - ConnectionInfo *mConnectionInfo; - SyncCheck *mSyncCheck; + // Member Objects / Pointers + + ErrorNotifier mRTNotifier; + ErrorNotifier mNRTNotifier; + + std::deque mQueue; + ResolveMap mUnresolvedContexts; + RefMap mContextRefs; + + FrameLib_Global *mRTGlobal; + FrameLib_Global *mNRTGlobal; + + Qelem mQelem; }; ////////////////////////////////////////////////////////////////////////// @@ -540,15 +744,41 @@ enum PDObjectArgsMode { kAsParams, kAllInputs, kDistribute }; template class FrameLib_PDClass : public PDClass_Base { - //using ConnectionMode = FrameLib_PDGlobals::ConnectionMode; + using ConnectionMode = FrameLib_PDGlobals::ConnectionMode; using FLObject = FrameLib_Multistream; using FLConnection = FrameLib_Object::Connection; - using PDConnection = FrameLib_Object::Connection; + using PDConnection = FrameLib_PDGlobals::PDConnection; using LockHold = FrameLib_LockHolder; using NumericType = FrameLib_Parameters::NumericType; using ClipMode = FrameLib_Parameters::ClipMode; - - using ConnectionInfo = FrameLib_PDGlobals::ConnectionInfo; + + struct PDProxy : public PDClass_Base + { + static t_pd *create(FrameLib_PDClass *owner, int index) + { + t_pd *proxy = pd_new(*PDProxy::getClassPointer()); + + ((PDProxy *)proxy)->mOwner = owner; + ((PDProxy *)proxy)->mIndex = index; + + return proxy; + } + + static void classInit(t_class *c, const char *classname) + { + addMethod(c, "frame"); + } + + PDProxy(t_object *x, t_symbol *sym, long ac, t_atom *av) : mOwner(nullptr), mIndex(-1) {} + + void frame() + { + mOwner->frameInlet(mIndex); + } + + FrameLib_PDClass *mOwner; + int mIndex; + }; struct ConnectionConfirmation { @@ -570,32 +800,58 @@ class FrameLib_PDClass : public PDClass_Base long mInIndex; }; - struct PDProxy : public PDClass_Base + class Input { - static t_pd *create(FrameLib_PDClass *owner, int index) - { - t_pd *proxy = pd_new(*PDProxy::getClassPointer()); - - ((PDProxy *)proxy)->mOwner = owner; - ((PDProxy *)proxy)->mIndex = index; - - return proxy; - } + public: - static void classInit(t_class *c, const char *classname) - { - addMethod(c, "frame"); - } + enum Error { kNone = 0x00, kVersion = 0x01, kContext = 0x02, kExtra= 0x04, kFeedback = 0x08, kDirect = 0x10 }; - PDProxy(t_object *x, t_symbol *sym, long ac, t_atom *av) : mOwner(nullptr), mIndex(-1) {} + Input(t_pd *proxy, long index) + : mProxy(toUnique(proxy)) + , mIndex(index) + , mErrorTime(-1) + , mErrorFlags(0) + {} - void frame() + Input() : Input(nullptr, 0) {} + + void reportError(t_object *userObject, Error error) const { - mOwner->frameInlet(mIndex); + auto postError = [&](const char *str) { pd_error(userObject, "%s input %ld", str, mIndex + 1); }; + + double time = clock_getlogicaltime(); + bool validTime = mErrorTime + 500 >= time; + + if (validTime && mErrorFlags & error) + return; + + switch (error) + { + case kVersion: postError("can't connect objects from different versions of framelib -"); break; + case kContext: postError("can't connect objects in different patching contexts -"); break; + case kExtra: postError("extra connection to"); break; + case kFeedback: postError("feedback loop detected at"); break; + case kDirect: postError("direct feedback loop detected at"); break; + + default: + return; + } + + if (validTime) + mErrorFlags |= error; + else + { + mErrorTime = time; + mErrorFlags = error; + } } - FrameLib_PDClass *mOwner; - int mIndex; + private: + + unique_pd_ptr mProxy; + long mIndex; + mutable long mErrorTime; + mutable long mErrorFlags; }; public: @@ -625,20 +881,31 @@ class FrameLib_PDClass : public PDClass_Base { addMethod, &FrameLib_PDClass::info>(c, "info"); addMethod, &FrameLib_PDClass::frame>(c, "frame"); - addMethod, &FrameLib_PDClass::sync>(c, "sync"); addMethod, &FrameLib_PDClass::dsp>(c); + if (T::sHandlesAudio) + { + addMethod, &FrameLib_PDClass::reset>(c, "reset"); + addMethod, &FrameLib_PDClass::process>(c, "process"); + + addMethod(c, (t_method) &extFindAudio, FrameLib_PDPrivate::messageFindAudioObjects()); + + dspInit(c); + } + + addMethod(c, (t_method) &extResolveContext, FrameLib_PDPrivate::messageResolveContext()); addMethod(c, (t_method) &extResolveConnections, FrameLib_PDPrivate::messageResolveConnections()); + addMethod(c, (t_method) &extMarkUnresolved, FrameLib_PDPrivate::messageMarkUnresolved()); addMethod(c, (t_method) &extMakeAutoOrdering, FrameLib_PDPrivate::messageMakeAutoOrdering()); addMethod(c, (t_method) &extClearAutoOrdering, FrameLib_PDPrivate::messageClearAutoOrdering()); + addMethod(c, (t_method) &extReset, FrameLib_PDPrivate::messageReset()); + addMethod(c, (t_method) &extIsDirectlyConnected, FrameLib_PDPrivate::messageIsDirectlyConnected()); addMethod(c, (t_method) &extConnectionConfirm, FrameLib_PDPrivate::messageConnectionConfirm()); + addMethod(c, (t_method) &extConnectionUpdate, FrameLib_PDPrivate::messageConnectionUpdate()); + addMethod(c, (t_method) &extGetFLObject, FrameLib_PDPrivate::messageGetFrameLibObject()); + addMethod(c, (t_method) &extGetUserObject, FrameLib_PDPrivate::messageGetUserObject()); addMethod(c, (t_method) &extGetNumAudioIns, FrameLib_PDPrivate::messageGetNumAudioIns()); addMethod(c, (t_method) &extGetNumAudioOuts, FrameLib_PDPrivate::messageGetNumAudioOuts()); - addMethod(c, (t_method) &extIsConnected, "__fl.is_connected"); - addMethod(c, (t_method) &extGetInternalObject, "__fl.get_internal_object"); - addMethod(c, (t_method) &extIsOutput, "__fl.is_output"); - - dspInit(c); } // Tag checks @@ -668,14 +935,14 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_PDClass(t_object *x, t_symbol *s, long argc, t_atom *argv, FrameLib_PDProxy *proxy = nullptr) : mProxy(proxy ? proxy : new FrameLib_PDProxy(x)) - , mConfirmObject(nullptr) - , mConfirmInIndex(-1) - , mConfirmOutIndex(-1) - , mConfirm(false) , mCanvas(canvas_getcurrent()) - , mSyncIn(nullptr) - , mNeedsResolve(true) + , mConfirmation(nullptr) , mUserObject(*this) + , mSpecifiedStreams(1) + , mConnectionsUpdated(false) + , mContextPatchConfirmed(false) + , mResolved(false) + , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } { // Stream count @@ -690,13 +957,15 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_Parameters::AutoSerial serialisedParameters; parseParameters(serialisedParameters, argc, argv); - mObject.reset(new T(FrameLib_Context(mGlobal->getGlobal(), mCanvas), &serialisedParameters, mProxy.get(), mSpecifiedStreams)); + FrameLib_Context context = mGlobal->makeContext(mPDContext); + mObject.reset(new T(context, &serialisedParameters, mProxy.get(), mSpecifiedStreams)); parseInputs(argc, argv); long numIns = getNumIns() + (supportsOrderingConnections() ? 1 : 0); mInputs.resize(numIns); mOutputs.resize(getNumOuts()); + mDirectlyConnected.resize(getNumIns(), false); dspSetup(getNumAudioIns(), getNumAudioOuts()); @@ -706,34 +975,27 @@ class FrameLib_PDClass : public PDClass_Base { if (i || handlesAudio()) { - mInputs[i] = PDProxy::create(this, (int) (getNumAudioIns() + i)); - inlet_new(*this, mInputs[i], gensym("frame"), gensym("frame")); + t_pd *proxy = PDProxy::create(this, (int) (getNumAudioIns() + i)); + inlet_new(*this, proxy, gensym("frame"), gensym("frame")); + mInputs[i] = Input(proxy, i); } else - mInputs[i] = nullptr; + mInputs[i] = Input(nullptr, i); } // Create frame outlets for (unsigned long i = 0; i < getNumOuts(); i++) mOutputs[i] = outlet_new(*this, gensym("frame")); - - // Add a sync outlet if we need to handle audio - - if (handlesAudio()) - { - //mSyncIn = (t_object *) outlet_new(nullptr, nullptr); - //outlet_add(mSyncIn, inlet_nth(*this, 0)); - } } ~FrameLib_PDClass() { - for (auto it = mInputs.begin(); it != mInputs.end(); it++) - if (*it) - pd_free(*it); - - //object_free(mSyncIn); + if (isRealtime()) + dspSetBroken(); + + mGlobal->flushContext(getContext(), mProxy.get()); + mGlobal->releaseContext(getContext()); } void info(t_symbol *sym, long ac, t_atom *av) @@ -818,9 +1080,9 @@ class FrameLib_PDClass : public PDClass_Base // Name, type and default value if (defaultStr.size()) - post("Parameter %ld: %s [%s] (default: %s)", i + 1, params->getName(i), params->getTypeString(i).c_str(), defaultStr.c_str()); + post("Parameter %lu: %s [%s] (default: %s)", i + 1, params->getName(i), params->getTypeString(i).c_str(), defaultStr.c_str()); else - post("Parameter %ld: %s [%s]", i + 1, params->getName(i), params->getTypeString(i).c_str()); + post("Parameter %lu: %s [%s]", i + 1, params->getName(i), params->getTypeString(i).c_str()); // Verbose - arguments, range (for numeric types), enum items (for enums), array sizes (for arrays), description @@ -857,6 +1119,7 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_Context getContext() const { return mObject->getContext(); } + bool isRealtime() const { return mGlobal->isRealtime(getContext()); } bool handlesAudio() const { return T::sHandlesAudio; } bool supportsOrderingConnections() const { return mObject->supportsOrderingConnections(); } @@ -889,14 +1152,16 @@ class FrameLib_PDClass : public PDClass_Base for (int j = 0; j < vec_size; j++) getAudioOut(i + 1)[j] = mSigOuts[i][j]; } - + void dsp(t_signal **sp) { + if (!isRealtime()) + return; + // Resolve connections (in case there are no schedulers left in the patch) and mark unresolved for next time - iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageResolveConnections())); - //resolveConnections(); - mNeedsResolve = true; + resolveConnections(); + mResolved = false; // Reset DSP @@ -912,7 +1177,8 @@ class FrameLib_PDClass : public PDClass_Base if (handlesAudio()) { addPerform::perform>(sp); - + mGlobal->finalObject(getContext()) = *this; + mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts() -2)); mSigIns.resize(getNumAudioIns() - 1); mSigOuts.resize(getNumAudioOuts() - 1); @@ -927,56 +1193,86 @@ class FrameLib_PDClass : public PDClass_Base } } - // Get Audio Outputs - - std::vector &getAudioOuts() - { - return mSigOuts; - } + // Non-realtime processing - // Type + static unsigned long maxBlockSize() { return 16384UL; } - ObjectType getType() + void reset(def_double sampleRate = 0.0) { - return mObject->getType(); + if (!isRealtime()) + { + LockHold lock(mGlobal->getLock(getContext())); + resolveNRTGraph(sampleRate > 0.0 ? sampleRate.mValue : sys_getsr(), true); + } } - // Audio Synchronisation - - void sync() + void process(double length) { - FrameLib_PDGlobals::SyncCheck::Action action = mSyncChecker(this, handlesAudio(), extIsOutput(this)); - - if (action != FrameLib_PDGlobals::SyncCheck::kSyncComplete && handlesAudio() && mNeedsResolve) - { - iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageResolveConnections())); - iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageClearAutoOrdering())); - iterateCanvas(mCanvas, gensym(FrameLib_PDPrivate::messageMakeAutoOrdering())); - } + unsigned long updateLength = length > 0 ? static_cast(length) : 0UL; + unsigned long time = static_cast(mObject->getBlockTime()) - 1UL; - // FIX + if (!updateLength || isRealtime()) + return; + + LockHold lock(mGlobal->getLock(getContext())); + + resolveNRTGraph(0.0, false); + + // Retrieve all the audio objects in a list + + std::vector audioObjects; + traversePatch(FrameLib_PDPrivate::messageFindAudioObjects(), &audioObjects); + + // Set up buffers - //if (action == FrameLib_PDGlobals::SyncCheck::kAttachAndSync) - // outlet_anything(mSyncIn, gensym("signal"), 0, nullptr); + unsigned long maxAudioIO = 0; - if (action != FrameLib_PDGlobals::SyncCheck::kSyncComplete) + for (auto it = audioObjects.begin(); it != audioObjects.end(); it++) + maxAudioIO = std::max(maxAudioIO, it->mObject->getNumAudioChans()); + + std::vector audioBuffer(maxBlockSize() * maxAudioIO); + std::vector ioBuffers(maxAudioIO); + + for (unsigned long i = 0; i < maxAudioIO; i++) + ioBuffers[i] = audioBuffer.data() + i * maxBlockSize(); + + // Loop to process audio + + for (unsigned long i = 0; i < updateLength; i += maxBlockSize()) { - for (unsigned long i = getNumOuts(); i > 0; i--) - outlet_anything(mOutputs[i - 1], gensym("sync"), 0, nullptr); + unsigned long blockSize = std::min(maxBlockSize(), updateLength - i); - if (mSyncChecker.upwardsMode()) + // Process inputs and schedulers (block controls object lifetime) + + if (true) { - for (unsigned long i = 0; i < getNumIns(); i++) - if (isConnected(i)) - objectMethod(getConnection(i).mObject, "sync"); + FrameLib_AudioQueue queue; - if (supportsOrderingConnections()) - for (unsigned long i = 0; i < getNumOrderingConnections(); i++) - objectMethod(getOrderingConnection(i).mObject, "sync"); + for (auto it = audioObjects.begin(); it != audioObjects.end(); it++) + { + if (it->mObject->getType() == ObjectType::Output) + continue; + + read(it->mBuffer, ioBuffers.data(), it->mObject->getNumAudioIns(), blockSize, time + i); + it->mObject->blockUpdate(ioBuffers.data(), nullptr, blockSize, queue); + } + } + + // Process outputs + + for (auto it = audioObjects.begin(); it != audioObjects.end(); it++) + { + if (it->mObject->getType() != ObjectType::Output) + continue; - mSyncChecker.restoreMode(); + it->mObject->blockUpdate(nullptr, ioBuffers.data(), blockSize); + write(it->mBuffer, ioBuffers.data(), it->mObject->getNumAudioOuts(), blockSize, time + i); } } + + // Process Messages + + mGlobal->contextMessages(getContext()); } // Connection Routines @@ -988,38 +1284,56 @@ class FrameLib_PDClass : public PDClass_Base void frameInlet(long index) { - const ConnectionInfo *info = mGlobal->getConnectionInfo(); + const PDConnection connection = mGlobal->getConnection(); + index -= getNumAudioIns(); - if (!info) + // Make sure there's an object to connect that has the same framelib version + + if (!connection.mObject || versionMismatch(connection.mObject, index, true)) return; - switch (info->mMode) + if (mGlobal->getConnectionMode() == ConnectionMode::kConnect) { - case ConnectionInfo::Mode::kConnect: - connect(info->mObject, info->mIndex, index); - break; - - case ConnectionInfo::Mode::kConfirm: - case ConnectionInfo::Mode::kDoubleCheck: - - if (index == mConfirmInIndex && mConfirmObject == info->mObject && mConfirmOutIndex == info->mIndex) - { - mConfirm = true; - if (info->mMode == ConnectionInfo::Mode::kDoubleCheck) - pd_error(mUserObject, "extra connection to input %ld", index + 1); - } - break; + connect(connection, index); + } + else if (mConfirmation) + { + if (mConfirmation->confirm(connection, index) && mGlobal->getConnectionMode() == ConnectionMode::kDoubleCheck) + mInputs[index].reportError(mUserObject, Input::kExtra); } } - + + // Get Audio Outputs + + std::vector &getAudioOuts() + { + return mSigOuts; + } + // External methods (A_CANT) - static void extResolveConnections(FrameLib_PDClass *x) + static void extFindAudio(FrameLib_PDClass *x, std::vector *objects) + { + objects->push_back(FrameLib_PDNRTAudio{x->mObject.get(), x->mBuffer}); + } + + static void extResolveContext(FrameLib_PDClass *x) + { + x->resolveContext(); + } + + static void extResolveConnections(FrameLib_PDClass *x, intptr_t *flag) + { + bool updated = x->resolveConnections(); + *flag = *flag || updated; + } + + static void extMarkUnresolved(FrameLib_PDClass *x) { - x->resolveConnections(); + x->mResolved = false; } - + static void extMakeAutoOrdering(FrameLib_PDClass *x) { x->mObject->makeAutoOrderingConnections(); @@ -1030,38 +1344,124 @@ class FrameLib_PDClass : public PDClass_Base x->mObject->clearAutoOrderingConnections(); } - static uintptr_t extIsConnected(FrameLib_PDClass *x, unsigned long index) + static void extReset(FrameLib_PDClass *x, const double *samplerate, intptr_t maxvectorsize) { - return x->confirmConnection(index, ConnectionInfo::Mode::kConfirm); + x->mObject->reset(*samplerate, static_cast(maxvectorsize)); } - static void extConnectionConfirm(FrameLib_PDClass *x, unsigned long index, FrameLib_PDGlobals::ConnectionInfo::Mode mode) + static void extConnectionUpdate(FrameLib_PDClass *x, intptr_t state) { - x->makeConnection(index, mode); + x->mConnectionsUpdated = state; } - static FrameLib_Multistream *extGetInternalObject(FrameLib_PDClass *x) + static FLObject *extGetFLObject(FrameLib_PDClass *x, uint64_t *version) { + *version = FrameLib_PDPrivate::version(); return x->mObject.get(); } - static uintptr_t extIsOutput(FrameLib_PDClass *x) + static t_object *extGetUserObject(FrameLib_PDClass *x) + { + return x->mUserObject; + } + + static void extConnectionConfirm(FrameLib_PDClass *x, unsigned long index, ConnectionMode mode) + { + x->makeConnection(index, mode); + } + + static intptr_t extIsDirectlyConnected(FrameLib_PDClass *x, unsigned long index) { - return x->handlesAudio() && (x->getNumAudioOuts() > 1); + return (intptr_t) x->mDirectlyConnected[index]; } - static uintptr_t extGetNumAudioIns(FrameLib_PDClass *x) + static intptr_t extGetNumAudioIns(FrameLib_PDClass *x) { return x->getNumAudioIns(); } - static uintptr_t extGetNumAudioOuts(FrameLib_PDClass *x) + static intptr_t extGetNumAudioOuts(FrameLib_PDClass *x) { return x->getNumAudioOuts(); } - + + // id attribute + /* + static void idSet(FrameLib_PDClass *x, t_object *attr, long argc, t_atom *argv) + { + x->mMaxContext.mName = argv ? atom_getsym(argv) : gensym(""); + x->updateContext(); + + return MAX_ERR_NONE; + } + + // rt attribute + + static void rtSet(FrameLib_PDClass *x, t_object *attr, long argc, t_atom *argv) + { + x->mMaxContext.mRealtime = argv ? (atom_getlong(argv) ? 1 : 0) : 0; + x->updateContext(); + + return MAX_ERR_NONE; + } + */ + private: + // Update the context if any of the pd context values have changed + + void updateContext() + { + if (mObject) + { + FrameLib_Context context = mGlobal->makeContext(mPDContext); + + if (context != mObject->getContext()) + { + mGlobal->addContextToResolve(context, *this); + matchContext(context, true); + } + + // N.B. release because otherwise it is retained twice + + mGlobal->releaseContext(context); + } + } + + // Attempt to match the context to a specified one + + void matchContext(FrameLib_Context context, bool force) + { + FrameLib_PDContext pdContext = mGlobal->getPDContext(context); + FrameLib_Context current = getContext(); + bool mismatchedPatch = mGlobal->getPDContext(current).mCanvas != pdContext.mCanvas; + + unsigned long size = 0; + + if ((!force && mismatchedPatch) || current == context) + return; + + mResolved = false; + + mGlobal->pushToQueue(*this); + + T *newObject = new T(context, mObject->getSerialised(), mProxy.get(), mSpecifiedStreams); + + for (unsigned long i = 0; i < mObject->getNumIns(); i++) + if (const double *values = mObject->getFixedInput(i, &size)) + newObject->setFixedInput(i, values, size); + + if (mGlobal->isRealtime(context) || mGlobal->isRealtime(current)) + dspSetBroken(); + + mPDContext = pdContext; + mGlobal->retainContext(context); + mGlobal->releaseContext(current); + mGlobal->flushErrors(context, *this); + + mObject.reset(newObject); + } + // Get an internal object from a generic pointer safely FrameLib_Multistream *getInternalObject(t_object *x) @@ -1071,50 +1471,79 @@ class FrameLib_PDClass : public PDClass_Base // Private connection methods - void iterateCanvas(t_glist *gl, t_symbol *method) + template + void iterateCanvas(t_glist *gl, t_symbol *method, Args...args) { - // Search for subpatchers, and call method on objects that don't have subpatchers + // Call method on all objects + + // FIX - revise for (t_gobj *g = gl->gl_list; g; g = g->g_next) - { - if (zgetfn((t_pd *) g, method)) - mess0((t_pd *) g, method); - } + objectMethod((t_object *) g, method, args...); } - - void resolveConnections() + + template + void traversePatch(const char *theMethodName, Args...args) { - if (mNeedsResolve) + t_symbol *theMethod = gensym(theMethodName); + + // Clear the queue and after traversing call objects added to the queue + + mGlobal->clearQueue(); + + iterateCanvas(mCanvas, theMethod, args...); + + while (t_object *object = mGlobal->popFromQueue()) + objectMethod(object, theMethodName, args...); + } + + bool resolveGraph(bool markUnresolved, bool forceRealtime = false) + { + if (!forceRealtime && isRealtime() && dspIsRunning()) + return false; + + intptr_t updated = false; + + mGlobal->setReportContextErrors(true); + traversePatch(FrameLib_PDPrivate::messageMarkUnresolved()); + traversePatch(FrameLib_PDPrivate::messageResolveConnections(), &updated); + traversePatch(FrameLib_PDPrivate::messageConnectionUpdate(), intptr_t(false)); + mGlobal->setReportContextErrors(false); + + // If updated then redo auto ordering connections + + if (updated) { - // Confirm input connections - - for (unsigned long i = 0; i < getNumIns(); i++) - confirmConnection(i, ConnectionInfo::Mode::kConfirm); - - // Confirm ordering connections - - for (unsigned long i = 0; i < getNumOrderingConnections(); i++) - confirmConnection(getOrderingConnection(i), getNumIns(), ConnectionInfo::Mode::kConfirm); - - // Make output connections - - for (unsigned long i = getNumOuts(); i > 0; i--) - makeConnection(i - 1, ConnectionInfo::Mode::kConnect); - - mNeedsResolve = false; + traversePatch(FrameLib_PDPrivate::messageClearAutoOrdering()); + traversePatch(FrameLib_PDPrivate::messageMakeAutoOrdering()); } + + if (markUnresolved) + traversePatch(FrameLib_PDPrivate::messageMarkUnresolved()); + + return updated; } - - void makeConnection(unsigned long index, ConnectionInfo::Mode mode) + + void resolveNRTGraph(double sampleRate, bool forceReset) { - ConnectionInfo info(*this, index, mode); + bool updated = resolveGraph(false); - mGlobal->setConnectionInfo(&info); - outlet_anything(mOutputs[index], gensym("frame"), 0, nullptr); - mGlobal->setConnectionInfo(); + if (updated || forceReset) + traversePatch(FrameLib_PDPrivate::messageReset(), &sampleRate, static_cast(maxBlockSize())); } - // Convert from framelib object to pd object and vice versa + void resolveContext() + { + if (isRealtime()) + resolveGraph(true); + else + { + LockHold lock(mGlobal->getLock(getContext())); + resolveNRTGraph(0.0, false); + } + } + + // Convert from framelib object to max object and vice versa static FLObject *toFLObject(t_object *x) { @@ -1126,15 +1555,15 @@ class FrameLib_PDClass : public PDClass_Base return object ? object->getProxy()->getOwner() : nullptr; } -// bool versionMismatch(t_object *object, long inIdx, bool report) const -// { -// bool mismatch = FrameLib_PDPrivate::versionMismatch(object); -// -// if (mismatch && report) -// mInputs[inIdx].reportError(mUserObject, Input::kVersion); -// -// return mismatch; -// } + bool versionMismatch(t_object *object, long inIdx, bool report) const + { + bool mismatch = FrameLib_PDPrivate::versionMismatch(object); + + if (mismatch && report) + mInputs[inIdx].reportError(mUserObject, Input::kVersion); + + return mismatch; + } // Get the number of audio ins/outs safely from a generic pointer @@ -1177,94 +1606,118 @@ class FrameLib_PDClass : public PDClass_Base // Private connection methods - bool confirmConnection(unsigned long inIndex, ConnectionInfo::Mode mode) + bool resolveConnections() { - if (!validInput(inIndex)) + if (mResolved) return false; + + // Confirm input connections - return confirmConnection(getConnection(inIndex), inIndex, mode); - } - - bool confirmConnection(PDConnection connection, unsigned long inIndex, ConnectionInfo::Mode mode) - { - if (!validInput(inIndex)) - return false; + for (long i = 0; i < getNumIns(); i++) + confirmConnection(i, ConnectionMode::kConfirm); - mConfirm = false; - mConfirmObject = connection.mObject; - mConfirmInIndex = inIndex; - mConfirmOutIndex = connection.mIndex; - - // Check for connection *only* if the internal object is connected (otherwise assume the previously connected object has been deleted) + // Confirm ordering connections + + for (long i = 0; i < getNumOrderingConnections(); i++) + confirmConnection(getOrderingConnection(i), getNumIns(), ConnectionMode::kConfirm); - if (mConfirmObject) - objectMethod(mConfirmObject, FrameLib_PDPrivate::messageConnectionConfirm(), mConfirmOutIndex, mode); + // Make output connections - if (mConfirmObject && !mConfirm) - disconnect(mConfirmObject, mConfirmOutIndex, mConfirmInIndex); + for (long i = getNumOuts(); i > 0; i--) + makeConnection(i - 1, ConnectionMode::kConnect); - bool result = mConfirm; - mConfirm = false; - mConfirmObject = nullptr; - mConfirmInIndex = mConfirmOutIndex = -1; + // Check if anything has updated since the last call to this method and make realtime resolved - return result; + bool updated = mConnectionsUpdated; + mConnectionsUpdated = false; + mResolved = true; + + return updated; + } + + void makeConnection(unsigned long index, ConnectionMode mode) + { + mGlobal->setConnection(PDConnection(*this, index)); + mGlobal->setConnectionMode(mode); + outlet_anything(mOutputs[index], gensym("frame"), 0, nullptr); + mGlobal->setConnection(PDConnection()); + } + + bool confirmConnection(unsigned long inIndex, ConnectionMode mode) + { + return confirmConnection(getConnection(inIndex), inIndex, mode); } - bool matchConnection(t_object *src, long outIdx, long inIdx) + bool confirmConnection(PDConnection connection, unsigned long inIndex, ConnectionMode mode) { - PDConnection connection = getConnection(inIdx); - return connection.mObject == src && connection.mIndex == outIdx; + if (!validInput(inIndex) || !connection.mObject) + return false; + + ConnectionConfirmation confirmation(connection, inIndex); + mConfirmation = &confirmation; + objectMethod(connection.mObject, FrameLib_PDPrivate::messageConnectionConfirm(), intptr_t(connection.mIndex), mode); + mConfirmation = nullptr; + + if (!confirmation.mConfirm) + disconnect(connection, inIndex); + + return confirmation.mConfirm; } - void connect(t_object *src, long outIdx, long inIdx) + void connect(PDConnection connection, long inIdx) { - FrameLib_Multistream *object = getInternalObject(src); + ConnectionResult result; + FLConnection internalConnection = toFLConnection(connection); - if (!isOrderingInput(inIdx) && (!validInput(inIdx) || !validOutput(outIdx, object) || matchConnection(src, outIdx, inIdx) || confirmConnection(inIdx, ConnectionInfo::Mode::kDoubleCheck))) + if (!(validOutput(connection.mIndex, internalConnection.mObject) && (isOrderingInput(inIdx) || (validInput(inIdx) && getConnection(inIdx) != connection && !confirmConnection(inIdx, ConnectionMode::kDoubleCheck))))) return; - - ConnectionResult result; + matchContext(internalConnection.mObject->getContext(), false); + if (isOrderingInput(inIdx)) - result = mObject->addOrderingConnection(FLConnection(object, outIdx)); + result = mObject->addOrderingConnection(internalConnection); else - result = mObject->addConnection(FLConnection(object, outIdx), inIdx); + result = mObject->addConnection(internalConnection, inIdx); switch (result) { + case ConnectionResult::Success: + mConnectionsUpdated = true; + objectMethod(connection.mObject, FrameLib_PDPrivate::messageConnectionUpdate(), intptr_t(true)); + break; + case ConnectionResult::FeedbackDetected: - pd_error(mUserObject, "feedback loop detected"); + mInputs[inIdx].reportError(mUserObject, Input::kFeedback); break; case ConnectionResult::WrongContext: - pd_error(mUserObject, "cannot connect objects from different top-level patchers"); + if (mGlobal->getReportContextErrors()) + mInputs[inIdx].reportError(mUserObject, Input::kContext); break; case ConnectionResult::SelfConnection: - pd_error(mUserObject, "direct feedback loop detected"); + mInputs[inIdx].reportError(mUserObject, Input::kDirect); break; - case ConnectionResult::Success: case ConnectionResult::NoOrderingSupport: case ConnectionResult::Aliased: break; } } - void disconnect(t_object *src, long outIdx, long inIdx) + void disconnect(PDConnection connection, long inIdx) { - FrameLib_Multistream *object = getInternalObject(src); - - if (!isOrderingInput(inIdx) && (!validInput(inIdx) || !matchConnection(src, outIdx, inIdx))) + if (!(isOrderingInput(inIdx) || (validInput(inIdx) && getConnection(inIdx) == connection))) return; if (isOrderingInput(inIdx)) - mObject->deleteOrderingConnection(FLConnection(object, outIdx)); + mObject->deleteOrderingConnection(toFLConnection(connection)); else mObject->deleteConnection(inIdx); + + mConnectionsUpdated = true; } - + // Info Utilities void postSplit(const char *text, const char *firstLineTag, const char *lineTag) @@ -1437,9 +1890,34 @@ class FrameLib_PDClass : public PDClass_Base } } + // Buffer access (read and write multichannel buffers) + + void read(t_symbol *buffer, double **outs, size_t numChans, size_t size, size_t offset) + { + // FIX + /* + PDBufferAccess access(*this, buffer); + + for (size_t i = 0; i < numChans; i++) + access.read(outs[i], size, offset, i); + */ + } + + void write(t_symbol *buffer, const double * const *ins, size_t numChans, size_t size, size_t offset) + { + // FIX + /* + PDBufferAccess access(*this, buffer); + + for (size_t i = 0; i < numChans; i++) + access.write(ins[i], size, offset, i); + */ + } protected: + MessageHandler *getHandler() { return mGlobal->getHandler(getContext()); } + // Proxy std::unique_ptr mProxy; @@ -1449,33 +1927,32 @@ class FrameLib_PDClass : public PDClass_Base // Data - N.B. - the order is crucial for safe deconstruction FrameLib_PDGlobals::ManagedPointer mGlobal; - FrameLib_PDGlobals::SyncCheck mSyncChecker; std::unique_ptr mObject; - std::vector mInputs; + std::vector mInputs; std::vector mOutputs; std::vector mSigIns; std::vector mSigOuts; std::vector mTemp; - long mProxyNum; - t_object *mConfirmObject; - long mConfirmInIndex; - long mConfirmOutIndex; - bool mConfirm; - t_glist *mCanvas; - t_object *mSyncIn; - unsigned long mSpecifiedStreams; + std::vector mDirectlyConnected; - bool mNeedsResolve; + ConnectionConfirmation *mConfirmation; -public: - t_object *mUserObject; + + unsigned long mSpecifiedStreams; + + bool mConnectionsUpdated; + bool mContextPatchConfirmed; + bool mResolved; + + t_symbol *mBuffer; + FrameLib_PDContext mPDContext; }; // Convenience for Objects Using FrameLib_Expand (use FrameLib_PDClass_Expand::makeClass() to create) From 8ccd44a4e20ed7100a8b52a29221d61269ef43ff Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 17:43:12 +0100 Subject: [PATCH 054/222] Remove unnecessary customisations --- framelib.xcodeproj/project.pbxproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/framelib.xcodeproj/project.pbxproj b/framelib.xcodeproj/project.pbxproj index 4f577c744..faaba9b12 100644 --- a/framelib.xcodeproj/project.pbxproj +++ b/framelib.xcodeproj/project.pbxproj @@ -18274,8 +18274,6 @@ B83E02AC206674D4005925DD /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_CXX_LIBRARY = "libc++"; COMBINE_HIDPI_IMAGES = YES; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_TRIGRAPHS = NO; @@ -18305,8 +18303,6 @@ B83E02AD206674D4005925DD /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_CXX_LIBRARY = "libc++"; COMBINE_HIDPI_IMAGES = YES; GCC_ENABLE_TRIGRAPHS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -18335,8 +18331,6 @@ B83E02AE206674D4005925DD /* Public Testing */ = { isa = XCBuildConfiguration; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; - CLANG_CXX_LIBRARY = "libc++"; COMBINE_HIDPI_IMAGES = YES; GCC_ENABLE_TRIGRAPHS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; From f7c0e07407835d20954da6d451bd4d0341ea93c0 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 20:33:58 +0100 Subject: [PATCH 055/222] Default flag value --- FrameLib_PD_Objects/Common/PDClass_Base.h | 1 + 1 file changed, 1 insertion(+) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index ac75d0235..215be1c9d 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -62,6 +62,7 @@ class PDClass_Base : mClock(this, (t_method) &call) , mMethod((IntMethod) fn) , mOwner(x) + , mFlag(false) {} void set() From 742d38eac453811c2620e0a7d17816cba68b6b8f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 21:38:31 +0100 Subject: [PATCH 056/222] Update makefile --- FrameLib_PD_Objects/makefile | 62 ++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index 398963cba..ec1f2584d 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -1,35 +1,41 @@ .SUFFIXES:.so OBJECTBASE=../FrameLib_Objects -VPATH = PD_Specific:\ ../FrameLib_Dependencies/tlsf - -FRAMELIBCPP= \ -$(wildcard ../FrameLib_Framework/FrameLib_*.cpp)\ -$(wildcard ../FrameLib_Objects/*/FrameLib_*.cpp)\ -../FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp - -FRAMELIBOBJ1=$(FRAMELIBCPP:.cpp=.o) tlsf.o -FRAMELIBOBJ=$(notdir $(FRAMELIBOBJ1)) - -FRAMELIBOBJINCLUDES= \ -$(patsubst %,-I%,$(sort $(dir $(wildcard ../FrameLib_Objects/*/)))) - -INCLUDEPATH=$(FRAMELIBOBJINCLUDES)\ - -IPD_Specific \ - -I../FrameLib_Dependencies \ - -I../FrameLib_Framework \ - -ICommon - -OBJS = framelib_pd.o - -OPTIM=-O3 +VPATH=PD_Specific:\ ../FrameLib_Dependencies/tlsf + +FL_CPP= \ + $(wildcard ../FrameLib_Framework/FrameLib_*.cpp)\ + $(wildcard ../FrameLib_Objects/*/FrameLib_*.cpp)\ + ../FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp + +FL_OBJ_DIR=$(FL_CPP:.cpp=.o) tlsf.o +FL_OBJ=$(notdir $(FL_OBJ_DIR)) + +INCLUDEPATH=\ + -IPD_Specific\ + -ICommon\ + -I../FrameLib_Dependencies\ + -I../FrameLib_Framework\ + -I$(OBJECTBASE)/Common_Utilities/ + +MAIN_OBJ=framelib_pd.o +OPTIMISATION=-O3 #OPT=-g -framelib_pd.d_fat: framelib_pd.o $(FRAMELIBOBJ1); \ - cc $(OPTIM) -arch i386 -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(OBJS) \ - $(FRAMELIBOBJ) -lstdc++ -lpthread - cp framelib_pd.d_fat /Users/alexharker/Documents/Pd/externals +DUMPMACHINE=$(shell cc -dumpmachine) +MACHINETYPE=$(word 2, $(subst -, , $(DUMPMACHINE))) + +framelib_pd.d_fat: $(MAIN_OBJ) $(FL_OBJ_DIR); +ifeq ($(MACHINETYPE), apple) + cc $(OPTIMISATION) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ + $(FL_OBJ) -lstdc++ -lpthread -framework Accelerate +else + cc $(OPTIMISATION) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ + $(FL_OBJ) -lstdc++ -lpthread +endif -.cpp.o:; g++ $(OPTIM) -arch i386 -arch x86_64 -std=c++11 -fPIC $(INCLUDEPATH) -c $< +%.o : %.cpp + g++ $(OPTIMISATION) -arch x86_64 -std=c++11 -fPIC $(INCLUDEPATH) -c $< -.c.o:; cc $(OPTIM) -arch i386 -arch x86_64 -fPIC $(INCLUDEPATH) -c $< +%.o : %.c + cc $(OPTIMISATION) -arch x86_64 -fPIC $(INCLUDEPATH) -c $< From ec136845a4c8615f4d1efd3404a14617e92413fd Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 21:41:10 +0100 Subject: [PATCH 057/222] Updat --- FrameLib_PD_Objects/makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index ec1f2584d..1c661735f 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -1,12 +1,14 @@ .SUFFIXES:.so -OBJECTBASE=../FrameLib_Objects +FL_FRAMEWORK=../FrameLib_Framework +FL_DEPENDENCIES=../FrameLib_Dependencies +FL_OBJECTS=../FrameLib_Objects VPATH=PD_Specific:\ ../FrameLib_Dependencies/tlsf FL_CPP= \ - $(wildcard ../FrameLib_Framework/FrameLib_*.cpp)\ - $(wildcard ../FrameLib_Objects/*/FrameLib_*.cpp)\ - ../FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp + $(wildcard $(FL_FRAMEWORK)/FrameLib_*.cpp)\ + $(wildcard $(FL_OBJECTS)/*/FrameLib_*.cpp)\ + $(FL_DEPENDENCIES)/HISSTools_FFT/HISSTools_FFT.cpp FL_OBJ_DIR=$(FL_CPP:.cpp=.o) tlsf.o FL_OBJ=$(notdir $(FL_OBJ_DIR)) @@ -14,8 +16,8 @@ FL_OBJ=$(notdir $(FL_OBJ_DIR)) INCLUDEPATH=\ -IPD_Specific\ -ICommon\ - -I../FrameLib_Dependencies\ - -I../FrameLib_Framework\ + -I$(FL_FRAMEWORK)\ + -I$(FL_DEPENDENCIES)\ -I$(OBJECTBASE)/Common_Utilities/ MAIN_OBJ=framelib_pd.o From 230d51a045f9c3270bd6ba0cebd482da7b4751e8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 31 Jul 2022 21:43:56 +0100 Subject: [PATCH 058/222] Fix makefile --- FrameLib_PD_Objects/makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index 1c661735f..666d656ce 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -13,22 +13,22 @@ FL_CPP= \ FL_OBJ_DIR=$(FL_CPP:.cpp=.o) tlsf.o FL_OBJ=$(notdir $(FL_OBJ_DIR)) -INCLUDEPATH=\ +INCLUDE_PATHS=\ -IPD_Specific\ -ICommon\ -I$(FL_FRAMEWORK)\ -I$(FL_DEPENDENCIES)\ - -I$(OBJECTBASE)/Common_Utilities/ + -I$(FL_OBJECTS)/Common_Utilities/ MAIN_OBJ=framelib_pd.o OPTIMISATION=-O3 #OPT=-g -DUMPMACHINE=$(shell cc -dumpmachine) -MACHINETYPE=$(word 2, $(subst -, , $(DUMPMACHINE))) +DUMP_MACHINE=$(shell cc -dumpmachine) +MACHINE_TYPE=$(word 2, $(subst -, , $(DUMP_MACHINE))) framelib_pd.d_fat: $(MAIN_OBJ) $(FL_OBJ_DIR); -ifeq ($(MACHINETYPE), apple) +ifeq ($(MACHINE_TYPE), apple) cc $(OPTIMISATION) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ $(FL_OBJ) -lstdc++ -lpthread -framework Accelerate else @@ -37,7 +37,7 @@ else endif %.o : %.cpp - g++ $(OPTIMISATION) -arch x86_64 -std=c++11 -fPIC $(INCLUDEPATH) -c $< + g++ $(OPTIMISATION) -arch x86_64 -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< %.o : %.c - cc $(OPTIMISATION) -arch x86_64 -fPIC $(INCLUDEPATH) -c $< + cc $(OPTIMISATION) -arch x86_64 -fPIC $(INCLUDE_PATHS) -c $< From 3f6b96ccecd27e164b5ae15b7c349d21d0c88512 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 00:06:40 +0100 Subject: [PATCH 059/222] Cleanup (ensure symbols are not reused) --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index e7526eee5..39d846ad7 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -72,7 +72,6 @@ struct FrameLib_PDPrivate static inline VersionString objectGlobal() { return "__fl.pd_global_items"; } static inline VersionString objectMessageHandler() { return "__fl.message.handler"; } - static inline VersionString objectMutator() { return "__fl.signal.mutator"; } static inline const char *messageGetUserObject() { return "__fl.get_user_object"; } static inline const char *messageUnwrap() { return "__fl.unwrap"; } @@ -652,7 +651,7 @@ class FrameLib_PDGlobals : public PDClass_Base static FrameLib_PDGlobals **getPDGlobalsPtr() { - return (FrameLib_PDGlobals **) &gensym("__fl.pd_global_items")->s_thing; + return (FrameLib_PDGlobals **) &FrameLib_PDPrivate::globalTag()->s_thing; } // Get and release the max global items (singleton) @@ -1462,13 +1461,6 @@ class FrameLib_PDClass : public PDClass_Base mObject.reset(newObject); } - // Get an internal object from a generic pointer safely - - FrameLib_Multistream *getInternalObject(t_object *x) - { - return objectMethod(x, "__fl.get_internal_object"); - } - // Private connection methods template From 279eb8435df769f85cbbc98f9e44dee5ec104c0a Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 00:06:52 +0100 Subject: [PATCH 060/222] Add a clean command --- FrameLib_PD_Objects/makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index 666d656ce..f9798adb8 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -41,3 +41,6 @@ endif %.o : %.c cc $(OPTIMISATION) -arch x86_64 -fPIC $(INCLUDE_PATHS) -c $< + +clean: + rm $(MAIN_OBJ) $(FL_OBJ) From 9f4fb272b42cafb0f2becd786a761d0f40e9ed16 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 01:01:46 +0100 Subject: [PATCH 061/222] Temporarily directly call the class creation method --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 39d846ad7..e0e919feb 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -558,7 +558,7 @@ class FrameLib_PDGlobals : public PDClass_Base std::get(*item) = key; std::get(*item) = 1; std::get(*item) = nullptr; - std::get(*item) = unique_pd_ptr(pd_new(*FrameLib_PDGlobals::getClassPointer())); + std::get(*item) = unique_pd_ptr((t_pd *)MessageHandler::create(nullptr, 0, nullptr)); std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); // Set timeouts @@ -688,7 +688,7 @@ class FrameLib_PDGlobals : public PDClass_Base { makeClass(maxGlobalClass); MessageHandler::makeClass(messageClassName); - x = (FrameLib_PDGlobals *) pd_new(*FrameLib_PDGlobals::getClassPointer()); + x = (FrameLib_PDGlobals *) FrameLib_PDGlobals::create(nullptr, 0, nullptr); *getPDGlobalsPtr() = x; } From fcbbc26c895166460cde669c3de27237e79281e1 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 08:43:35 +0100 Subject: [PATCH 062/222] Create classes by name --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 10 ++++++---- FrameLib_PD_Objects/Common/PDClass_Base.h | 12 ++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index e0e919feb..13241b3c9 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -551,14 +551,13 @@ class FrameLib_PDGlobals : public PDClass_Base if (!item) { - t_symbol *handlerSym = gensym(FrameLib_PDPrivate::objectMessageHandler()); item.reset(new RefData()); FrameLib_Context context(key.mRealtime ? mRTGlobal : mNRTGlobal, item.get()); std::get(*item) = key; std::get(*item) = 1; std::get(*item) = nullptr; - std::get(*item) = unique_pd_ptr((t_pd *)MessageHandler::create(nullptr, 0, nullptr)); + std::get(*item) = unique_pd_ptr((t_pd *) createNamed(FrameLib_PDPrivate::objectMessageHandler())); std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); // Set timeouts @@ -688,13 +687,16 @@ class FrameLib_PDGlobals : public PDClass_Base { makeClass(maxGlobalClass); MessageHandler::makeClass(messageClassName); - x = (FrameLib_PDGlobals *) FrameLib_PDGlobals::create(nullptr, 0, nullptr); - *getPDGlobalsPtr() = x; + *getPDGlobalsPtr() = x = (FrameLib_PDGlobals *) createNamed(maxGlobalClass); + post("Made global"); } + post("Retain global"); FrameLib_Global::get(&x->mRTGlobal, priorities(true), &x->mRTNotifier); FrameLib_Global::get(&x->mNRTGlobal, priorities(false), &x->mNRTNotifier); + post("Got Global %x %x %x", x, &x->mRTNotifier, &x->mNRTNotifier); + return x; } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 215be1c9d..1cc41a913 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -199,6 +199,18 @@ class PDClass_Base return static_cast(ret); } + // Create a named object from code + + static void *createNamed(const char *name) + { + typedef void *(*createFn)(t_symbol *, long, t_atom *); + + t_symbol *sym = gensym(name); + createFn createMethod = (createFn) getfn(&pd_objectmaker, sym); + + return (*createMethod)(sym, 0, nullptr); + } + // Static Methods for class initialisation, object creation and deletion template static t_class **getClassPointer() From e6d771dd1e66777fc91240aed8752aa05b0887c6 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 08:51:12 +0100 Subject: [PATCH 063/222] Add flags, and thus make internal objects non-patchable --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- FrameLib_PD_Objects/Common/PDClass_Base.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 13241b3c9..33c5b3786 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -685,8 +685,8 @@ class FrameLib_PDGlobals : public PDClass_Base if (!x) { - makeClass(maxGlobalClass); - MessageHandler::makeClass(messageClassName); + makeClass(maxGlobalClass, CLASS_PD); + MessageHandler::makeClass(messageClassName, CLASS_PD); *getPDGlobalsPtr() = x = (FrameLib_PDGlobals *) createNamed(maxGlobalClass); post("Made global"); } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 1cc41a913..c3ed9ddcb 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -228,11 +228,11 @@ class PDClass_Base } template - static void makeClass(const char *classname) + static void makeClass(const char *classname, int flags = 0) { t_class **C = getClassPointer(); - *C = class_new(gensym(classname), (t_newmethod)create, (t_method)destroy, sizeof(T), 0, A_GIMME, 0); + *C = class_new(gensym(classname), (t_newmethod)create, (t_method)destroy, sizeof(T), flags, A_GIMME, 0); T::classInit(*C, classname); *accessClassName() = std::string(classname); class_sethelpsymbol(*C, gensym(classname)); From 453ee4e755e9fbe58a71451f8ca2f759938d0e7a Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:00:10 +0100 Subject: [PATCH 064/222] Add facility to check if a class exists --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 19 +++++++------------ FrameLib_PD_Objects/Common/PDClass_Base.h | 9 ++++++++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 33c5b3786..cf608fe18 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -660,17 +660,14 @@ class FrameLib_PDGlobals : public PDClass_Base auto maxGlobalClass = FrameLib_PDPrivate::objectGlobal(); auto messageClassName = FrameLib_PDPrivate::objectMessageHandler(); - /* - t_symbol *globalTag = FrameLib_MaxPrivate::globalTag(); - - // Make sure the pd globals and message handler classes exist - - if (!class_findbyname(CLASS_NOBOX, gensym(maxGlobalClass))) - makeClass(CLASS_NOBOX, maxGlobalClass); - - if (!class_findbyname(CLASS_NOBOX, gensym(messageClassName))) - MessageHandler::makeClass(CLASS_NOBOX, messageClassName); + // Make sure the pd globals and message handler classes exist + if (!classExists(maxGlobalClass)) + makeClass(maxGlobalClass, CLASS_PD); + + if (!classExists(messageClassName)) + MessageHandler::makeClass(messageClassName, CLASS_PD); + /* // See if an object is registered (otherwise make object and register it...) FrameLib_MaxGlobals *x = (FrameLib_MaxGlobals *) object_findregistered(nameSpace, globalTag); @@ -685,8 +682,6 @@ class FrameLib_PDGlobals : public PDClass_Base if (!x) { - makeClass(maxGlobalClass, CLASS_PD); - MessageHandler::makeClass(messageClassName, CLASS_PD); *getPDGlobalsPtr() = x = (FrameLib_PDGlobals *) createNamed(maxGlobalClass); post("Made global"); } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index c3ed9ddcb..577de1cb8 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -199,8 +199,15 @@ class PDClass_Base return static_cast(ret); } - // Create a named object from code + // Check if a class exists or not + static bool classExists(const char *name) + { + return zgetfn(&pd_objectmaker, gensym(name)); + } + + // Create a named object from code + static void *createNamed(const char *name) { typedef void *(*createFn)(t_symbol *, long, t_atom *); From 22a107df493936f757986d35203f5b442ee2e78e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:26:26 +0100 Subject: [PATCH 065/222] Safely deal with symbols (using a default empty symbol) --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 18 +++++++++--------- FrameLib_PD_Objects/Common/PDClass_Base.h | 7 ++++++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index cf608fe18..3d4b78f19 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -923,7 +923,7 @@ class FrameLib_PDClass : public PDClass_Base static bool isTag(t_atom *a) { - t_symbol *sym = atom_getsymbol(a); + t_symbol *sym = atom_getsymbol_default(a); return atom_gettype(a) == A_SYMBOL && (isParameterTag(sym) || isInputTag(sym)); } @@ -1004,7 +1004,7 @@ class FrameLib_PDClass : public PDClass_Base while (ac--) { - t_symbol *type = atom_getsymbol(av++); + t_symbol *type = atom_getsymbol_default(av++); if (type == gensym("description")) flags |= kInfoDesciption; else if (type == gensym("inputs")) flags |= kInfoInputs; @@ -1748,7 +1748,7 @@ class FrameLib_PDClass : public PDClass_Base { if (atom_gettype(a) == A_SYMBOL) { - t_symbol *sym = atom_getsymbol(a); + t_symbol *sym = atom_getsymbol_default(a); if (strlen(sym->s_name) > 1 && sym->s_name[0] == '=') return safeCount(sym->s_name + 1, 1, 1024); @@ -1768,7 +1768,7 @@ class FrameLib_PDClass : public PDClass_Base values.push_back(atom_getfloat(argv + idx)); if (atom_gettype(argv + idx) == A_SYMBOL && !values.back()) - pd_error(mUserObject, "string %s in entry list where value expected", atom_getsymbol(argv + idx)->s_name); + pd_error(mUserObject, "string %s in entry list where value expected", atom_getsymbol_default(argv + idx)->s_name); } return idx; @@ -1787,7 +1787,7 @@ class FrameLib_PDClass : public PDClass_Base { if (atom_gettype(argv + i) == A_SYMBOL) { - t_symbol *str = atom_getsymbol(argv + i); + t_symbol *str = atom_getsymbol_default(argv + i); serialisedParameters.write(std::to_string(i).c_str(), str->s_name); } else @@ -1802,7 +1802,7 @@ class FrameLib_PDClass : public PDClass_Base while (i < argc) { - t_symbol *sym = atom_getsymbol(argv + i++); + t_symbol *sym = atom_getsymbol_default_default(argv + i++); if (isParameterTag(sym)) { @@ -1816,9 +1816,9 @@ class FrameLib_PDClass : public PDClass_Base // Add to parameters with stray item detection - if (atom_getsymbol(argv + i) != gensym("")) + if (atom_gettype(argv + i) == A_SYMBOL) { - serialisedParameters.write(sym->s_name + 1, atom_getsymbol(argv + i++)->s_name); + serialisedParameters.write(sym->s_name + 1, atom_getsymbol_default(argv + i++)->s_name); if (i < argc && !isTag(argv + i)) pd_error(mUserObject, "stray items after parameter %s", sym->s_name); @@ -1866,7 +1866,7 @@ class FrameLib_PDClass : public PDClass_Base while (i < argc) { - t_symbol *sym = atom_getsymbol(argv + i++); + t_symbol *sym = atom_getsymbol_default(argv + i++); if (isInputTag(sym)) { diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 577de1cb8..2a094bbdd 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -148,11 +148,16 @@ class PDClass_Base // Atom helpers - static t_atomtype atom_gettype(t_atom* a) + static t_atomtype atom_gettype(t_atom *a) { return a->a_type; } + static t_symbol *atom_getsymbol_default(t_atom *a) + { + return atom_gettype(a) == A_SYMBOL ? atom_getsymbol(a) : gensym(""); + } + static void atom_setfloat(t_atom *a, double v) { a->a_type = A_FLOAT; From fe3a5ff9bc6c79fb069aa17123a1ba6e9c3bf034 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:26:52 +0100 Subject: [PATCH 066/222] Fix previous commit (safe symbols) --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 3d4b78f19..fa1331ff5 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1802,7 +1802,7 @@ class FrameLib_PDClass : public PDClass_Base while (i < argc) { - t_symbol *sym = atom_getsymbol_default_default(argv + i++); + t_symbol *sym = atom_getsymbol_default(argv + i++); if (isParameterTag(sym)) { From 4ed8c9abf8a3a365db6c4f40920116945f495979 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:46:28 +0100 Subject: [PATCH 067/222] Typecast when creating named classes --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- FrameLib_PD_Objects/Common/PDClass_Base.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index fa1331ff5..8dbbf5b54 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -557,7 +557,7 @@ class FrameLib_PDGlobals : public PDClass_Base std::get(*item) = key; std::get(*item) = 1; std::get(*item) = nullptr; - std::get(*item) = unique_pd_ptr((t_pd *) createNamed(FrameLib_PDPrivate::objectMessageHandler())); + std::get(*item) = unique_pd_ptr(createNamed(FrameLib_PDPrivate::objectMessageHandler())); std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); // Set timeouts @@ -682,7 +682,7 @@ class FrameLib_PDGlobals : public PDClass_Base if (!x) { - *getPDGlobalsPtr() = x = (FrameLib_PDGlobals *) createNamed(maxGlobalClass); + *getPDGlobalsPtr() = x = createNamed(maxGlobalClass); post("Made global"); } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 2a094bbdd..55df958d7 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -213,14 +213,15 @@ class PDClass_Base // Create a named object from code - static void *createNamed(const char *name) + template + static T *createNamed(const char *name) { typedef void *(*createFn)(t_symbol *, long, t_atom *); t_symbol *sym = gensym(name); createFn createMethod = (createFn) getfn(&pd_objectmaker, sym); - return (*createMethod)(sym, 0, nullptr); + return reinterpret_cast((*createMethod)(sym, 0, nullptr)); } // Static Methods for class initialisation, object creation and deletion From bfbcbf9d77e929c3287d0d4d7b7270436008714b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:47:11 +0100 Subject: [PATCH 068/222] C++ style / formatting --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 2 +- FrameLib_Max_Objects/Common/MaxClass_Base.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 9eecb3a19..6f1da5155 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -694,7 +694,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base std::get(*item) = key; std::get(*item) = 1; std::get(*item) = nullptr; - std::get(*item) = unique_object_ptr((t_object *)object_new_typed(CLASS_NOBOX, handlerSym, 0, nullptr)); + std::get(*item) = unique_object_ptr((t_object *) object_new_typed(CLASS_NOBOX, handlerSym, 0, nullptr)); std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); // Set timeouts diff --git a/FrameLib_Max_Objects/Common/MaxClass_Base.h b/FrameLib_Max_Objects/Common/MaxClass_Base.h index 2c0a10da5..682015e0e 100644 --- a/FrameLib_Max_Objects/Common/MaxClass_Base.h +++ b/FrameLib_Max_Objects/Common/MaxClass_Base.h @@ -198,7 +198,7 @@ class MaxClass_Base static void *create(t_symbol *sym, long ac, t_atom *av) { void *x = object_alloc(*getClassPointer()); - new(x) T((t_object *)x, sym, ac, av); + new(x) T(reinterpret_cast(x), sym, ac, av); return x; } @@ -249,7 +249,7 @@ class MaxClass_Base // Allows type conversion to a t_object pointer - operator t_object* () { return (t_object *) this; } + operator t_object* () { return reinterpret_cast(this); } private: From e5575699bb7bf5a153e29b8230b356f55a7df06b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:47:26 +0100 Subject: [PATCH 069/222] Add comment --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 8dbbf5b54..519bb9c15 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1382,6 +1382,9 @@ class FrameLib_PDClass : public PDClass_Base } // id attribute + + // FIX - attributes + /* static void idSet(FrameLib_PDClass *x, t_object *attr, long argc, t_atom *argv) { From 58fe0d9d12ca5635080042cbd716364bf03f50a0 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:47:40 +0100 Subject: [PATCH 070/222] Formatting --- FrameLib_PD_Objects/Common/PDClass_Base.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 55df958d7..15e01dfc3 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -226,14 +226,16 @@ class PDClass_Base // Static Methods for class initialisation, object creation and deletion - template static t_class **getClassPointer() + template + static t_class **getClassPointer() { static t_class *C; return &C; } - template static std::string *accessClassName() + template + static std::string *accessClassName() { static std::string str; From 3abc6dcb24ad0a5fff43edc5c4230966b59d614e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 09:49:00 +0100 Subject: [PATCH 071/222] Improve type handling --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- FrameLib_PD_Objects/Common/PDClass_Base.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 519bb9c15..68ef521b7 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -502,7 +502,7 @@ class FrameLib_PDGlobals : public PDClass_Base , mNRTNotifier(&mNRTGlobal) , mRTGlobal(nullptr) , mNRTGlobal(nullptr) - , mQelem(*this, (t_method) &serviceContexts) + , mQelem(this, (t_method) &serviceContexts) {} // Max global item methods @@ -705,7 +705,7 @@ class FrameLib_PDGlobals : public PDClass_Base assert(!mNRTGlobal && "Reference counting error"); *getPDGlobalsPtr() = nullptr; - pd_free((t_pd *)this); + pd_free(*this); } } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 15e01dfc3..2b10104de 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -310,9 +310,10 @@ class PDClass_Base operator t_object&() { return mObject; } - // Allows type conversion to a t_object pointer + // Allows type conversion to a t_object or t_pd pointer - operator t_object* () { return (t_object *) this; } + operator t_object* () { return reinterpret_cast(this); } + operator t_pd* () { return &this->mObject.te_g.g_pd; } private: From fa252c7c4ae37b27767e34fadcef3ec4639070c5 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 10:41:13 +0100 Subject: [PATCH 072/222] Use pd binding to manage the globals object --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 40 ++++++++----------- FrameLib_PD_Objects/Common/PDClass_Base.h | 7 ++++ 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 68ef521b7..6c0ebf284 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -648,44 +648,38 @@ class FrameLib_PDGlobals : public PDClass_Base return FrameLib_Thread::defaultPriorities(); } - static FrameLib_PDGlobals **getPDGlobalsPtr() - { - return (FrameLib_PDGlobals **) &FrameLib_PDPrivate::globalTag()->s_thing; - } - // Get and release the max global items (singleton) static FrameLib_PDGlobals *get() { - auto maxGlobalClass = FrameLib_PDPrivate::objectGlobal(); + auto pdGlobalTag = FrameLib_PDPrivate::globalTag(); + auto pdGlobalClass = FrameLib_PDPrivate::objectGlobal(); auto messageClassName = FrameLib_PDPrivate::objectMessageHandler(); // Make sure the pd globals and message handler classes exist - if (!classExists(maxGlobalClass)) - makeClass(maxGlobalClass, CLASS_PD); + if (!classExists(pdGlobalClass)) + makeClass(pdGlobalClass, CLASS_PD); if (!classExists(messageClassName)) MessageHandler::makeClass(messageClassName, CLASS_PD); - /* - // See if an object is registered (otherwise make object and register it...) - - FrameLib_MaxGlobals *x = (FrameLib_MaxGlobals *) object_findregistered(nameSpace, globalTag); - - if (!x) - x = (FrameLib_MaxGlobals *) object_register(nameSpace, globalTag, object_new_typed(CLASS_NOBOX, gensym(maxGlobalClass), 0, nullptr)); - */ - // Make sure the pd globals class exists - - FrameLib_PDGlobals *x = *getPDGlobalsPtr(); + // Create a global to get the class name + + FrameLib_PDGlobals *y = createNamed(pdGlobalClass); + + // See if an object is already registered (and either free the new object or bind it...) + + FrameLib_PDGlobals *x = (FrameLib_PDGlobals *) pd_findbyclass(pdGlobalTag, objectName(*y)); if (!x) { - *getPDGlobalsPtr() = x = createNamed(maxGlobalClass); - post("Made global"); + x = y; + pd_bind(*x, pdGlobalTag); } - + else + pd_free(*y); + post("Retain global"); FrameLib_Global::get(&x->mRTGlobal, priorities(true), &x->mRTNotifier); FrameLib_Global::get(&x->mNRTGlobal, priorities(false), &x->mNRTNotifier); @@ -704,7 +698,7 @@ class FrameLib_PDGlobals : public PDClass_Base { assert(!mNRTGlobal && "Reference counting error"); - *getPDGlobalsPtr() = nullptr; + pd_unbind(*this, FrameLib_PDPrivate::globalTag()); pd_free(*this); } } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 2b10104de..c6605059a 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -224,6 +224,13 @@ class PDClass_Base return reinterpret_cast((*createMethod)(sym, 0, nullptr)); } + // Get a class pointer from an object + + static t_class *objectName(t_pd *pd) + { + return *pd; + } + // Static Methods for class initialisation, object creation and deletion template From 562a3e1d746e4046006722790a99b7894403ef4c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 10:43:09 +0100 Subject: [PATCH 073/222] Remove debug messages --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 6c0ebf284..09c03e6f7 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -680,12 +680,9 @@ class FrameLib_PDGlobals : public PDClass_Base else pd_free(*y); - post("Retain global"); FrameLib_Global::get(&x->mRTGlobal, priorities(true), &x->mRTNotifier); FrameLib_Global::get(&x->mNRTGlobal, priorities(false), &x->mNRTNotifier); - post("Got Global %x %x %x", x, &x->mRTNotifier, &x->mNRTNotifier); - return x; } From e147782df996d3c10e602b5762c5acd0a136bf9e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 1 Aug 2022 23:15:10 +0100 Subject: [PATCH 074/222] Correct calls to objectMethod --- FrameLib_PD_Objects/Common/PDClass_Base.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index c6605059a..bcfbb130a 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -192,7 +192,10 @@ class PDClass_Base { typedef void *(*t_fn5)(void *x, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5); - t_fn5 *m = (t_fn5 *) zgetfn((t_pd *) object, theMethod); + t_fn5 m = (t_fn5) zgetfn(&object->te_g.g_pd, theMethod); + + if (!m) + return static_cast(0); void *ret = (*m)(object, objectMethodArg(s), From 6b52aac138a97a66115fa5de8b65db61ff6d073d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 09:06:13 +0100 Subject: [PATCH 075/222] Add a really basic pd test --- Testing/02_PD/fl_test1.pd | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Testing/02_PD/fl_test1.pd diff --git a/Testing/02_PD/fl_test1.pd b/Testing/02_PD/fl_test1.pd new file mode 100644 index 000000000..bd1c7630d --- /dev/null +++ b/Testing/02_PD/fl_test1.pd @@ -0,0 +1,12 @@ +#N canvas 280 199 486 473 12; +#X obj 74 37 unsynced.fl.interval~ 4000; +#X obj 155 228 unsynced.fl.sink~; +#X obj 327 50 noise~; +#X obj 136 314 dac~; +#X obj 160 142 unsynced.fl.source~ /length 2000; +#X connect 0 0 4 0; +#X connect 0 1 4 2; +#X connect 1 1 3 0; +#X connect 2 0 4 1; +#X connect 4 0 1 0; +#X connect 4 1 1 1; From ffb52d1ca246d68d173f0bc0e256d127dd66a39f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 09:06:21 +0100 Subject: [PATCH 076/222] Add a to do for pd --- FrameLib_PD_Objects/PD_TO_DO.md | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 FrameLib_PD_Objects/PD_TO_DO.md diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md new file mode 100644 index 000000000..514d7b256 --- /dev/null +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -0,0 +1,49 @@ + +**Status and Building** + +- Currently most framelib objects get built to a single library files +- Host communication object (fl.topad~/fl.frompd~) currently need to be added. +- Realtime operation is supported, but non-realtime support is incomplete +- There are some key issues to note below + +To build you should be able to run make on this directory and then copy framelib_pd.d_fat and set it to load on startup + +Building *should* work on linux (it works on apple) but I've not tested. +I'm not sure if there should be a VS project for windows or not. + +**Testing** + +- I've started a test folder at Testing/02_PD/ with at least one simple demo +- Not the first outlet and inlet of unsynced objects are the sync IO + +**Key Issues** + +- *Audio synchronisation* - this is the main issue with finishing pd support and the Max approach won't work There +- Because audio inputs and outputs are in different objects they must process audio in the correct order +- In Max this is achieved by making these objects own subpatches with the actual object inside and making invisible audio connections to force the ordering +- At the moment in pd you get "unsynced" objects and must make these connections manually +- Miller suggesting making all outputs signal outputs, which would work but isn't nice and is wasteful +- My next step is to try to understand d_ugen.c better to see if there's another way + +- Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) +- At the moment you can't connect framelib objects between different subpatchers + +- Message ordering - If messages are send to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. + +- Attributes - non-realtime in Max is set by attributes. Part of the misssing support in pd is to sort these (which must be supported manually) +- My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. + +- Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good + +**Documentation** + +- Help files required (based on max help files) for each object +- Tutorials - consider if these should be translated somehow? +- Reference - I'm not sure if there is an equivalent to the reference system, or if the info message to framelib objects is sufficient + +**Build System and Distribution** + +- The makefile is very basic and currently builds 64 bit only +- Improve the makefile or build system to support all necessary platforms and OSes +- At the moment object files go into the main PD folder - I'd like them to go into a build directory but I don't know make well enough +- At the moment I suppress undefined symbols at link, but that means that if there was a non-pd-related link error it wouldn't be caught, so if something nicer is possible that would be good. From 91ef38f299ecf5b2892c2bd27103089aab896819 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 09:33:41 +0100 Subject: [PATCH 077/222] Improve pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 514d7b256..3089d2675 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -13,17 +13,17 @@ I'm not sure if there should be a VS project for windows or not. **Testing** -- I've started a test folder at Testing/02_PD/ with at least one simple demo -- Not the first outlet and inlet of unsynced objects are the sync IO +- I've started a test folder at Testing/02\_PD with at least one simple demo +- Note that the first outlet and inlet of unsynced objects are the sync IO **Key Issues** -- *Audio synchronisation* - this is the main issue with finishing pd support and the Max approach won't work There +- *Audio synchronisation* - this is the main issue with finishing pd support and the Max approach won't work here - Because audio inputs and outputs are in different objects they must process audio in the correct order - In Max this is achieved by making these objects own subpatches with the actual object inside and making invisible audio connections to force the ordering - At the moment in pd you get "unsynced" objects and must make these connections manually - Miller suggesting making all outputs signal outputs, which would work but isn't nice and is wasteful -- My next step is to try to understand d_ugen.c better to see if there's another way +- My next step is to try to understand d_ugen.c to understand how the dsp graph is built and if there is a better way - Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) - At the moment you can't connect framelib objects between different subpatchers @@ -35,6 +35,8 @@ I'm not sure if there should be a VS project for windows or not. - Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good +- Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful) + **Documentation** - Help files required (based on max help files) for each object From 81f0a652ef692f4bff547e9807026c0c3c78746f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 09:34:21 +0100 Subject: [PATCH 078/222] More pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 3089d2675..20c4ef955 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -2,7 +2,7 @@ **Status and Building** - Currently most framelib objects get built to a single library files -- Host communication object (fl.topad~/fl.frompd~) currently need to be added. +- Host communication objects (fl.topad~/fl.frompd~) and the context control objects (at least) currently need to be added. - Realtime operation is supported, but non-realtime support is incomplete - There are some key issues to note below From 2fb96606530761307d998798848f352f0fecaa4f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 10:08:25 +0100 Subject: [PATCH 079/222] More correct --- FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp b/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp index a6a7bf9ce..5bf7630d4 100644 --- a/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp +++ b/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp @@ -77,7 +77,7 @@ FrameLib_MaxClass_ToMax::FrameLib_MaxClass_ToMax(t_object *x, t_symbol *s, long mOutlets.resize(nStreams); for (unsigned long i = nStreams; i > 0; i--) - mOutlets[i - 1] = outlet_new(this, 0L); + mOutlets[i - 1] = outlet_new(*this, 0L); mHostProxy = static_cast(mProxy.get()); } From ef8ae234611a84d7761dfab2bb4382f0e8021e33 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 10:08:36 +0100 Subject: [PATCH 080/222] Add fl.topd~ --- FrameLib_PD_Objects/framelib_pd.cpp | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 8011f81c6..460bdfb1b 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -6,6 +6,58 @@ #include "pd_buffer.h" +// To PD Class + +class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand +{ + struct ToHostProxy : public FrameLib_ToHost::Proxy, public FrameLib_PDMessageProxy + { + ToHostProxy(FrameLib_PDClass_ToPD *object) + : FrameLib_PDMessageProxy(*object) + , mObject(object) + {} + + void sendToHost(unsigned long index, unsigned long stream, const double *values, unsigned long N, FrameLib_TimeFormat time) override + { + mObject->getHandler()->add(MessageInfo(this, time, stream), values, N); + } + + void sendToHost(unsigned long index, unsigned long stream, const FrameLib_Parameters::Serial *serial, FrameLib_TimeFormat time) override + { + mObject->getHandler()->add(MessageInfo(this, time, stream), serial); + } + + void sendMessage(unsigned long stream, t_symbol *s, short ac, t_atom *av) override; + + private: + + FrameLib_PDClass_ToPD *mObject; + }; + +public: + + // Constructor + + FrameLib_PDClass_ToPD(t_object *x, t_symbol *s, long argc, t_atom *argv) + { + unsigned long nStreams = getSpecifiedStreams(); + + mOutlets.resize(nStreams); + + for (unsigned long i = nStreams; i > 0; i--) + mOutlets[i - 1] = outlet_new(*this, 0L); + + mHostProxy = static_cast(mProxy.get()); + } + +private: + + // Data + + ToHostProxy *mHostProxy; + std::vector mOutlets; +}; + // PD Read Class class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand @@ -187,6 +239,10 @@ struct FrameLib_PDClass_ComplexExpression : public FrameLib_PDClass_ComplexExpre extern "C" void framelib_pd_setup(void) { + // Host Communication + + FrameLib_PDClass_ToPD::makeClass("fl.topd~"); + // Filters FrameLib_PDClass_Expand::makeClass("fl.biquad~"); From c10b3cb6a9ed731b52f1b1207c4d1a3b11c89cf5 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 10:09:50 +0100 Subject: [PATCH 081/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 20c4ef955..5c4bf06fe 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -1,8 +1,8 @@ **Status and Building** -- Currently most framelib objects get built to a single library files -- Host communication objects (fl.topad~/fl.frompd~) and the context control objects (at least) currently need to be added. +- Currently most (161 out of 163) framelib objects get built to a single library files +- The fl.frompd~ and fl.contextcontrol~ objects currently need to be added. - Realtime operation is supported, but non-realtime support is incomplete - There are some key issues to note below From 2676d289dd98a0a1b67d90d2c0e7125cad1947d8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 10:11:17 +0100 Subject: [PATCH 082/222] Fix constructor --- FrameLib_PD_Objects/framelib_pd.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 460bdfb1b..f1623c081 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -39,6 +39,7 @@ class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand // Constructor FrameLib_PDClass_ToPD(t_object *x, t_symbol *s, long argc, t_atom *argv) + : FrameLib_PDClass(x, s, argc, argv, new ToHostProxy(this)) { unsigned long nStreams = getSpecifiedStreams(); From 7668722ce00a5eb9958f6048a56477433329df49 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 10:17:46 +0100 Subject: [PATCH 083/222] Add missing method --- FrameLib_PD_Objects/framelib_pd.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index f1623c081..8890c96ce 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -27,7 +27,20 @@ class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand mObject->getHandler()->add(MessageInfo(this, time, stream), serial); } - void sendMessage(unsigned long stream, t_symbol *s, short ac, t_atom *av) override; + void sendMessage(unsigned long stream, t_symbol *s, short ac, t_atom *av) override + { + auto& outlets = mObject->mOutlets; + unsigned long idx = stream % outlets.size(); + + if (s) + outlet_anything(outlets[idx], s, ac, av); + else if (!ac) + outlet_bang(outlets[idx]); + else if (ac == 1) + outlet_float(outlets[idx], atom_getfloat(av)); + else + outlet_list(outlets[idx], nullptr, ac, av); + } private: From b30ec03c4676f3979729bf404743168ecce0e9c3 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 12:17:53 +0100 Subject: [PATCH 084/222] Add fl.contextcontrol~ to pd --- FrameLib_PD_Objects/framelib_pd.cpp | 143 ++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 8890c96ce..9e514dddc 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -1,11 +1,150 @@ #include "FrameLib_PDClass.h" #include "../FrameLib_Exports/FrameLib_Objects.h" +#include "../FrameLib_Exports/FrameLib_TypeAliases.h" // Buffer #include "pd_buffer.h" +// Context Control - A pd class to communicate with the current pd + +class FrameLib_PDClass_ContextControl : public PDClass_Base +{ + using PDClass = FrameLib_PDClass; + +public: + + static void classInit(t_class *c, const char *classname) + { + addMethod(c, "multithread"); + + class_addmethod(c, (t_method) &extTimeOut, gensym("timeout"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(c, (t_method) &extCodeExport, gensym("export"), A_SYMBOL, A_SYMBOL, 0); + } + + FrameLib_PDClass_ContextControl(t_object *x, t_symbol *sym, long argc, t_atom *argv) + : mPDContext{ true, canvas_getcurrent(), gensym("") } + , mContext(mGlobal->makeContext(mPDContext)) + { + } + + ~FrameLib_PDClass_ContextControl() + { + mGlobal->releaseContext(mContext); + } + + // Attributes + + // id attribute + /* + static t_max_err idSet(FrameLib_PDClass_ContextControl *x, t_object *attr, long argc, t_atom *argv) + { + x->mMaxContext.mName = argv ? atom_getsym(argv) : gensym(""); + + return MAX_ERR_NONE; + } + + // rt attribute + + static t_max_err rtSet(FrameLib_PDClass_ContextControl *x, t_object *attr, long argc, t_atom *argv) + { + x->mMaxContext.mRealtime = argv ? (atom_getlong(argv) ? 1 : 0) : 0; + + return MAX_ERR_NONE; + }*/ + + // Time out + + static void extTimeOut(FrameLib_PDClass_ContextControl *x, double relative, double absolute) + { + x->timeOut(relative, absolute); + } + + // Export + + static void extCodeExport(FrameLib_PDClass_ContextControl *x, t_symbol *className, t_symbol *path) + { + x->codeExport(className, path); + } + +private: + + // Multithreading + + void multithread(double on) + { + FrameLib_Context::ProcessingQueue processingQueue(mContext); + processingQueue->setMultithreading(on); + } + + // Time out + + void timeOut(double relative, double absolute) + { + FrameLib_Context::ProcessingQueue processingQueue(mContext); + processingQueue->setTimeOuts(relative / 100.0, absolute / 1000.0); + } + + // Export + + void codeExport(t_symbol *className, t_symbol *path) + { + // Get the first object and its underlying framelib object + + t_object *object = searchPatch(mPDContext.mCanvas); + FrameLib_Multistream *flObject = toFLObject(object); + + if (!object || !flObject) + { + pd_error(this, "couldn't find any framelib objects in the current context"); + return; + } + + objectMethod(object, FrameLib_PDPrivate::messageResolveContext()); + + auto replace = FrameLib_TypeAliases::makeReplaceStrings(); + + // FIX - should we deal with search paths etc.? + + ExportError error = exportGraph(flObject, path->s_name, className->s_name, &replace); + + if (error == ExportError::PathError) + pd_error(this, "couldn't write to or find specified path"); + else if (error == ExportError::WriteError) + pd_error(this, "couldn't write file"); + } + + // Convert an object to an FLObject + + FrameLib_Multistream *toFLObject(t_object *x) + { + return FrameLib_PDPrivate::toFrameLibObject(x); + } + + t_object *searchPatch(t_glist *gl) + { + // Call method on all objects + + // FIX - revise + + for (t_gobj *g = gl->gl_list; g; g = g->g_next) + { + FrameLib_Multistream *flObject = toFLObject((t_object *) g); + if (flObject && flObject->getContext() == mContext) + return (t_object *) g; + } + + return nullptr; + } + + // Members + + FrameLib_PDGlobals::ManagedPointer mGlobal; + FrameLib_PDContext mPDContext; + FrameLib_Context mContext; +}; + // To PD Class class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand @@ -253,6 +392,10 @@ struct FrameLib_PDClass_ComplexExpression : public FrameLib_PDClass_ComplexExpre extern "C" void framelib_pd_setup(void) { + // Context Control + + FrameLib_PDClass_ContextControl::makeClass("fl.contextcontrol~"); + // Host Communication FrameLib_PDClass_ToPD::makeClass("fl.topd~"); From a30841134f711c569b059e5a5b72166b9d9cdd5a Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 12:18:00 +0100 Subject: [PATCH 085/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 5c4bf06fe..547385481 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -1,8 +1,8 @@ **Status and Building** -- Currently most (161 out of 163) framelib objects get built to a single library files -- The fl.frompd~ and fl.contextcontrol~ objects currently need to be added. +- Currently most (162 out of 163) framelib objects get built to a single library files +- The fl.frompd~ currently need to be added. - Realtime operation is supported, but non-realtime support is incomplete - There are some key issues to note below @@ -37,6 +37,15 @@ I'm not sure if there should be a VS project for windows or not. - Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful) +**Review** + +- Some pd correctness needs review: + - PD-specific or custom objects (read/info/topd/frompd/contextcontrol/expressions) + - Float arguments (t_floatarg?) + - Messages that would take ints in Max + - Assist strings? + - resetting dsp when resolving connections + **Documentation** - Help files required (based on max help files) for each object From adac4d50e94362f9ec816bdc91caad7fb08ce546 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 12:25:21 +0100 Subject: [PATCH 086/222] Add fl.frompd~ --- FrameLib_PD_Objects/framelib_pd.cpp | 73 +++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 9e514dddc..1aa49acff 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -211,6 +211,78 @@ class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand std::vector mOutlets; }; +// From PD Class + +class FrameLib_PDClass_FromPD : public FrameLib_PDClass_Expand +{ + struct FromHostProxy : public FrameLib_FromHost::Proxy, public FrameLib_PDProxy + { + FromHostProxy(t_object *x) + : FrameLib_FromHost::Proxy(true, true) + , FrameLib_PDProxy(x) {} + }; + +public: + + // Class Initialisation + + static void classInit(t_class *c, const char *classname) + { + FrameLib_PDClass::classInit(c, classname); + + addMethod(c, "float"); + addMethod(c, "list"); + addMethod(c, "anything"); + } + + // Constructor + + FrameLib_PDClass_FromPD(t_object *x, t_symbol *s, long argc, t_atom *argv) + : FrameLib_PDClass(x, s, argc, argv, new FromHostProxy(x)) + { + mHostProxy = static_cast(mProxy.get()); + } + + // Additional handlers + + void floatHandler(double in) + { + mHostProxy->sendFromHost(0, &in, 1); + } + + void list(t_symbol *s, long argc, t_atom *argv) + { + std::vector temporary(argc); + + for (long i = 0; i < argc; i++) + temporary[i] = atom_getfloat(argv++); + + mHostProxy->sendFromHost(0, temporary.data(), argc); + } + + void anything(t_symbol *s, long argc, t_atom *argv) + { + if (argc > 1 && atom_gettype(argv) == A_SYMBOL) + pd_error(this, "too many arguments for string value"); + + if (argc && atom_gettype(argv) == A_SYMBOL) + mHostProxy->sendFromHost(0, s->s_name, atom_getsymbol_default(argv)->s_name); + else + { + std::vector temporary(argc); + + for (long i = 0; i < argc; i++) + temporary[i] = atom_getfloat(argv++); + + mHostProxy->sendFromHost(0, s->s_name, temporary.data(), argc); + } + } + +private: + + FromHostProxy *mHostProxy; +}; + // PD Read Class class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand @@ -399,6 +471,7 @@ extern "C" void framelib_pd_setup(void) // Host Communication FrameLib_PDClass_ToPD::makeClass("fl.topd~"); + FrameLib_PDClass_ToPD::makeClass("fl.frompd~"); // Filters From 54d2b47a88c09710710ce213b451f82a66e104f7 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 12:26:21 +0100 Subject: [PATCH 087/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 547385481..219ee70e9 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -1,8 +1,7 @@ **Status and Building** -- Currently most (162 out of 163) framelib objects get built to a single library files -- The fl.frompd~ currently need to be added. +- All (163 out of 163) framelib objects get built to a single library files - Realtime operation is supported, but non-realtime support is incomplete - There are some key issues to note below From 8b4423f353c22846d8e7ff3abb8e042862962f18 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 14:45:34 +0100 Subject: [PATCH 088/222] Turn off dynamic contexts as they are broken in pd --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 09c03e6f7..e102da0ee 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -929,7 +929,9 @@ class FrameLib_PDClass : public PDClass_Base , mConnectionsUpdated(false) , mContextPatchConfirmed(false) , mResolved(false) - , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } + , mPDContext{ true, mCanvas, gensym("") } +// FIX + // , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } { // Stream count From 5a43905d0f60c5e111e619f7dc21203051e75091 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 16:06:47 +0100 Subject: [PATCH 089/222] Improve makefile (turn off asserts for now) --- FrameLib_PD_Objects/makefile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index f9798adb8..850e88a98 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -22,6 +22,10 @@ INCLUDE_PATHS=\ MAIN_OBJ=framelib_pd.o OPTIMISATION=-O3 + +CPPFLAGS+=-DNDEBUG +CFLAGS+=$(OPTIMISATION) +CXXFLAGS+=$(OPTIMISATION) #OPT=-g DUMP_MACHINE=$(shell cc -dumpmachine) @@ -29,18 +33,18 @@ MACHINE_TYPE=$(word 2, $(subst -, , $(DUMP_MACHINE))) framelib_pd.d_fat: $(MAIN_OBJ) $(FL_OBJ_DIR); ifeq ($(MACHINE_TYPE), apple) - cc $(OPTIMISATION) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ + cc $(CPPFLAGS) $(CXXFLAGS) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ $(FL_OBJ) -lstdc++ -lpthread -framework Accelerate else - cc $(OPTIMISATION) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ + cc$(CPPFLAGS) $(CXXFLAGS) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ $(FL_OBJ) -lstdc++ -lpthread endif %.o : %.cpp - g++ $(OPTIMISATION) -arch x86_64 -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< + g++ $(CPPFLAGS) $(CXXFLAGS) -arch x86_64 -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< %.o : %.c - cc $(OPTIMISATION) -arch x86_64 -fPIC $(INCLUDE_PATHS) -c $< + cc $(CPPFLAGS) $(CFLAGS) -arch x86_64 -fPIC $(INCLUDE_PATHS) -c $< clean: rm $(MAIN_OBJ) $(FL_OBJ) From ea641c329bb7ca9728b45838b2a232fdd58c01a0 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 17:15:43 +0100 Subject: [PATCH 090/222] Revert "Turn off dynamic contexts as they are broken in pd" This reverts commit 8b4423f353c22846d8e7ff3abb8e042862962f18. --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index e102da0ee..09c03e6f7 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -929,9 +929,7 @@ class FrameLib_PDClass : public PDClass_Base , mConnectionsUpdated(false) , mContextPatchConfirmed(false) , mResolved(false) - , mPDContext{ true, mCanvas, gensym("") } -// FIX - // , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } + , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } { // Stream count From f52d6b616c8578511adebb5466fca37842b3ea06 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 17:16:30 +0100 Subject: [PATCH 091/222] Allow realtime reporting of DSP timing errors (rather than using asserts) as an option (for pd debug) --- FrameLib_Framework/FrameLib_DSP.cpp | 40 +++++++++++++++++------------ FrameLib_PD_Objects/makefile | 4 +-- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/FrameLib_Framework/FrameLib_DSP.cpp b/FrameLib_Framework/FrameLib_DSP.cpp index ea2f3f06f..422ee8e57 100644 --- a/FrameLib_Framework/FrameLib_DSP.cpp +++ b/FrameLib_Framework/FrameLib_DSP.cpp @@ -1,6 +1,14 @@ #include "FrameLib_DSP.h" +// N.B. define FRAMELIB_RT_DSP_CHECK to report on timing errors in realtime rather than asserting (debug) or removing the tests (release) + +#ifdef FRAMELIB_RT_DSP_CHECK +#define debug_rt_check(e, str) if (!(e)) getReporter()(ErrorSource::DSP, getProxy(), str); +#else +#define debug_rt_check(e, str) assert(e && str); +#endif + // Constructor / Destructor FrameLib_DSP::FrameLib_DSP(ObjectType type, FrameLib_Context context, FrameLib_Proxy *proxy, FrameLib_Parameters::Info *info, unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans) @@ -362,7 +370,7 @@ void FrameLib_DSP::dependencyNotify(NotificationType type, NotificationQueue& qu if (mProcessingQueue->isTimedOut()) return; - assert(((mDependencyCount > 0) || (mUpdatingInputs && (mInputCount > 0))) && "Dependency count is already zero"); + debug_rt_check(((mDependencyCount > 0) || (mUpdatingInputs && (mInputCount > 0))), "Dependency count is already zero"); if (allocator && mOutputDone) releaseOutputMemory(allocator); @@ -373,7 +381,7 @@ void FrameLib_DSP::dependencyNotify(NotificationType type, NotificationQueue& qu { // N.B. Avoid re-entrancy by increasing the relevant dependency counts before processing (plus matched notifications) - assert((mDependencyCount > 0) || !mUpdatingInputs && "Dependency count shouldn't be zero if updating inputs"); + debug_rt_check((mDependencyCount > 0) || !mUpdatingInputs, "Dependency count shouldn't be zero if updating inputs"); mDependencyCount++; mInputCount++; @@ -381,8 +389,8 @@ void FrameLib_DSP::dependencyNotify(NotificationType type, NotificationQueue& qu queue.push(this); } - assert(mDependencyCount >= 0 && "Dependency count shouldn't be negative"); - assert(mInputCount >= 0 && "Input count shouldn't be negative"); + debug_rt_check(mDependencyCount >= 0, "Dependency count shouldn't be negative"); + debug_rt_check(mInputCount >= 0, "Input count shouldn't be negative"); } // For updating the correct input count @@ -401,7 +409,7 @@ void FrameLib_DSP::dependenciesReady(NotificationQueue& queue, LocalAllocator *a { setLocalAllocator(allocator); -#ifndef NDEBUG +#if !(defined NDEBUG) || (defined FRAMELIB_RT_DSP_CHECK) const FrameLib_TimeFormat inputTime = mInputTime; #endif @@ -585,17 +593,17 @@ void FrameLib_DSP::dependenciesReady(NotificationQueue& queue, LocalAllocator *a for (auto it = mOutputDependencies.begin(); it != mOutputDependencies.end(); it++) (*it)->dependencyNotify(NotificationType::Input, queue); - // Debug (before re-entering) + // Debug (before re-entering) - N.B. may be done as an error or an assert + + debug_rt_check(!needsAudioNotification() || (inputTime >= mBlockStartTime), "Object behind host"); + debug_rt_check(!needsAudioNotification() || (inputTime < mBlockEndTime), "Object ahead of host"); + debug_rt_check(mInputTime > inputTime, "Failed to move time forward"); + debug_rt_check(mInputTime <= mValidTime, "Input is ahead of output"); + debug_rt_check(mFrameTime <= mInputTime, "Output is ahead of input"); + debug_rt_check(mDependencyCount >= 1, "Dependency count shouldn't be less than 1"); + debug_rt_check(mUpdatingInputs || endOfTime || mInputCount == 0, "Input count should be 0"); + debug_rt_check(!mUpdatingInputs || mInputCount >= 1, "Input count shouldn't be less than 1"); - assert(!needsAudioNotification() || (inputTime >= mBlockStartTime) && "Object behind host"); - assert(!needsAudioNotification() || (inputTime < mBlockEndTime) && "Object ahead of host"); - assert(mInputTime > inputTime && "Failed to move time forward"); - assert(mInputTime <= mValidTime && "Input is ahead of output"); - assert(mFrameTime <= mInputTime && "Output is ahead of input"); - assert(mDependencyCount >= 1 && "Dependency count shouldn't be less than 1"); - assert(mUpdatingInputs || endOfTime || mInputCount == 0 && "Input count should be 0"); - assert(!mUpdatingInputs || mInputCount >= 1 && "Input count shouldn't be less than 1"); - // After resolving all other dependencies do self-notifications allowing self triggering if (!endOfTime) @@ -640,7 +648,7 @@ inline void FrameLib_DSP::freeOutputMemory(LocalAllocator *allocator) inline void FrameLib_DSP::releaseOutputMemory(LocalAllocator *allocator) { - assert(mOutputMemoryCount > 0 && "Output memory count is already zero"); + debug_rt_check(mOutputMemoryCount > 0, "Output memory count is already zero"); if (--mOutputMemoryCount == 0) freeOutputMemory(allocator); diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index 850e88a98..f46111a01 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -23,9 +23,7 @@ INCLUDE_PATHS=\ MAIN_OBJ=framelib_pd.o OPTIMISATION=-O3 -CPPFLAGS+=-DNDEBUG -CFLAGS+=$(OPTIMISATION) -CXXFLAGS+=$(OPTIMISATION) +CPPFLAGS+=-DNDEBUG -DFRAMELIB_RT_DSP_CHECK #OPT=-g DUMP_MACHINE=$(shell cc -dumpmachine) From d8abc586c2724f6c6027a229dfab5903274200df Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 17:21:40 +0100 Subject: [PATCH 092/222] Fix makefile --- FrameLib_PD_Objects/makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index f46111a01..be41df810 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -23,6 +23,8 @@ INCLUDE_PATHS=\ MAIN_OBJ=framelib_pd.o OPTIMISATION=-O3 +CFLAGS+=$(OPTIMISATION) +CXXFLAGS+=$(OPTIMISATION) CPPFLAGS+=-DNDEBUG -DFRAMELIB_RT_DSP_CHECK #OPT=-g From bac63a356bccefa5406f7928e2efdffd4d9bb845 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 17:26:37 +0100 Subject: [PATCH 093/222] Add a stereo granular example --- Testing/02_PD/fl_test2.pd | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Testing/02_PD/fl_test2.pd diff --git a/Testing/02_PD/fl_test2.pd b/Testing/02_PD/fl_test2.pd new file mode 100644 index 000000000..d4fea5369 --- /dev/null +++ b/Testing/02_PD/fl_test2.pd @@ -0,0 +1,78 @@ +#N canvas 316 325 1076 735 12; +#X obj 81 551 unsynced.fl.sink~; +#X obj 227 550 unsynced.fl.sink~; +#X obj 193 610 *~ 0.2; +#X obj 336 601 *~ 0.2; +#X obj 188 653 dac~; +#X obj 136 513 fl.*~; +#X obj 285 511 fl.*~; +#X obj 167 480 fl.cos~; +#X obj 312 479 fl.sin~; +#X obj 132 424 fl.window~ hann /size 16384; +#X obj 132 351 fl.read~ samps /units ms; +#X obj 134 311 fl.+~; +#X obj 134 279 fl.samplerate~ samples->ms; +#X obj 128 244 fl.ramp~ /mode requested /length 1000; +#X obj 116 79 fl.random~; +#X obj 371 79 fl.random~; +#X obj 549 78 fl.random~; +#X obj 118 123 fl.map~ linear 0 1 10000 20000; +#X obj 550 115 fl.map~ exp 0 1 20 16000; +#X obj 768 79 fl.random~; +#X obj 770 114 fl.*~ 1.5708; +#X obj 118 173 fl.tag~ length; +#X obj 131 382 fl.svf~ 500 0.7 bandpass; +#X obj 542 166 fl.tag~ freq; +#X obj 658 359 soundfiler; +#X floatatom 658 385 0 0 0 0 - - - 0; +#X obj 658 297 loadbang; +#X msg 658 327 read -resize voice.wav samps; +#X text 515 467 This patch is the same as the stero granular (2b) example +from the Max tests. Note that the interla pd sounds folder needs to +be in the search path; +#X obj 904 343 table samps; +#X floatatom 430 594 5 0 0 0 - - - 0; +#X obj 432 569 bng 15 250 50 0 empty empty empty 17 7 0 10 #fcfcfc +#000000 #000000; +#X obj 404 538 fl.topd~ =4; +#X obj 372 123 fl.*~ 1000; +#X obj 99 21 unsynced.fl.interval~ 50; +#X connect 0 1 2 0; +#X connect 1 1 3 0; +#X connect 2 0 4 0; +#X connect 3 0 4 1; +#X connect 5 0 0 1; +#X connect 6 0 1 1; +#X connect 7 0 5 1; +#X connect 8 0 6 1; +#X connect 8 0 32 0; +#X connect 9 0 5 0; +#X connect 9 0 6 0; +#X connect 10 0 22 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 12 0; +#X connect 14 0 17 0; +#X connect 15 0 33 0; +#X connect 16 0 18 0; +#X connect 17 0 21 0; +#X connect 18 0 23 0; +#X connect 19 0 20 0; +#X connect 20 0 7 0; +#X connect 20 0 8 0; +#X connect 21 0 13 1; +#X connect 22 0 9 0; +#X connect 23 0 22 1; +#X connect 24 0 25 0; +#X connect 26 0 27 0; +#X connect 27 0 24 0; +#X connect 32 0 30 0; +#X connect 32 0 31 0; +#X connect 33 0 11 1; +#X connect 34 0 0 0; +#X connect 34 0 1 0; +#X connect 34 1 14 0; +#X connect 34 1 15 0; +#X connect 34 1 16 0; +#X connect 34 1 19 0; +#X connect 34 1 13 0; From ffa6de12b7320b886eeda539a4fc1e504e991712 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 18:15:33 +0100 Subject: [PATCH 094/222] Correct pd use of flat arguments and use idiomatic class adders for simple methods --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 4 ++-- FrameLib_PD_Objects/Common/PDClass_Base.h | 19 ++++++++++--------- FrameLib_PD_Objects/framelib_pd.cpp | 15 ++++++++------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 09c03e6f7..5a698df4d 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1184,7 +1184,7 @@ class FrameLib_PDClass : public PDClass_Base static unsigned long maxBlockSize() { return 16384UL; } - void reset(def_double sampleRate = 0.0) + void reset(t_deffloatarg sampleRate = 0.0) { if (!isRealtime()) { @@ -1193,7 +1193,7 @@ class FrameLib_PDClass : public PDClass_Base } } - void process(double length) + void process(t_floatarg length) { unsigned long updateLength = length > 0 ? static_cast(length) : 0UL; unsigned long time = static_cast(mObject->getBlockTime()) - 1UL; diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index bcfbb130a..b2292f299 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -30,7 +30,7 @@ class PDClass_Base // Types for defining methods with DEFLONG or DEFFLOAT arguments //using def_int = DefaultArg; - using def_double = DefaultArg; + using t_deffloatarg = DefaultArg; // Unique pointers to t_objects @@ -103,11 +103,11 @@ class PDClass_Base template ::MethodGimme F> static void call(T *x, t_symbol *s, long ac, t_atom *av) {((x)->*F)(s, ac, av); }; template ::MethodGimme F> static void addMethod(t_class *c, const char *name) { class_addmethod(c, (t_method) call, gensym(name), A_GIMME, 0); } - template struct Float { typedef void (T::*MethodFloat)(double v); }; - template ::MethodFloat F> static void call(T *x, double v) { ((x)->*F)(v); } + template struct Float { typedef void (T::*MethodFloat)(t_floatarg v); }; + template ::MethodFloat F> static void call(T *x, t_floatarg v) { ((x)->*F)(v); } template ::MethodFloat F> static void addMethod(t_class *c, const char *name) { class_addmethod(c, (t_method) call, gensym(name), A_FLOAT, 0); } - template struct DefFloat { typedef void (T::*MethodDefFloat)(def_double v); }; + template struct DefFloat { typedef void (T::*MethodDefFloat)(t_deffloatarg v); }; template ::MethodDefFloat F> static void call(T *x, double v) { (x->*F)(v); } template ::MethodDefFloat F> static void addMethod(t_class *c, const char *name) { auto f = call; class_addmethod(c, (t_method) f, gensym(name), A_DEFFLOAT, 0); } @@ -116,11 +116,6 @@ class PDClass_Base template ::MethodSym F> static void call(T *x, t_symbol *s) { ((x)->*F)(s); } template ::MethodSym F> static void addMethod(t_class *c, const char *name) { class_addmethod(c, (t_method) call, gensym(name), A_DEFSYM, 0); } - // FIX - is this a meaningful thing in PD? - template struct Subpatch { typedef void *(T::*MethodSubPatch)(long index, void *arg); }; - template ::MethodSubPatch F> static void *call(T *x, long index, void *arg) { return ((x)->*F)(index, arg); } - template ::MethodSubPatch F> static void addMethod(t_class *c, const char *name) { class_addmethod(c, (t_method) call, gensym(name), A_CANT, 0); } - template struct DSP { typedef void (T::*MethodDSP)(t_signal **sp); }; template ::MethodDSP F> static void call(T *x, t_signal **sp) { ((x)->*F)(sp); } template ::MethodDSP F> static void addMethod(t_class *c) { class_addmethod(c, (t_method) call, gensym("dsp"), A_CANT, 0); } @@ -146,6 +141,12 @@ class PDClass_Base dsp_add(callPerform, 2, this, sp[0]->s_vecsize); } + // Special helpers + + template ::MethodFloat F> static void addFloatMethod(t_class *c) { class_doaddfloat(c, (t_method) call); } + template ::MethodGimme F> static void addListMethod(t_class *c) { class_addlist(c, (t_method) (call)); } + template ::MethodGimme F> static void addAnythingMethod(t_class *c) { class_addanything(c, (t_method) (call)); } + // Atom helpers static t_atomtype atom_gettype(t_atom *a) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 1aa49acff..43f84b307 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -72,7 +72,7 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base // Multithreading - void multithread(double on) + void multithread(t_floatarg on) { FrameLib_Context::ProcessingQueue processingQueue(mContext); processingQueue->setMultithreading(on); @@ -80,7 +80,7 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base // Time out - void timeOut(double relative, double absolute) + void timeOut(t_floatarg relative, t_floatarg absolute) { FrameLib_Context::ProcessingQueue processingQueue(mContext); processingQueue->setTimeOuts(relative / 100.0, absolute / 1000.0); @@ -230,9 +230,9 @@ class FrameLib_PDClass_FromPD : public FrameLib_PDClass_Expand(c, "float"); - addMethod(c, "list"); - addMethod(c, "anything"); + addFloatMethod(c); + addListMethod(c); + addAnythingMethod(c); } // Constructor @@ -245,9 +245,10 @@ class FrameLib_PDClass_FromPD : public FrameLib_PDClass_ExpandsendFromHost(0, &in, 1); + double d_in = in; + mHostProxy->sendFromHost(0, &d_in, 1); } void list(t_symbol *s, long argc, t_atom *argv) From 20edd26fa688c4816a4a78054f625778335956f6 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 18:16:07 +0100 Subject: [PATCH 095/222] Remove old paths --- FrameLib_PD_Objects/makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index be41df810..3615b2061 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -3,7 +3,7 @@ FL_FRAMEWORK=../FrameLib_Framework FL_DEPENDENCIES=../FrameLib_Dependencies FL_OBJECTS=../FrameLib_Objects -VPATH=PD_Specific:\ ../FrameLib_Dependencies/tlsf +VPATH=../FrameLib_Dependencies/tlsf FL_CPP= \ $(wildcard $(FL_FRAMEWORK)/FrameLib_*.cpp)\ @@ -14,7 +14,6 @@ FL_OBJ_DIR=$(FL_CPP:.cpp=.o) tlsf.o FL_OBJ=$(notdir $(FL_OBJ_DIR)) INCLUDE_PATHS=\ - -IPD_Specific\ -ICommon\ -I$(FL_FRAMEWORK)\ -I$(FL_DEPENDENCIES)\ From 167b4ad59d1f9086972c72bbfb7c399249c9269d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 18:29:04 +0100 Subject: [PATCH 096/222] Need to service realtime context messages --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 5a698df4d..0e800b38f 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -121,10 +121,6 @@ struct FrameLib_PDProxy : public virtual FrameLib_Proxy { setOwner(x); } - - // Override for object proxies that need to know about the patch hierarchy - - //virtual void contextPatchUpdated(t_object *patch, unsigned long depth) {} }; struct FrameLib_PDMessageProxy : FrameLib_PDProxy @@ -134,10 +130,6 @@ struct FrameLib_PDMessageProxy : FrameLib_PDProxy // Override for objects that require max messages to be sent from framelib virtual void sendMessage(unsigned long stream, t_symbol *s, short ac, t_atom *av) {} - - // Store context patch info - - //void contextPatchUpdated(t_object *patch, unsigned long depth) override { mDepth = depth; } }; struct FrameLib_PDNRTAudio @@ -1138,6 +1130,8 @@ class FrameLib_PDClass : public PDClass_Base for (int i = 0; i < (getNumAudioOuts() - 1); i++) for (int j = 0; j < vec_size; j++) getAudioOut(i + 1)[j] = mSigOuts[i][j]; + + mGlobal->contextMessages(getContext(), *this); } void dsp(t_signal **sp) From 946895f8d704da51705f43fcdfb42fbd24b0324f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 18:38:41 +0100 Subject: [PATCH 097/222] Add fl.pack~ and fl.unpack~ to pd --- FrameLib_PD_Objects/framelib_pd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 43f84b307..c402e76d1 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -552,6 +552,8 @@ extern "C" void framelib_pd_setup(void) // Streaming FrameLib_PDClass_Expand::makeClass("fl.streamid~"); + FrameLib_PDClass::makeClass("fl.pack~"); + FrameLib_PDClass::makeClass("fl.unpack~"); // Time Smoothing From 1824906c431eefe4525a0845d9713ff537ca0f98 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 18:39:51 +0100 Subject: [PATCH 098/222] Update the pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 219ee70e9..4992d3c97 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -1,7 +1,7 @@ **Status and Building** -- All (163 out of 163) framelib objects get built to a single library files +- All (165 out of 165) framelib objects get built to a single library files - Realtime operation is supported, but non-realtime support is incomplete - There are some key issues to note below @@ -12,7 +12,7 @@ I'm not sure if there should be a VS project for windows or not. **Testing** -- I've started a test folder at Testing/02\_PD with at least one simple demo +- I've started a test folder at Testing/02\_PD with a couple of simple demos - Note that the first outlet and inlet of unsynced objects are the sync IO **Key Issues** @@ -38,9 +38,11 @@ I'm not sure if there should be a VS project for windows or not. **Review** +- Some pd correctness has been reviewed (DONE): + - Float arguments (t_floatarg?) + - Some pd correctness needs review: - PD-specific or custom objects (read/info/topd/frompd/contextcontrol/expressions) - - Float arguments (t_floatarg?) - Messages that would take ints in Max - Assist strings? - resetting dsp when resolving connections From 94a629664aed4e02d963158e21f21ca8baa0f8b5 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 20:36:30 +0100 Subject: [PATCH 099/222] Create outlets in left-right order for pd --- FrameLib_PD_Objects/framelib_pd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index c402e76d1..fdc3698dd 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -197,8 +197,8 @@ class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand mOutlets.resize(nStreams); - for (unsigned long i = nStreams; i > 0; i--) - mOutlets[i - 1] = outlet_new(*this, 0L); + for (unsigned long i = 0; i < nStreams; i++) + mOutlets[i] = outlet_new(*this, 0L); mHostProxy = static_cast(mProxy.get()); } From 0b67bfbaed58d92459d4d45714cd01c789143b66 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 21:30:04 +0100 Subject: [PATCH 100/222] More comments --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 6f1da5155..aeae63b9b 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -1379,6 +1379,8 @@ class FrameLib_MaxClass : public MaxClass_Base addMethod, &FrameLib_MaxClass::sync>(c, "sync"); addMethod, &FrameLib_MaxClass::dsp>(c); + // Audio Only + if (T::sHandlesAudio) { addMethod, &FrameLib_MaxClass::reset>(c, "reset"); @@ -1389,11 +1391,15 @@ class FrameLib_MaxClass : public MaxClass_Base dspInit(c); + // Buffer attribute + CLASS_ATTR_SYM(c, "buffer", ATTR_FLAGS_NONE, FrameLib_MaxClass, mBuffer); CLASS_ATTR_BASIC(c, "buffer", 0L); CLASS_ATTR_LABEL(c, "buffer", 0L, "Buffer"); } + // Attributes + CLASS_ATTR_SYM(c, "id", ATTR_FLAGS_NONE, FrameLib_MaxClass, mMaxContext.mName); CLASS_ATTR_ACCESSORS(c, "id", 0, &FrameLib_MaxClass::idSet); CLASS_ATTR_BASIC(c, "id", 0L); @@ -1404,6 +1410,8 @@ class FrameLib_MaxClass : public MaxClass_Base CLASS_ATTR_BASIC(c, "rt", 0L); CLASS_ATTR_LABEL(c, "rt", 0L, "Realtime"); + // External Methods + addMethod(c, (method) &extPatchLineUpdate, "patchlineupdate"); addMethod(c, (method) &extConnectionAccept, "connectionaccept"); addMethod(c, (method) &extResolveContext, FrameLib_MaxPrivate::messageResolveContext()); From 54f67013931261c96d29792b36cc521bffa6ba11 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 21:32:24 +0100 Subject: [PATCH 101/222] Set the context (and buffer) by message --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 36 +++++++++++-------- FrameLib_PD_Objects/framelib_pd.cpp | 28 +++++++++------ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 0e800b38f..bbf8d353e 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -862,6 +862,13 @@ class FrameLib_PDClass : public PDClass_Base addMethod, &FrameLib_PDClass::frame>(c, "frame"); addMethod, &FrameLib_PDClass::dsp>(c); + // Attributes + + addMethod(c, "id"); + addMethod(c, "rt"); + + // Audio only + if (T::sHandlesAudio) { addMethod, &FrameLib_PDClass::reset>(c, "reset"); @@ -872,6 +879,8 @@ class FrameLib_PDClass : public PDClass_Base dspInit(c); } + // External Methods + addMethod(c, (t_method) &extResolveContext, FrameLib_PDPrivate::messageResolveContext()); addMethod(c, (t_method) &extResolveConnections, FrameLib_PDPrivate::messageResolveConnections()); addMethod(c, (t_method) &extMarkUnresolved, FrameLib_PDPrivate::messageMarkUnresolved()); @@ -1367,28 +1376,27 @@ class FrameLib_PDClass : public PDClass_Base } // id attribute + + void idSet(t_symbol *name) + { + mPDContext.mName = name; + updateContext(); + } - // FIX - attributes + // rt attribute - /* - static void idSet(FrameLib_PDClass *x, t_object *attr, long argc, t_atom *argv) + void rtSet(t_floatarg arg) { - x->mMaxContext.mName = argv ? atom_getsym(argv) : gensym(""); - x->updateContext(); - - return MAX_ERR_NONE; + mPDContext.mRealtime = arg; + updateContext(); } - // rt attribute + // buffer attribute - static void rtSet(FrameLib_PDClass *x, t_object *attr, long argc, t_atom *argv) + void bufferSet(t_symbol *buffer) { - x->mMaxContext.mRealtime = argv ? (atom_getlong(argv) ? 1 : 0) : 0; - x->updateContext(); - - return MAX_ERR_NONE; + mBuffer = buffer; } - */ private: diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index fdc3698dd..fd087f232 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -18,6 +18,8 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base static void classInit(t_class *c, const char *classname) { addMethod(c, "multithread"); + addMethod(c, "id"); + addMethod(c, "rt"); class_addmethod(c, (t_method) &extTimeOut, gensym("timeout"), A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(c, (t_method) &extCodeExport, gensym("export"), A_SYMBOL, A_SYMBOL, 0); @@ -37,22 +39,20 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base // Attributes // id attribute - /* - static t_max_err idSet(FrameLib_PDClass_ContextControl *x, t_object *attr, long argc, t_atom *argv) + + void idSet(t_symbol *name) { - x->mMaxContext.mName = argv ? atom_getsym(argv) : gensym(""); - - return MAX_ERR_NONE; + mPDContext.mName = name; + updateContext(); } // rt attribute - static t_max_err rtSet(FrameLib_PDClass_ContextControl *x, t_object *attr, long argc, t_atom *argv) + void rtSet(t_floatarg arg) { - x->mMaxContext.mRealtime = argv ? (atom_getlong(argv) ? 1 : 0) : 0; - - return MAX_ERR_NONE; - }*/ + mPDContext.mRealtime = arg; + updateContext(); + } // Time out @@ -115,6 +115,14 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base pd_error(this, "couldn't write file"); } + // Context + + void updateContext() + { + mGlobal->releaseContext(mContext); + mContext = mGlobal->makeContext(mPDContext); + } + // Convert an object to an FLObject FrameLib_Multistream *toFLObject(t_object *x) From 7356b887c9974f2b24f6c4f5406ee80f4f9d891d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 2 Aug 2022 21:33:14 +0100 Subject: [PATCH 102/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 4992d3c97..ac1b39e49 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -27,7 +27,7 @@ I'm not sure if there should be a VS project for windows or not. - Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) - At the moment you can't connect framelib objects between different subpatchers -- Message ordering - If messages are send to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. +- Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. - Attributes - non-realtime in Max is set by attributes. Part of the misssing support in pd is to sort these (which must be supported manually) - My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. @@ -40,11 +40,11 @@ I'm not sure if there should be a VS project for windows or not. - Some pd correctness has been reviewed (DONE): - Float arguments (t_floatarg?) + - Assist strings? (don't exist for pd) - Some pd correctness needs review: - PD-specific or custom objects (read/info/topd/frompd/contextcontrol/expressions) - Messages that would take ints in Max - - Assist strings? - resetting dsp when resolving connections **Documentation** From 908f0728ff85bbd84b0b1cdbb10f554d1ad23d9c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 08:14:18 +0100 Subject: [PATCH 103/222] Delete unused lines in pd wrapper --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index bbf8d353e..94bdbc758 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -605,9 +605,6 @@ class FrameLib_PDGlobals : public PDClass_Base PDConnection getConnection() const { return mConnection; } ConnectionMode getConnectionMode() const { return mConnectionMode; } -// void setConnectAccept(ConnectAccept ca) { mConnectAccept = ca; } -// bool checkAccept(ConnectAccept ca) const { return mConnectAccept == ca; } - private: // Context methods @@ -696,7 +693,6 @@ class FrameLib_PDGlobals : public PDClass_Base PDConnection mConnection; ConnectionMode mConnectionMode; - //ConnectAccept mConnectAccept; bool mReportContextErrors; // Member Objects / Pointers @@ -846,10 +842,7 @@ class FrameLib_PDClass : public PDClass_Base std::string proxyClassName; if (T::sHandlesAudio) - { - //Wrapper:: template makeClass>(CLASS_BOX, className); internalClassName.insert(0, "unsynced."); - } proxyClassName.append(".proxy"); PDClass_Base::makeClass(internalClassName.c_str()); From 966ac130d93ffef2e4a42b242f6ba45f7d02d98b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 08:21:51 +0100 Subject: [PATCH 104/222] Consistency --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index aeae63b9b..9fd926277 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -656,9 +656,9 @@ class FrameLib_MaxGlobals : public MaxClass_Base return object; } - void addContextToResolve(FrameLib_Context context, t_object *object) + void addContextToResolve(FrameLib_Context c, t_object *object) { - mUnresolvedContexts[context] = object; + mUnresolvedContexts[c] = object; mQelem.set(); } From 3c29cab6eed8e416eabc216f30ca377c87ff9f0f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 10:36:32 +0100 Subject: [PATCH 105/222] Resolve realtime graphs from dsp routine for schedulers in pd (simpler and more reliable resolving) --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 86 +++++++------------ FrameLib_PD_Objects/framelib_pd.cpp | 3 +- 2 files changed, 34 insertions(+), 55 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 94bdbc758..926153c29 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -412,12 +412,11 @@ class FrameLib_PDGlobals : public PDClass_Base } }; - enum RefDataItem { kKey, kCount, kLock, kFinal, kHandler, kQueuePtr }; + enum RefDataItem { kKey, kCount, kLock, kLastResolved, kFinal, kHandler, kQueuePtr }; using QueuePtr = std::unique_ptr; - using RefData = std::tuple; + using RefData = std::tuple; using RefMap = std::unordered_map, Hash>; - using ResolveMap = std::unordered_map; public: @@ -494,10 +493,9 @@ class FrameLib_PDGlobals : public PDClass_Base , mNRTNotifier(&mNRTGlobal) , mRTGlobal(nullptr) , mNRTGlobal(nullptr) - , mQelem(this, (t_method) &serviceContexts) {} - // Max global item methods + // Pd global item methods void clearQueue() { mQueue.clear(); } void pushToQueue(t_object * object) { return mQueue.push_back(object); } @@ -512,10 +510,14 @@ class FrameLib_PDGlobals : public PDClass_Base return object; } - void addContextToResolve(FrameLib_Context context, t_object *object) + bool setLastResolved(FrameLib_Context c, double time) { - mUnresolvedContexts[context] = object; - mQelem.set(); + bool changed = time != data(c); + + if (changed) + data(c) = time; + + return changed; } void contextMessages(FrameLib_Context c) @@ -548,6 +550,7 @@ class FrameLib_PDGlobals : public PDClass_Base std::get(*item) = key; std::get(*item) = 1; + std::get(*item) = 0; std::get(*item) = nullptr; std::get(*item) = unique_pd_ptr(createNamed(FrameLib_PDPrivate::objectMessageHandler())); std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); @@ -573,14 +576,6 @@ class FrameLib_PDGlobals : public PDClass_Base ErrorNotifier::flush(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal); getHandler(c)->flush(proxy); - - auto it = mUnresolvedContexts.find(c); - - if (it != mUnresolvedContexts.end()) - { - objectMethod(it->second, FrameLib_PDPrivate::messageResolveContext()); - mUnresolvedContexts.erase(it); - } } void flushErrors(FrameLib_Context c, t_object *object) @@ -609,14 +604,6 @@ class FrameLib_PDGlobals : public PDClass_Base // Context methods - static void serviceContexts(FrameLib_PDGlobals *x) - { - for (auto it = x->mUnresolvedContexts.begin(); it != x->mUnresolvedContexts.end(); it++) - objectMethod(it->second, FrameLib_PDPrivate::messageResolveContext()); - - x->mUnresolvedContexts.clear(); - } - template typename std::tuple_element::type& data(FrameLib_Context context) { @@ -701,13 +688,10 @@ class FrameLib_PDGlobals : public PDClass_Base ErrorNotifier mNRTNotifier; std::deque mQueue; - ResolveMap mUnresolvedContexts; RefMap mContextRefs; FrameLib_Global *mRTGlobal; FrameLib_Global *mNRTGlobal; - - Qelem mQelem; }; ////////////////////////////////////////////////////////////////////////// @@ -1159,6 +1143,11 @@ class FrameLib_PDClass : public PDClass_Base if (handlesAudio()) { + // Resolve this context + + if (getType() == ObjectType::Scheduler && mGlobal->setLastResolved(mObject->getContext(), clock_getlogicaltime())) + resolveGraph(samplingRate, vec_size, true); + addPerform::perform>(sp); mGlobal->finalObject(getContext()) = *this; @@ -1198,7 +1187,6 @@ class FrameLib_PDClass : public PDClass_Base return; LockHold lock(mGlobal->getLock(getContext())); - resolveNRTGraph(0.0, false); // Retrieve all the audio objects in a list @@ -1403,7 +1391,8 @@ class FrameLib_PDClass : public PDClass_Base if (context != mObject->getContext()) { - mGlobal->addContextToResolve(context, *this); + // FIX + //mGlobal->addContextToResolve(context, *this); matchContext(context, true); } @@ -1427,9 +1416,7 @@ class FrameLib_PDClass : public PDClass_Base return; mResolved = false; - - mGlobal->pushToQueue(*this); - + T *newObject = new T(context, mObject->getSerialised(), mProxy.get(), mSpecifiedStreams); for (unsigned long i = 0; i < mObject->getNumIns(); i++) @@ -1445,6 +1432,8 @@ class FrameLib_PDClass : public PDClass_Base mGlobal->flushErrors(context, *this); mObject.reset(newObject); + + mGlobal->pushToQueue(*this); } // Private connection methods @@ -1475,10 +1464,12 @@ class FrameLib_PDClass : public PDClass_Base objectMethod(object, theMethodName, args...); } - bool resolveGraph(bool markUnresolved, bool forceRealtime = false) + void resolveGraph(double sampleRate, intptr_t vecSize, bool force) { - if (!forceRealtime && isRealtime() && dspIsRunning()) - return false; + //bool markUnresolved = isRealtime(); + + if (!force && isRealtime() && dspIsRunning()) + return; intptr_t updated = false; @@ -1496,29 +1487,16 @@ class FrameLib_PDClass : public PDClass_Base traversePatch(FrameLib_PDPrivate::messageMakeAutoOrdering()); } - if (markUnresolved) - traversePatch(FrameLib_PDPrivate::messageMarkUnresolved()); - - return updated; + //if (markUnresolved) + // traversePatch(FrameLib_PDPrivate::messageMarkUnresolved()); + + if (updated || force) + traversePatch(FrameLib_PDPrivate::messageReset(), &sampleRate, vecSize); } void resolveNRTGraph(double sampleRate, bool forceReset) { - bool updated = resolveGraph(false); - - if (updated || forceReset) - traversePatch(FrameLib_PDPrivate::messageReset(), &sampleRate, static_cast(maxBlockSize())); - } - - void resolveContext() - { - if (isRealtime()) - resolveGraph(true); - else - { - LockHold lock(mGlobal->getLock(getContext())); - resolveNRTGraph(0.0, false); - } + resolveGraph(0.0, static_cast(maxBlockSize()), forceReset); } // Convert from framelib object to max object and vice versa diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index fd087f232..ce1c77b3a 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -101,7 +101,8 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base return; } - objectMethod(object, FrameLib_PDPrivate::messageResolveContext()); + // FIX + //objectMethod(object, FrameLib_PDPrivate::messageResolveContext()); auto replace = FrameLib_TypeAliases::makeReplaceStrings(); From 7104cc8ea5de71c950e952a3df9972ed0379f44b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 10:36:48 +0100 Subject: [PATCH 106/222] Consistency --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 9fd926277..3382de437 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -2071,9 +2071,9 @@ class FrameLib_MaxClass : public MaxClass_Base x->mObject->clearAutoOrderingConnections(); } - static void extReset(FrameLib_MaxClass *x, const double *samplerate, t_ptr_int maxvectorsize) + static void extReset(FrameLib_MaxClass *x, const double *sampleRate, t_ptr_int vecSize) { - x->mObject->reset(*samplerate, static_cast(maxvectorsize)); + x->mObject->reset(*sampleRate, static_cast(vecSize)); } static void extConnectionUpdate(FrameLib_MaxClass *x, t_ptr_int state) From d1466d37d8e7651f5d96a6dd90a47f8ae05ee68e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 10:40:41 +0100 Subject: [PATCH 107/222] C++ style --- FrameLib_Max_Objects/Common/MaxClass_Base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_Max_Objects/Common/MaxClass_Base.h b/FrameLib_Max_Objects/Common/MaxClass_Base.h index 2c0a10da5..682015e0e 100644 --- a/FrameLib_Max_Objects/Common/MaxClass_Base.h +++ b/FrameLib_Max_Objects/Common/MaxClass_Base.h @@ -198,7 +198,7 @@ class MaxClass_Base static void *create(t_symbol *sym, long ac, t_atom *av) { void *x = object_alloc(*getClassPointer()); - new(x) T((t_object *)x, sym, ac, av); + new(x) T(reinterpret_cast(x), sym, ac, av); return x; } @@ -249,7 +249,7 @@ class MaxClass_Base // Allows type conversion to a t_object pointer - operator t_object* () { return (t_object *) this; } + operator t_object* () { return reinterpret_cast(this); } private: From 68b0ceba6dc3fc10467a0f2600defa3bcdd314e3 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 10:40:46 +0100 Subject: [PATCH 108/222] Correctness --- FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp b/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp index a6a7bf9ce..5bf7630d4 100644 --- a/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp +++ b/FrameLib_Max_Objects/Host_Communication/fl.tomax~.cpp @@ -77,7 +77,7 @@ FrameLib_MaxClass_ToMax::FrameLib_MaxClass_ToMax(t_object *x, t_symbol *s, long mOutlets.resize(nStreams); for (unsigned long i = nStreams; i > 0; i--) - mOutlets[i - 1] = outlet_new(this, 0L); + mOutlets[i - 1] = outlet_new(*this, 0L); mHostProxy = static_cast(mProxy.get()); } From 5220861d04e9daf0009fd36ac98178821970f8f9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 10:40:57 +0100 Subject: [PATCH 109/222] Formatting/naming/consistency --- .../Common/FrameLib_MaxClass.h | 112 ++++++++++-------- 1 file changed, 63 insertions(+), 49 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index e6053d433..3382de437 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -32,7 +32,7 @@ struct FrameLib_MaxPrivate { return 1000; } - + // A constant representing the max wrapper and framework versions. // The versions are combined in a manner that they are both easily readable when viewed in decimal format @@ -40,7 +40,7 @@ struct FrameLib_MaxPrivate { return static_cast(FrameLib_FrameworkVersion) * 1000000000 + static_cast(maxWrapperVersion()); } - + struct VersionString { VersionString(const char *str) : mString(str) @@ -55,15 +55,15 @@ struct FrameLib_MaxPrivate VersionString& operator=(const VersionString&) = delete; VersionString(VersionString&&) = default; VersionString& operator=(VersionString&&) = default; - + operator const char *() { return mString.c_str(); } std::string mString; }; - + static inline t_symbol *FLNamespace() { return gensym("__fl.framelib_private"); } static inline t_symbol *globalTag() { return gensym(VersionString("__fl.max_global_tag")); } - + static inline VersionString objectGlobal() { return "__fl.max_global_items"; } static inline VersionString objectMessageHandler() { return "__fl.message.handler"; } static inline VersionString objectMutator() { return "__fl.signal.mutator"; } @@ -325,7 +325,7 @@ class MessageHandler : public MaxClass_Base void add(const MessageInfo& info, const FrameLib_Parameters::Serial *serial) { // Lock, determine maximum vector size and copy - + FrameLib_LockHolder lock(&mLock); for (auto it = serial->begin(); it != serial->end(); it++) @@ -342,7 +342,7 @@ class MessageHandler : public MaxClass_Base void ready() { - // Lock and copy onto the output queue + // Lock and copy onto the output queue FrameLib_LockHolder lock(&mLock); @@ -376,7 +376,7 @@ class MessageHandler : public MaxClass_Base MessageBlock messages; // Swap data - + FrameLib_LockHolder flushLock(&handler->mFlushLock); FrameLib_LockHolder lock(&handler->mLock); @@ -402,7 +402,7 @@ class MessageHandler : public MaxClass_Base private: - static void output(const Message& message, t_atom *output) + static void output(const Message& message, t_atom *data) { FrameLib_MaxMessageProxy *proxy = message.mInfo.mProxy; @@ -414,9 +414,9 @@ class MessageHandler : public MaxClass_Base unsigned long N = limit(static_cast(message.mVector.size())); for (unsigned long i = 0; i < N; i++) - atom_setfloat(output + i, message.mVector[i]); + atom_setfloat(data + i, message.mVector[i]); - proxy->sendMessage(message.mInfo.mStream, nullptr, static_cast(N), output); + proxy->sendMessage(message.mInfo.mStream, nullptr, static_cast(N), data); } else { @@ -433,15 +433,15 @@ class MessageHandler : public MaxClass_Base size = limit(size); for (unsigned long i = 0; i < size; i++) - atom_setfloat(output + i, vector[i]); + atom_setfloat(data + i, vector[i]); } else { size = 1; - atom_setsym(output, gensym(it.getString())); + atom_setsym(data, gensym(it.getString())); } - proxy->sendMessage(message.mInfo.mStream, tag, static_cast(size), output); + proxy->sendMessage(message.mInfo.mStream, tag, static_cast(size), data); } } } @@ -450,7 +450,7 @@ class MessageHandler : public MaxClass_Base mutable FrameLib_Lock mLock; mutable FrameLib_Lock mFlushLock; - + MessageBlock mData; std::deque mOutput; }; @@ -610,7 +610,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base long mTime; Mode mMode; }; - + // Convenience Pointer for automatic deletion and RAII struct ManagedPointer @@ -620,10 +620,10 @@ class FrameLib_MaxGlobals : public MaxClass_Base ManagedPointer(const ManagedPointer&) = delete; ManagedPointer& operator=(const ManagedPointer&) = delete; - + FrameLib_MaxGlobals *operator->() { return mPointer; } const FrameLib_MaxGlobals *operator->() const { return mPointer; } - + private: FrameLib_MaxGlobals *mPointer; @@ -632,9 +632,15 @@ class FrameLib_MaxGlobals : public MaxClass_Base // Constructor and Destructor (public for max API, but use ManagedPointer from outside this class) FrameLib_MaxGlobals(t_object *x, t_symbol *sym, long ac, t_atom *av) - : mReportContextErrors(false), mRTNotifier(&mRTGlobal), mNRTNotifier(&mNRTGlobal), mRTGlobal(nullptr), mNRTGlobal(nullptr), mQelem(*this, (method) &serviceContexts), mSyncCheck(nullptr) + : mReportContextErrors(false) + , mRTNotifier(&mRTGlobal) + , mNRTNotifier(&mNRTGlobal) + , mRTGlobal(nullptr) + , mNRTGlobal(nullptr) + , mQelem(*this, (method) &serviceContexts) + , mSyncCheck(nullptr) {} - + // Max global item methods void clearQueue() { mQueue.clear(); } @@ -649,10 +655,10 @@ class FrameLib_MaxGlobals : public MaxClass_Base return object; } - - void addContextToResolve(FrameLib_Context context, t_object *object) + + void addContextToResolve(FrameLib_Context c, t_object *object) { - mUnresolvedContexts[context] = object; + mUnresolvedContexts[c] = object; mQelem.set(); } @@ -688,11 +694,11 @@ class FrameLib_MaxGlobals : public MaxClass_Base std::get(*item) = key; std::get(*item) = 1; std::get(*item) = nullptr; - std::get(*item) = unique_object_ptr((t_object *)object_new_typed(CLASS_NOBOX, handlerSym, 0, nullptr)); + std::get(*item) = unique_object_ptr((t_object *) object_new_typed(CLASS_NOBOX, handlerSym, 0, nullptr)); std::get(*item) = QueuePtr(new FrameLib_Context::ProcessingQueue(context)); // Set timeouts - + if (key.mRealtime) (*(std::get(*item).get()))->setTimeOuts(16.0, 1.0); else @@ -706,15 +712,15 @@ class FrameLib_MaxGlobals : public MaxClass_Base void retainContext(FrameLib_Context c) { data(c)++; } void releaseContext(FrameLib_Context c) { if (--data(c) == 0) mContextRefs.erase(data(c)); } - + void flushContext(FrameLib_Context c, FrameLib_MaxProxy *proxy) { ErrorNotifier::flush(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal); getHandler(c)->flush(proxy); - + auto it = mUnresolvedContexts.find(c); - + if (it != mUnresolvedContexts.end()) { objectMethod(it->second, FrameLib_MaxPrivate::messageResolveContext()); @@ -726,19 +732,19 @@ class FrameLib_MaxGlobals : public MaxClass_Base { ErrorNotifier::flushIgnore(data(c).mRealtime ? &mRTGlobal : &mNRTGlobal, object); } - + FrameLib_MaxContext getMaxContext(FrameLib_Context c) { return data(c); } - + bool isRealtime(FrameLib_Context c) const { return c.getGlobal() == mRTGlobal; } Lock *getLock(FrameLib_Context c) { return &data(c); } t_object *&finalObject(FrameLib_Context c) { return data(c); } - + void setReportContextErrors(bool report) { mReportContextErrors = report; } bool getReportContextErrors() const { return mReportContextErrors; } - + void setConnection(MaxConnection c) { mConnection = c; } void setConnectionMode(ConnectionMode m) { mConnectionMode = m; } MaxConnection getConnection() const { return mConnection; } @@ -758,7 +764,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base { for (auto it = x->mUnresolvedContexts.begin(); it != x->mUnresolvedContexts.end(); it++) objectMethod(it->second, FrameLib_MaxPrivate::messageResolveContext()); - + x->mUnresolvedContexts.clear(); } @@ -844,7 +850,7 @@ class FrameLib_MaxGlobals : public MaxClass_Base std::deque mQueue; ResolveMap mUnresolvedContexts; RefMap mContextRefs; - + FrameLib_Global *mRTGlobal; FrameLib_Global *mNRTGlobal; @@ -1298,7 +1304,7 @@ class FrameLib_MaxClass : public MaxClass_Base enum Error { kNone = 0x00, kVersion = 0x01, kContext = 0x02, kExtra= 0x04, kFeedback = 0x08, kDirect = 0x10 }; Input(void *proxy, long index) - : mProxy(MaxClass_Base::toUnique(proxy)) + : mProxy(toUnique(proxy)) , mIndex(index) , mErrorTime(-1) , mErrorFlags(0) @@ -1373,6 +1379,8 @@ class FrameLib_MaxClass : public MaxClass_Base addMethod, &FrameLib_MaxClass::sync>(c, "sync"); addMethod, &FrameLib_MaxClass::dsp>(c); + // Audio Only + if (T::sHandlesAudio) { addMethod, &FrameLib_MaxClass::reset>(c, "reset"); @@ -1383,11 +1391,15 @@ class FrameLib_MaxClass : public MaxClass_Base dspInit(c); + // Buffer attribute + CLASS_ATTR_SYM(c, "buffer", ATTR_FLAGS_NONE, FrameLib_MaxClass, mBuffer); CLASS_ATTR_BASIC(c, "buffer", 0L); CLASS_ATTR_LABEL(c, "buffer", 0L, "Buffer"); } + // Attributes + CLASS_ATTR_SYM(c, "id", ATTR_FLAGS_NONE, FrameLib_MaxClass, mMaxContext.mName); CLASS_ATTR_ACCESSORS(c, "id", 0, &FrameLib_MaxClass::idSet); CLASS_ATTR_BASIC(c, "id", 0L); @@ -1398,6 +1410,8 @@ class FrameLib_MaxClass : public MaxClass_Base CLASS_ATTR_BASIC(c, "rt", 0L); CLASS_ATTR_LABEL(c, "rt", 0L, "Realtime"); + // External Methods + addMethod(c, (method) &extPatchLineUpdate, "patchlineupdate"); addMethod(c, (method) &extConnectionAccept, "connectionaccept"); addMethod(c, (method) &extResolveContext, FrameLib_MaxPrivate::messageResolveContext()); @@ -1877,7 +1891,7 @@ class FrameLib_MaxClass : public MaxClass_Base return; LockHold lock(mGlobal->getLock(getContext())); - + resolveNRTGraph(0.0, false); // Retrieve all the audio objects in a list @@ -2057,9 +2071,9 @@ class FrameLib_MaxClass : public MaxClass_Base x->mObject->clearAutoOrderingConnections(); } - static void extReset(FrameLib_MaxClass *x, const double *samplerate, t_ptr_int maxvectorsize) + static void extReset(FrameLib_MaxClass *x, const double *sampleRate, t_ptr_int vecSize) { - x->mObject->reset(*samplerate, static_cast(maxvectorsize)); + x->mObject->reset(*sampleRate, static_cast(vecSize)); } static void extConnectionUpdate(FrameLib_MaxClass *x, t_ptr_int state) @@ -2158,7 +2172,7 @@ class FrameLib_MaxClass : public MaxClass_Base if (mObject) { FrameLib_Context context = mGlobal->makeContext(mMaxContext); - + if (context != mObject->getContext()) { mGlobal->addContextToResolve(context, *this); @@ -2166,7 +2180,7 @@ class FrameLib_MaxClass : public MaxClass_Base } // N.B. release because otherwise it is retained twice - + mGlobal->releaseContext(context); } } @@ -2178,7 +2192,7 @@ class FrameLib_MaxClass : public MaxClass_Base FrameLib_MaxContext maxContext = mGlobal->getMaxContext(context); FrameLib_Context current = getContext(); bool mismatchedPatch = mGlobal->getMaxContext(current).mPatch != maxContext.mPatch; - + unsigned long size = 0; if ((!force && mismatchedPatch) || current == context) @@ -2193,7 +2207,7 @@ class FrameLib_MaxClass : public MaxClass_Base for (unsigned long i = 0; i < mObject->getNumIns(); i++) if (const double *values = mObject->getFixedInput(i, &size)) newObject->setFixedInput(i, values, size); - + if (mGlobal->isRealtime(context) || mGlobal->isRealtime(current)) dspSetBroken(); @@ -2209,7 +2223,7 @@ class FrameLib_MaxClass : public MaxClass_Base object_attr_touch(mUserObject, gensym("rt")); if (idChanged) object_attr_touch(mUserObject, gensym("id")); - + mObject.reset(newObject); } @@ -2268,7 +2282,7 @@ class FrameLib_MaxClass : public MaxClass_Base traversePatch(FrameLib_MaxPrivate::messageResolveConnections(), &updated); traversePatch(FrameLib_MaxPrivate::messageConnectionUpdate(), t_ptr_int(false)); mGlobal->setReportContextErrors(false); - + // If updated then redo auto ordering connections if (updated) @@ -2358,7 +2372,7 @@ class FrameLib_MaxClass : public MaxClass_Base MaxConnection getConnection(long index) { return toMaxConnection(mObject->getConnection(index)); } MaxConnection getOrderingConnection(long index) { return toMaxConnection(mObject->getOrderingConnection(index)); } - long getNumOrderingConnections() const { return static_cast(mObject->getNumOrderingConnections()); } + long getNumOrderingConnections() const { return static_cast(mObject->getNumOrderingConnections()); } static MaxConnection toMaxConnection(FLConnection c) { return MaxConnection(toMaxObject(c.mObject), c.mIndex); } static FLConnection toFLConnection(MaxConnection c) { return FLConnection(toFLObject(c.mObject), c.mIndex); } @@ -2795,13 +2809,13 @@ class FrameLib_MaxClass : public MaxClass_Base long mProxyNum; ConnectionConfirmation *mConfirmation; - + unique_object_ptr mSyncIn; t_object *mUserObject; unsigned long mSpecifiedStreams; - + bool mConnectionsUpdated; bool mContextPatchConfirmed; bool mResolved; @@ -2816,7 +2830,7 @@ class FrameLib_MaxClass : public MaxClass_Base // Convenience for Objects Using FrameLib_Expand (use FrameLib_MaxClass_Expand::makeClass() to create) -template -using FrameLib_MaxClass_Expand = FrameLib_MaxClass, argsSetAllInputs>; +template +using FrameLib_MaxClass_Expand = FrameLib_MaxClass, argsMode>; #endif From 42cea716d38f1615881beb4c58e1fba92996b980 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 10:41:13 +0100 Subject: [PATCH 110/222] Enhanced scheduling debugging option --- FrameLib_Framework/FrameLib_DSP.cpp | 40 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/FrameLib_Framework/FrameLib_DSP.cpp b/FrameLib_Framework/FrameLib_DSP.cpp index ea2f3f06f..422ee8e57 100644 --- a/FrameLib_Framework/FrameLib_DSP.cpp +++ b/FrameLib_Framework/FrameLib_DSP.cpp @@ -1,6 +1,14 @@ #include "FrameLib_DSP.h" +// N.B. define FRAMELIB_RT_DSP_CHECK to report on timing errors in realtime rather than asserting (debug) or removing the tests (release) + +#ifdef FRAMELIB_RT_DSP_CHECK +#define debug_rt_check(e, str) if (!(e)) getReporter()(ErrorSource::DSP, getProxy(), str); +#else +#define debug_rt_check(e, str) assert(e && str); +#endif + // Constructor / Destructor FrameLib_DSP::FrameLib_DSP(ObjectType type, FrameLib_Context context, FrameLib_Proxy *proxy, FrameLib_Parameters::Info *info, unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans) @@ -362,7 +370,7 @@ void FrameLib_DSP::dependencyNotify(NotificationType type, NotificationQueue& qu if (mProcessingQueue->isTimedOut()) return; - assert(((mDependencyCount > 0) || (mUpdatingInputs && (mInputCount > 0))) && "Dependency count is already zero"); + debug_rt_check(((mDependencyCount > 0) || (mUpdatingInputs && (mInputCount > 0))), "Dependency count is already zero"); if (allocator && mOutputDone) releaseOutputMemory(allocator); @@ -373,7 +381,7 @@ void FrameLib_DSP::dependencyNotify(NotificationType type, NotificationQueue& qu { // N.B. Avoid re-entrancy by increasing the relevant dependency counts before processing (plus matched notifications) - assert((mDependencyCount > 0) || !mUpdatingInputs && "Dependency count shouldn't be zero if updating inputs"); + debug_rt_check((mDependencyCount > 0) || !mUpdatingInputs, "Dependency count shouldn't be zero if updating inputs"); mDependencyCount++; mInputCount++; @@ -381,8 +389,8 @@ void FrameLib_DSP::dependencyNotify(NotificationType type, NotificationQueue& qu queue.push(this); } - assert(mDependencyCount >= 0 && "Dependency count shouldn't be negative"); - assert(mInputCount >= 0 && "Input count shouldn't be negative"); + debug_rt_check(mDependencyCount >= 0, "Dependency count shouldn't be negative"); + debug_rt_check(mInputCount >= 0, "Input count shouldn't be negative"); } // For updating the correct input count @@ -401,7 +409,7 @@ void FrameLib_DSP::dependenciesReady(NotificationQueue& queue, LocalAllocator *a { setLocalAllocator(allocator); -#ifndef NDEBUG +#if !(defined NDEBUG) || (defined FRAMELIB_RT_DSP_CHECK) const FrameLib_TimeFormat inputTime = mInputTime; #endif @@ -585,17 +593,17 @@ void FrameLib_DSP::dependenciesReady(NotificationQueue& queue, LocalAllocator *a for (auto it = mOutputDependencies.begin(); it != mOutputDependencies.end(); it++) (*it)->dependencyNotify(NotificationType::Input, queue); - // Debug (before re-entering) + // Debug (before re-entering) - N.B. may be done as an error or an assert + + debug_rt_check(!needsAudioNotification() || (inputTime >= mBlockStartTime), "Object behind host"); + debug_rt_check(!needsAudioNotification() || (inputTime < mBlockEndTime), "Object ahead of host"); + debug_rt_check(mInputTime > inputTime, "Failed to move time forward"); + debug_rt_check(mInputTime <= mValidTime, "Input is ahead of output"); + debug_rt_check(mFrameTime <= mInputTime, "Output is ahead of input"); + debug_rt_check(mDependencyCount >= 1, "Dependency count shouldn't be less than 1"); + debug_rt_check(mUpdatingInputs || endOfTime || mInputCount == 0, "Input count should be 0"); + debug_rt_check(!mUpdatingInputs || mInputCount >= 1, "Input count shouldn't be less than 1"); - assert(!needsAudioNotification() || (inputTime >= mBlockStartTime) && "Object behind host"); - assert(!needsAudioNotification() || (inputTime < mBlockEndTime) && "Object ahead of host"); - assert(mInputTime > inputTime && "Failed to move time forward"); - assert(mInputTime <= mValidTime && "Input is ahead of output"); - assert(mFrameTime <= mInputTime && "Output is ahead of input"); - assert(mDependencyCount >= 1 && "Dependency count shouldn't be less than 1"); - assert(mUpdatingInputs || endOfTime || mInputCount == 0 && "Input count should be 0"); - assert(!mUpdatingInputs || mInputCount >= 1 && "Input count shouldn't be less than 1"); - // After resolving all other dependencies do self-notifications allowing self triggering if (!endOfTime) @@ -640,7 +648,7 @@ inline void FrameLib_DSP::freeOutputMemory(LocalAllocator *allocator) inline void FrameLib_DSP::releaseOutputMemory(LocalAllocator *allocator) { - assert(mOutputMemoryCount > 0 && "Output memory count is already zero"); + debug_rt_check(mOutputMemoryCount > 0, "Output memory count is already zero"); if (--mOutputMemoryCount == 0) freeOutputMemory(allocator); From ebe608ca442f2b3c4a59c690cad35ba0339f29ac Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 13:50:59 +0100 Subject: [PATCH 111/222] Deal better with audio restarts --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 5 ++++- FrameLib_PD_Objects/Common/PDClass_Base.h | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 926153c29..c4645e3b6 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1409,6 +1409,7 @@ class FrameLib_PDClass : public PDClass_Base FrameLib_PDContext pdContext = mGlobal->getPDContext(context); FrameLib_Context current = getContext(); bool mismatchedPatch = mGlobal->getPDContext(current).mCanvas != pdContext.mCanvas; + bool oldState = false; unsigned long size = 0; @@ -1424,7 +1425,7 @@ class FrameLib_PDClass : public PDClass_Base newObject->setFixedInput(i, values, size); if (mGlobal->isRealtime(context) || mGlobal->isRealtime(current)) - dspSetBroken(); + oldState = dspSuspend(); mPDContext = pdContext; mGlobal->retainContext(context); @@ -1434,6 +1435,8 @@ class FrameLib_PDClass : public PDClass_Base mObject.reset(newObject); mGlobal->pushToQueue(*this); + + dspResume(oldState); } // Private connection methods diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index b2292f299..ea1380960 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -313,6 +313,16 @@ class PDClass_Base canvas_update_dsp(); return true; } + + bool dspSuspend() + { + return canvas_suspend_dsp(); + } + + void dspResume(bool oldState) + { + canvas_resume_dsp(oldState); + } const t_sample *getAudioIn(unsigned long idx) { return mSigIns[idx]; } t_sample *getAudioOut(unsigned long idx) { return mSigOuts[idx]; } From 90a1f1367bc1e2b9f907689381acae995306ac77 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 13:51:25 +0100 Subject: [PATCH 112/222] Remove unused methods --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index c4645e3b6..ca644d827 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -77,7 +77,6 @@ struct FrameLib_PDPrivate static inline const char *messageUnwrap() { return "__fl.unwrap"; } static inline const char *messageIsWrapper() { return "__fl.is_wrapper"; } static inline const char *messageFindAudioObjects() { return "__fl.find_audio_objects"; } - static inline const char *messageResolveContext() { return "__fl.resolve_context"; } static inline const char *messageResolveConnections() { return "__fl.resolve_connections"; } static inline const char *messageMarkUnresolved() { return "__fl.mark_unresolved"; } static inline const char *messageMakeAutoOrdering() { return "__fl.make_auto_ordering"; } @@ -858,7 +857,6 @@ class FrameLib_PDClass : public PDClass_Base // External Methods - addMethod(c, (t_method) &extResolveContext, FrameLib_PDPrivate::messageResolveContext()); addMethod(c, (t_method) &extResolveConnections, FrameLib_PDPrivate::messageResolveConnections()); addMethod(c, (t_method) &extMarkUnresolved, FrameLib_PDPrivate::messageMarkUnresolved()); addMethod(c, (t_method) &extMakeAutoOrdering, FrameLib_PDPrivate::messageMakeAutoOrdering()); @@ -1289,11 +1287,6 @@ class FrameLib_PDClass : public PDClass_Base objects->push_back(FrameLib_PDNRTAudio{x->mObject.get(), x->mBuffer}); } - static void extResolveContext(FrameLib_PDClass *x) - { - x->resolveContext(); - } - static void extResolveConnections(FrameLib_PDClass *x, intptr_t *flag) { bool updated = x->resolveConnections(); From 92ec10387f5f28320ec24d0a668a9f944ab14c05 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 16:38:50 +0100 Subject: [PATCH 113/222] Remove user object (unused) from pd wrapper --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 41 +++++++------------ 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index ca644d827..048e97a54 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -73,7 +73,6 @@ struct FrameLib_PDPrivate static inline VersionString objectGlobal() { return "__fl.pd_global_items"; } static inline VersionString objectMessageHandler() { return "__fl.message.handler"; } - static inline const char *messageGetUserObject() { return "__fl.get_user_object"; } static inline const char *messageUnwrap() { return "__fl.unwrap"; } static inline const char *messageIsWrapper() { return "__fl.is_wrapper"; } static inline const char *messageFindAudioObjects() { return "__fl.find_audio_objects"; } @@ -440,15 +439,14 @@ class FrameLib_PDGlobals : public PDClass_Base { std::string errorText; t_object *object = it->getReporter() ? it->getReporter()->getOwner() : nullptr; - t_object *userObject = object ? objectMethod(object, FrameLib_PDPrivate::messageGetUserObject()) : nullptr; it->getErrorText(errorText); - if (userObject) + if (object) { if (object == ignore) continue; - pd_error(userObject, "%s", errorText.c_str()); + pd_error(object, "%s", errorText.c_str()); } else error("%s", errorText.c_str()); @@ -773,9 +771,9 @@ class FrameLib_PDClass : public PDClass_Base Input() : Input(nullptr, 0) {} - void reportError(t_object *userObject, Error error) const + void reportError(t_object *object, Error error) const { - auto postError = [&](const char *str) { pd_error(userObject, "%s input %ld", str, mIndex + 1); }; + auto postError = [&](const char *str) { pd_error(object, "%s input %ld", str, mIndex + 1); }; double time = clock_getlogicaltime(); bool validTime = mErrorTime + 500 >= time; @@ -866,7 +864,6 @@ class FrameLib_PDClass : public PDClass_Base addMethod(c, (t_method) &extConnectionConfirm, FrameLib_PDPrivate::messageConnectionConfirm()); addMethod(c, (t_method) &extConnectionUpdate, FrameLib_PDPrivate::messageConnectionUpdate()); addMethod(c, (t_method) &extGetFLObject, FrameLib_PDPrivate::messageGetFrameLibObject()); - addMethod(c, (t_method) &extGetUserObject, FrameLib_PDPrivate::messageGetUserObject()); addMethod(c, (t_method) &extGetNumAudioIns, FrameLib_PDPrivate::messageGetNumAudioIns()); addMethod(c, (t_method) &extGetNumAudioOuts, FrameLib_PDPrivate::messageGetNumAudioOuts()); } @@ -900,7 +897,6 @@ class FrameLib_PDClass : public PDClass_Base : mProxy(proxy ? proxy : new FrameLib_PDProxy(x)) , mCanvas(canvas_getcurrent()) , mConfirmation(nullptr) - , mUserObject(*this) , mSpecifiedStreams(1) , mConnectionsUpdated(false) , mContextPatchConfirmed(false) @@ -1269,7 +1265,7 @@ class FrameLib_PDClass : public PDClass_Base else if (mConfirmation) { if (mConfirmation->confirm(connection, index) && mGlobal->getConnectionMode() == ConnectionMode::kDoubleCheck) - mInputs[index].reportError(mUserObject, Input::kExtra); + mInputs[index].reportError(*this, Input::kExtra); } } @@ -1323,12 +1319,7 @@ class FrameLib_PDClass : public PDClass_Base *version = FrameLib_PDPrivate::version(); return x->mObject.get(); } - - static t_object *extGetUserObject(FrameLib_PDClass *x) - { - return x->mUserObject; - } - + static void extConnectionConfirm(FrameLib_PDClass *x, unsigned long index, ConnectionMode mode) { x->makeConnection(index, mode); @@ -1512,7 +1503,7 @@ class FrameLib_PDClass : public PDClass_Base bool mismatch = FrameLib_PDPrivate::versionMismatch(object); if (mismatch && report) - mInputs[inIdx].reportError(mUserObject, Input::kVersion); + mInputs[inIdx].reportError(*this, Input::kVersion); return mismatch; } @@ -1639,16 +1630,16 @@ class FrameLib_PDClass : public PDClass_Base break; case ConnectionResult::FeedbackDetected: - mInputs[inIdx].reportError(mUserObject, Input::kFeedback); + mInputs[inIdx].reportError(*this, Input::kFeedback); break; case ConnectionResult::WrongContext: if (mGlobal->getReportContextErrors()) - mInputs[inIdx].reportError(mUserObject, Input::kContext); + mInputs[inIdx].reportError(*this, Input::kContext); break; case ConnectionResult::SelfConnection: - mInputs[inIdx].reportError(mUserObject, Input::kDirect); + mInputs[inIdx].reportError(*this, Input::kDirect); break; case ConnectionResult::NoOrderingSupport: @@ -1731,7 +1722,7 @@ class FrameLib_PDClass : public PDClass_Base values.push_back(atom_getfloat(argv + idx)); if (atom_gettype(argv + idx) == A_SYMBOL && !values.back()) - pd_error(mUserObject, "string %s in entry list where value expected", atom_getsymbol_default(argv + idx)->s_name); + pd_error(*this, "string %s in entry list where value expected", atom_getsymbol_default(argv + idx)->s_name); } return idx; @@ -1773,7 +1764,7 @@ class FrameLib_PDClass : public PDClass_Base if ((i >= argc) || isTag(argv + i)) { - pd_error(mUserObject, "no values given for parameter %s", sym->s_name); + pd_error(*this, "no values given for parameter %s", sym->s_name); continue; } @@ -1784,7 +1775,7 @@ class FrameLib_PDClass : public PDClass_Base serialisedParameters.write(sym->s_name + 1, atom_getsymbol_default(argv + i++)->s_name); if (i < argc && !isTag(argv + i)) - pd_error(mUserObject, "stray items after parameter %s", sym->s_name); + pd_error(*this, "stray items after parameter %s", sym->s_name); } else { @@ -1837,7 +1828,7 @@ class FrameLib_PDClass : public PDClass_Base mObject->setFixedInput(inputNumber(sym), values.data(), static_cast(values.size())); if (inputNumber(sym) >= static_cast(getNumIns())) - pd_error(mUserObject, "input %s out of bounds", sym->s_name); + pd_error(*this, "input %s out of bounds", sym->s_name); } } } @@ -1894,9 +1885,7 @@ class FrameLib_PDClass : public PDClass_Base std::vector mDirectlyConnected; ConnectionConfirmation *mConfirmation; - - t_object *mUserObject; - + unsigned long mSpecifiedStreams; bool mConnectionsUpdated; From 41700414a622f93f52f034c3e88d2ca1ccc8305d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 18:59:53 +0100 Subject: [PATCH 114/222] Avoid conversion ambiguity --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 56 ++++++++++--------- FrameLib_PD_Objects/Common/PDClass_Base.h | 18 +++--- FrameLib_PD_Objects/framelib_pd.cpp | 4 +- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 048e97a54..9493fe485 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -643,15 +643,15 @@ class FrameLib_PDGlobals : public PDClass_Base // See if an object is already registered (and either free the new object or bind it...) - FrameLib_PDGlobals *x = (FrameLib_PDGlobals *) pd_findbyclass(pdGlobalTag, objectName(*y)); + FrameLib_PDGlobals *x = (FrameLib_PDGlobals *) pd_findbyclass(pdGlobalTag, objectClass(y->asPD())); if (!x) { x = y; - pd_bind(*x, pdGlobalTag); + pd_bind(x->asPD(), pdGlobalTag); } else - pd_free(*y); + pd_free(y->asPD()); FrameLib_Global::get(&x->mRTGlobal, priorities(true), &x->mRTNotifier); FrameLib_Global::get(&x->mNRTGlobal, priorities(false), &x->mNRTNotifier); @@ -668,8 +668,8 @@ class FrameLib_PDGlobals : public PDClass_Base { assert(!mNRTGlobal && "Reference counting error"); - pd_unbind(*this, FrameLib_PDPrivate::globalTag()); - pd_free(*this); + pd_unbind(asPD(), FrameLib_PDPrivate::globalTag()); + pd_free(asPD()); } } @@ -762,18 +762,19 @@ class FrameLib_PDClass : public PDClass_Base enum Error { kNone = 0x00, kVersion = 0x01, kContext = 0x02, kExtra= 0x04, kFeedback = 0x08, kDirect = 0x10 }; - Input(t_pd *proxy, long index) + Input(t_pd *proxy, t_object *owner, long index) : mProxy(toUnique(proxy)) + , mOwner(owner) , mIndex(index) , mErrorTime(-1) , mErrorFlags(0) {} - Input() : Input(nullptr, 0) {} + Input() : Input(nullptr, nullptr, 0) {} - void reportError(t_object *object, Error error) const + void reportError(Error error) const { - auto postError = [&](const char *str) { pd_error(object, "%s input %ld", str, mIndex + 1); }; + auto postError = [&](const char *str) { pd_error(mOwner, "%s input %ld", str, mIndex + 1); }; double time = clock_getlogicaltime(); bool validTime = mErrorTime + 500 >= time; @@ -805,6 +806,7 @@ class FrameLib_PDClass : public PDClass_Base private: unique_pd_ptr mProxy; + t_object *mOwner; long mIndex; mutable long mErrorTime; mutable long mErrorFlags; @@ -935,17 +937,17 @@ class FrameLib_PDClass : public PDClass_Base if (i || handlesAudio()) { t_pd *proxy = PDProxy::create(this, (int) (getNumAudioIns() + i)); - inlet_new(*this, proxy, gensym("frame"), gensym("frame")); - mInputs[i] = Input(proxy, i); + inlet_new(asObject(), proxy, gensym("frame"), gensym("frame")); + mInputs[i] = Input(proxy, asObject(), i); } else - mInputs[i] = Input(nullptr, i); + mInputs[i] = Input(nullptr, asObject(), i); } // Create frame outlets for (unsigned long i = 0; i < getNumOuts(); i++) - mOutputs[i] = outlet_new(*this, gensym("frame")); + mOutputs[i] = outlet_new(asObject(), gensym("frame")); } ~FrameLib_PDClass() @@ -1111,7 +1113,7 @@ class FrameLib_PDClass : public PDClass_Base for (int j = 0; j < vec_size; j++) getAudioOut(i + 1)[j] = mSigOuts[i][j]; - mGlobal->contextMessages(getContext(), *this); + mGlobal->contextMessages(getContext(), asObject()); } void dsp(t_signal **sp) @@ -1143,7 +1145,7 @@ class FrameLib_PDClass : public PDClass_Base resolveGraph(samplingRate, vec_size, true); addPerform::perform>(sp); - mGlobal->finalObject(getContext()) = *this; + mGlobal->finalObject(getContext()) = asObject(); mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts() -2)); mSigIns.resize(getNumAudioIns() - 1); @@ -1265,7 +1267,7 @@ class FrameLib_PDClass : public PDClass_Base else if (mConfirmation) { if (mConfirmation->confirm(connection, index) && mGlobal->getConnectionMode() == ConnectionMode::kDoubleCheck) - mInputs[index].reportError(*this, Input::kExtra); + mInputs[index].reportError(Input::kExtra); } } @@ -1414,11 +1416,11 @@ class FrameLib_PDClass : public PDClass_Base mPDContext = pdContext; mGlobal->retainContext(context); mGlobal->releaseContext(current); - mGlobal->flushErrors(context, *this); + mGlobal->flushErrors(context, asObject()); mObject.reset(newObject); - mGlobal->pushToQueue(*this); + mGlobal->pushToQueue(asObject()); dspResume(oldState); } @@ -1503,7 +1505,7 @@ class FrameLib_PDClass : public PDClass_Base bool mismatch = FrameLib_PDPrivate::versionMismatch(object); if (mismatch && report) - mInputs[inIdx].reportError(*this, Input::kVersion); + mInputs[inIdx].reportError(Input::kVersion); return mismatch; } @@ -1580,7 +1582,7 @@ class FrameLib_PDClass : public PDClass_Base void makeConnection(unsigned long index, ConnectionMode mode) { - mGlobal->setConnection(PDConnection(*this, index)); + mGlobal->setConnection(PDConnection(asObject(), index)); mGlobal->setConnectionMode(mode); outlet_anything(mOutputs[index], gensym("frame"), 0, nullptr); mGlobal->setConnection(PDConnection()); @@ -1630,16 +1632,16 @@ class FrameLib_PDClass : public PDClass_Base break; case ConnectionResult::FeedbackDetected: - mInputs[inIdx].reportError(*this, Input::kFeedback); + mInputs[inIdx].reportError(Input::kFeedback); break; case ConnectionResult::WrongContext: if (mGlobal->getReportContextErrors()) - mInputs[inIdx].reportError(*this, Input::kContext); + mInputs[inIdx].reportError(Input::kContext); break; case ConnectionResult::SelfConnection: - mInputs[inIdx].reportError(*this, Input::kDirect); + mInputs[inIdx].reportError(Input::kDirect); break; case ConnectionResult::NoOrderingSupport: @@ -1722,7 +1724,7 @@ class FrameLib_PDClass : public PDClass_Base values.push_back(atom_getfloat(argv + idx)); if (atom_gettype(argv + idx) == A_SYMBOL && !values.back()) - pd_error(*this, "string %s in entry list where value expected", atom_getsymbol_default(argv + idx)->s_name); + pd_error(asObject(), "string %s in entry list where value expected", atom_getsymbol_default(argv + idx)->s_name); } return idx; @@ -1764,7 +1766,7 @@ class FrameLib_PDClass : public PDClass_Base if ((i >= argc) || isTag(argv + i)) { - pd_error(*this, "no values given for parameter %s", sym->s_name); + pd_error(asObject(), "no values given for parameter %s", sym->s_name); continue; } @@ -1775,7 +1777,7 @@ class FrameLib_PDClass : public PDClass_Base serialisedParameters.write(sym->s_name + 1, atom_getsymbol_default(argv + i++)->s_name); if (i < argc && !isTag(argv + i)) - pd_error(*this, "stray items after parameter %s", sym->s_name); + pd_error(asObject(), "stray items after parameter %s", sym->s_name); } else { @@ -1828,7 +1830,7 @@ class FrameLib_PDClass : public PDClass_Base mObject->setFixedInput(inputNumber(sym), values.data(), static_cast(values.size())); if (inputNumber(sym) >= static_cast(getNumIns())) - pd_error(*this, "input %s out of bounds", sym->s_name); + pd_error(asObject(), "input %s out of bounds", sym->s_name); } } } diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index ea1380960..ce07ca56e 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -32,8 +32,7 @@ class PDClass_Base //using def_int = DefaultArg; using t_deffloatarg = DefaultArg; - - // Unique pointers to t_objects + // Unique pointers to t_pds using unique_pd_ptr = std::unique_ptr; static unique_pd_ptr toUnique(t_pd *ptr) { return unique_pd_ptr(ptr); } @@ -230,7 +229,7 @@ class PDClass_Base // Get a class pointer from an object - static t_class *objectName(t_pd *pd) + static t_class *objectClass(t_pd *pd) { return *pd; } @@ -292,12 +291,12 @@ class PDClass_Base // Create signal inlets for (unsigned long i = 0; numSigIns && i < (numSigIns - 1); i++) - signalinlet_new(*this, 0.0); + signalinlet_new(asObject(), 0.0); // Create signal outlets for (unsigned long i = 0; i < numSigOuts; i++) - outlet_new(*this, gensym("signal")); + outlet_new(asObject(), gensym("signal")); } bool dspIsRunning() @@ -327,14 +326,13 @@ class PDClass_Base const t_sample *getAudioIn(unsigned long idx) { return mSigIns[idx]; } t_sample *getAudioOut(unsigned long idx) { return mSigOuts[idx]; } - // Allows type conversion to a t_object + // Allow coversion to the t_object pointer - operator t_object&() { return mObject; } + t_object *asObject() { return &mObject; } - // Allows type conversion to a t_object or t_pd pointer + // Allows type conversion to a t_pd pointer - operator t_object* () { return reinterpret_cast(this); } - operator t_pd* () { return &this->mObject.te_g.g_pd; } + t_pd *asPD() { return &this->mObject.te_g.g_pd; } private: diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index ce1c77b3a..bc88f28b3 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -161,7 +161,7 @@ class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand struct ToHostProxy : public FrameLib_ToHost::Proxy, public FrameLib_PDMessageProxy { ToHostProxy(FrameLib_PDClass_ToPD *object) - : FrameLib_PDMessageProxy(*object) + : FrameLib_PDMessageProxy(object->asObject()) , mObject(object) {} @@ -207,7 +207,7 @@ class FrameLib_PDClass_ToPD : public FrameLib_PDClass_Expand mOutlets.resize(nStreams); for (unsigned long i = 0; i < nStreams; i++) - mOutlets[i] = outlet_new(*this, 0L); + mOutlets[i] = outlet_new(asObject(), 0L); mHostProxy = static_cast(mProxy.get()); } From 470b3a8e45fa85cc51fa09b04e747f6f1acc7869 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 19:07:51 +0100 Subject: [PATCH 115/222] Resolve NRT graphs when contexts update in pd --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 9493fe485..ca28c804c 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1377,9 +1377,10 @@ class FrameLib_PDClass : public PDClass_Base if (context != mObject->getContext()) { - // FIX - //mGlobal->addContextToResolve(context, *this); matchContext(context, true); + + if (!isRealtime()) + resolveNRTGraph(0.0, false); } // N.B. release because otherwise it is retained twice From 7a032e1a9d85336dc925b9eed3129a748e5ad139 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 19:08:03 +0100 Subject: [PATCH 116/222] Get the classname using the stored class --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index ca28c804c..f56275e0f 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -982,10 +982,8 @@ class FrameLib_PDClass : public PDClass_Base flags = !flags ? (kInfoDesciption | kInfoInputs | kInfoOutputs | kInfoParameters) : flags; // Start Tag - - // FIX - user object should be used here.... - - post("------------------ %s ------------------", class_getname(*getClassPointer())); + + post("------------------ %s ------------------", class_getname(*asPD())); // Description From 10cbdf4c5ff8a72ce6f5b164ccf50954e39f16a4 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 20:17:03 +0100 Subject: [PATCH 117/222] Slightly better formatting --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index f56275e0f..c9b494f38 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1061,7 +1061,7 @@ class FrameLib_PDClass : public PDClass_Base } if (type == FrameLib_Parameters::Type::Enum) for (unsigned long j = 0; j <= static_cast(params->getMax(i)); j++) - post(" [%ld] - %s", j, params->getItemString(i, j)); + post(" [%ld] - %s", j, params->getItemString(i, j)); else if (type == FrameLib_Parameters::Type::Array) post("- Array Size: %ld", params->getArraySize(i)); else if (type == FrameLib_Parameters::Type::VariableArray) From 89ebfe94979c0a4c253f76213bf70604b54d23a4 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 20:20:51 +0100 Subject: [PATCH 118/222] Deal more correctly with pd types --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 5 ++++- FrameLib_PD_Objects/framelib_pd.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index c9b494f38..5d0f79913 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1434,7 +1434,10 @@ class FrameLib_PDClass : public PDClass_Base // FIX - revise for (t_gobj *g = gl->gl_list; g; g = g->g_next) - objectMethod((t_object *) g, method, args...); + { + if (t_object *object = pd_checkobject(&g->g_pd)) + objectMethod(object, method, args...); + } } template diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index bc88f28b3..9c1bfc84c 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -139,9 +139,12 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base for (t_gobj *g = gl->gl_list; g; g = g->g_next) { - FrameLib_Multistream *flObject = toFLObject((t_object *) g); - if (flObject && flObject->getContext() == mContext) - return (t_object *) g; + if (t_object *object = pd_checkobject(&g->g_pd)) + { + FrameLib_Multistream *flObject = toFLObject(object); + if (flObject && flObject->getContext() == mContext) + return object; + } } return nullptr; From acc36f457167f06ae3349d45d136df94cd6e69b7 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 20:52:44 +0100 Subject: [PATCH 119/222] Add code for reading and writing sequentially to pd buffers for NRT --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 16 ++++---- FrameLib_PD_Objects/Common/pd_buffer.h | 41 ++++++++++++++++++- framelib.xcodeproj/project.pbxproj | 2 +- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 5d0f79913..b993789df 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -6,6 +6,8 @@ #include "g_canvas.h" +#include "pd_buffer.h" + #include "FrameLib_Global.h" #include "FrameLib_Context.h" #include "FrameLib_Parameters.h" @@ -1841,24 +1843,20 @@ class FrameLib_PDClass : public PDClass_Base void read(t_symbol *buffer, double **outs, size_t numChans, size_t size, size_t offset) { - // FIX - /* - PDBufferAccess access(*this, buffer); + // FIX - multichannel for read and write? + + pd_buffer access(buffer); for (size_t i = 0; i < numChans; i++) access.read(outs[i], size, offset, i); - */ } void write(t_symbol *buffer, const double * const *ins, size_t numChans, size_t size, size_t offset) { - // FIX - /* - PDBufferAccess access(*this, buffer); - + pd_buffer access(buffer); + for (size_t i = 0; i < numChans; i++) access.write(ins[i], size, offset, i); - */ } protected: diff --git a/FrameLib_PD_Objects/Common/pd_buffer.h b/FrameLib_PD_Objects/Common/pd_buffer.h index 2f10199fd..a29a49438 100644 --- a/FrameLib_PD_Objects/Common/pd_buffer.h +++ b/FrameLib_PD_Objects/Common/pd_buffer.h @@ -11,7 +11,7 @@ class pd_buffer fetch(t_word *data, intptr_t size) : table_fetcher(size, 1.0), mData(data) {} - t_sample operator()(intptr_t offset) + t_sample& operator()(intptr_t offset) { return mData[offset].w_float; } @@ -39,8 +39,47 @@ class pd_buffer table_read_edges(fetch(m_table, m_length), output, positions, size, amp, interp, edges, bound); } + void read(double *output, size_t length, size_t offset, size_t chan) + { + intptr_t read_length = static_cast(constrain_length(length, chan, offset)); + + fetch fetcher(m_table, m_length); + + for (intptr_t i = 0; i < read_length; i++) + output[i] = fetcher(offset + i); + + // Zero remaining samples if needed + + std::fill_n(output + read_length, length - read_length, 0.0); + } + + void write(const double *input, size_t length, size_t offset, size_t chan) + { + length = constrain_length(length, chan, offset); + + fetch writer(m_table, m_length); + + for (size_t i = 0; i < length; i++) + writer(i) = static_cast(input[i]); + } + private: + size_t constrain_length(size_t length, size_t chan, size_t offset) + { + // Request is entirely outside of the buffer's memory + + if (offset >= static_cast(m_length)) + return 0; + + // Request is partially outside of the buffer's memory + + if ((offset + length) > static_cast(m_length)) + return static_cast(m_length) - offset; + + return length; + } + t_garray *m_array; t_word *m_table; int m_length; diff --git a/framelib.xcodeproj/project.pbxproj b/framelib.xcodeproj/project.pbxproj index faaba9b12..3e38f7e82 100644 --- a/framelib.xcodeproj/project.pbxproj +++ b/framelib.xcodeproj/project.pbxproj @@ -5511,9 +5511,9 @@ isa = PBXGroup; children = ( B83E0296206674CD005925DD /* m_pd.h */, + B8D383D524B7314300E8D807 /* pd_buffer.h */, B83E0297206674CD005925DD /* PDClass_Base.h */, B83E0295206674CD005925DD /* FrameLib_PDClass.h */, - B8D383D524B7314300E8D807 /* pd_buffer.h */, ); path = Common; sourceTree = ""; From d60747a40599a747d8c14deadaea665bafa333d3 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 20:55:20 +0100 Subject: [PATCH 120/222] Note issues --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index b993789df..e9e8851fe 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1097,7 +1097,7 @@ class FrameLib_PDClass : public PDClass_Base void perform(int vec_size) { - // FIX - use alloca + // FIX - use alloca / revise perform and dsp // Copy Audio In @@ -1379,6 +1379,8 @@ class FrameLib_PDClass : public PDClass_Base { matchContext(context, true); + // FIX - multiple issues + if (!isRealtime()) resolveNRTGraph(0.0, false); } @@ -1432,9 +1434,7 @@ class FrameLib_PDClass : public PDClass_Base void iterateCanvas(t_glist *gl, t_symbol *method, Args...args) { // Call method on all objects - - // FIX - revise - + for (t_gobj *g = gl->gl_list; g; g = g->g_next) { if (t_object *object = pd_checkobject(&g->g_pd)) From 0e290153a3f734ff666d7af75a6eabf57b372634 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 22:15:46 +0100 Subject: [PATCH 121/222] Remove comment --- FrameLib_PD_Objects/framelib_pd.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 9c1bfc84c..9d75e741f 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -134,9 +134,7 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base t_object *searchPatch(t_glist *gl) { // Call method on all objects - - // FIX - revise - + for (t_gobj *g = gl->gl_list; g; g = g->g_next) { if (t_object *object = pd_checkobject(&g->g_pd)) From 819faf70f3c84a4c42e56e7b5aa1028841eb27e7 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 22:16:06 +0100 Subject: [PATCH 122/222] Parse "attributes" in pd --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index e9e8851fe..e8087687d 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -889,10 +889,20 @@ class FrameLib_PDClass : public PDClass_Base return false; } + static bool isAttributeTag(t_symbol *sym) + { + return strlen(sym->s_name) > 1 && sym->s_name[0] == '-'; + } + + static bool isNamedAttributeTag(t_symbol *sym, const char *tag) + { + return isAttributeTag(sym) && !strcmp(sym->s_name + 1, tag); + } + static bool isTag(t_atom *a) { t_symbol *sym = atom_getsymbol_default(a); - return atom_gettype(a) == A_SYMBOL && (isParameterTag(sym) || isInputTag(sym)); + return atom_gettype(a) == A_SYMBOL && (isParameterTag(sym) || isInputTag(sym) || isAttributeTag(sym)); } // Constructor and Destructor @@ -907,6 +917,10 @@ class FrameLib_PDClass : public PDClass_Base , mResolved(false) , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } { + // Attributes + + parseAttributes(argc, argv); + // Stream count if (argc && getStreamCount(argv)) @@ -1839,6 +1853,52 @@ class FrameLib_PDClass : public PDClass_Base } } + // Attribute parsing + + void parseAttributes(long argc, t_atom *argv) + { + long i = 0; + + // Parse attribute tags + + while (i < argc) + { + t_symbol *sym = atom_getsymbol_default(argv + i++); + + if (isAttributeTag(sym)) + { + // Check attributes are valid + + bool commonAttributes = isNamedAttributeTag(sym, "rt") || isNamedAttributeTag(sym, "id"); + bool bufferAttribute = handlesAudio() && isNamedAttributeTag(sym, "buffer"); + + if (!commonAttributes && !bufferAttribute) + { + pd_error(asObject(), "unknown attribute %s", sym->s_name); + continue; + } + + // Check for missing values + + if ((i >= argc) || isTag(argv + i)) + { + pd_error(asObject(), "no values given for attribute %s", sym->s_name); + continue; + } + + if (isNamedAttributeTag(sym, "rt")) + rtSet(atom_getfloat(argv + i++)); + else if (isNamedAttributeTag(sym, "id")) + idSet(atom_getsymbol_default(argv + i++)); + else if (isNamedAttributeTag(sym, "buffer")) + bufferSet(atom_getsymbol_default(argv + i++)); + + if (i < argc && !isTag(argv + i)) + pd_error(asObject(), "stray items after attribute %s", sym->s_name); + } + } + } + // Buffer access (read and write multichannel buffers) void read(t_symbol *buffer, double **outs, size_t numChans, size_t size, size_t offset) From 8c0c20b40a09dfdaf038003645487bd1fb418818 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 22:46:37 +0100 Subject: [PATCH 123/222] Fix buffer writing --- FrameLib_PD_Objects/Common/pd_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/pd_buffer.h b/FrameLib_PD_Objects/Common/pd_buffer.h index a29a49438..d544f2ac0 100644 --- a/FrameLib_PD_Objects/Common/pd_buffer.h +++ b/FrameLib_PD_Objects/Common/pd_buffer.h @@ -60,7 +60,7 @@ class pd_buffer fetch writer(m_table, m_length); for (size_t i = 0; i < length; i++) - writer(i) = static_cast(input[i]); + writer(i + offset) = static_cast(input[i]); } private: From 764089d623e58fd22974794036f046e42b6e8ad9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 22:46:49 +0100 Subject: [PATCH 124/222] Default buffer attribute --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1 + 1 file changed, 1 insertion(+) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index e8087687d..bc372d6e8 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -915,6 +915,7 @@ class FrameLib_PDClass : public PDClass_Base , mConnectionsUpdated(false) , mContextPatchConfirmed(false) , mResolved(false) + , mBuffer(gensym("")) , mPDContext{ T::sType == ObjectType::Scheduler, mCanvas, gensym("") } { // Attributes From 0708b21ae703f201c87079f2705df06e4ecfbb99 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 22:56:17 +0100 Subject: [PATCH 125/222] Redraw arrays after writing --- FrameLib_PD_Objects/Common/pd_buffer.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FrameLib_PD_Objects/Common/pd_buffer.h b/FrameLib_PD_Objects/Common/pd_buffer.h index d544f2ac0..e931360a3 100644 --- a/FrameLib_PD_Objects/Common/pd_buffer.h +++ b/FrameLib_PD_Objects/Common/pd_buffer.h @@ -61,6 +61,9 @@ class pd_buffer for (size_t i = 0; i < length; i++) writer(i + offset) = static_cast(input[i]); + + if (length) + garray_redraw(m_array); } private: From 400e5027bfbfe311e8ce58d7e67b8b45a2661bb5 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 23:07:14 +0100 Subject: [PATCH 126/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index ac1b39e49..9dbd416c5 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -2,8 +2,8 @@ **Status and Building** - All (165 out of 165) framelib objects get built to a single library files -- Realtime operation is supported, but non-realtime support is incomplete -- There are some key issues to note below +- Realtime operation and non-realtime operation is supported +- There are some key issues to note below and some minor niggles to be ironed out To build you should be able to run make on this directory and then copy framelib_pd.d_fat and set it to load on startup @@ -29,13 +29,14 @@ I'm not sure if there should be a VS project for windows or not. - Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. -- Attributes - non-realtime in Max is set by attributes. Part of the misssing support in pd is to sort these (which must be supported manually) -- My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. - - Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good - Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful) +- Attributes - non-realtime in Max is set by attributes. Part of the misssing support in pd is to sort these (which must be supported manually) +- My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. +- sigmund~ uses dashes like the command line so I've copied that for now. [REVIEW] + **Review** - Some pd correctness has been reviewed (DONE): @@ -45,6 +46,7 @@ I'm not sure if there should be a VS project for windows or not. - Some pd correctness needs review: - PD-specific or custom objects (read/info/topd/frompd/contextcontrol/expressions) - Messages that would take ints in Max + - Whether garray_usedindsp should be used - resetting dsp when resolving connections **Documentation** From 0cfcd7960da53e50a1f87f5246c02178084656d1 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 23:07:23 +0100 Subject: [PATCH 127/222] Add an NRT pd example --- Testing/02_PD/fl_test3.pd | 97 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Testing/02_PD/fl_test3.pd diff --git a/Testing/02_PD/fl_test3.pd b/Testing/02_PD/fl_test3.pd new file mode 100644 index 000000000..11c1ba4c8 --- /dev/null +++ b/Testing/02_PD/fl_test3.pd @@ -0,0 +1,97 @@ +#N canvas 358 90 1114 850 12; +#X obj 244 577 unsynced.fl.sink~; +#X obj 210 637 *~ 0.2; +#X obj 353 628 *~ 0.2; +#X obj 205 680 dac~; +#X obj 153 540 fl.*~; +#X obj 302 538 fl.*~; +#X obj 184 507 fl.cos~; +#X obj 395 419 fl.sin~; +#X obj 149 451 fl.window~ hann /size 16384; +#X obj 149 378 fl.read~ samps /units ms; +#X obj 151 338 fl.+~; +#X obj 151 306 fl.samplerate~ samples->ms; +#X obj 145 271 fl.ramp~ /mode requested /length 1000; +#X obj 133 106 fl.random~; +#X obj 388 106 fl.random~; +#X obj 566 105 fl.random~; +#X obj 135 150 fl.map~ linear 0 1 10000 20000; +#X obj 567 142 fl.map~ exp 0 1 20 16000; +#X obj 785 106 fl.random~; +#X obj 787 141 fl.*~ 1.5708; +#X obj 135 200 fl.tag~ length; +#X obj 148 409 fl.svf~ 500 0.7 bandpass; +#X obj 559 193 fl.tag~ freq; +#X obj 675 386 soundfiler; +#X floatatom 675 412 0 0 0 0 - - - 0; +#X obj 675 324 loadbang; +#X msg 675 354 read -resize voice.wav samps; +#X obj 921 370 table samps; +#X obj 389 150 fl.*~ 1000; +#N canvas 0 22 450 278 (subpatch) 0; +#X array array 17942 float 2; +#X coords 0 1 17942 -1 200 140 1 0 0; +#X restore 651 641 graph; +#X obj 434 635 send array; +#X obj 433 598 list prepend 0; +#X obj 414 491 fl.pack~ 2; +#X obj 468 458 fl.length~; +#X msg 506 555 \; array resize \$1; +#X obj 433 526 fl.topd~ =2; +#X msg 265 41 rt 1; +#X obj 45 77 unsynced.fl.interval~ 500 -rt 0; +#X obj 28 607 unsynced.fl.sink~ -buffer outputs; +#X msg 119 31 process 60000; +#X obj 820 432 table outputs 120000; +#X msg 61 30 reset; +#X text 560 477 This patch is a non realimte verison of the stero granular +(2b) example from the Max tests. Note that the interla pd sounds folder +needs to be in the search path; +#X text 631 559 This seems to make the audio pause if I select a menu +; +#X connect 0 1 2 0; +#X connect 1 0 3 0; +#X connect 2 0 3 1; +#X connect 4 0 38 1; +#X connect 5 0 0 1; +#X connect 6 0 4 1; +#X connect 7 0 5 1; +#X connect 8 0 4 0; +#X connect 8 0 5 0; +#X connect 8 0 32 0; +#X connect 8 0 33 0; +#X connect 9 0 21 0; +#X connect 10 0 9 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 16 0; +#X connect 14 0 28 0; +#X connect 15 0 17 0; +#X connect 16 0 20 0; +#X connect 17 0 22 0; +#X connect 18 0 19 0; +#X connect 19 0 6 0; +#X connect 19 0 7 0; +#X connect 20 0 12 1; +#X connect 21 0 8 0; +#X connect 22 0 21 1; +#X connect 23 0 24 0; +#X connect 25 0 26 0; +#X connect 26 0 23 0; +#X connect 28 0 10 1; +#X connect 31 0 30 0; +#X connect 32 0 35 0; +#X connect 33 0 32 1; +#X connect 35 0 31 0; +#X connect 35 1 34 0; +#X connect 36 0 37 0; +#X connect 37 0 0 0; +#X connect 37 0 38 0; +#X connect 37 1 13 0; +#X connect 37 1 14 0; +#X connect 37 1 15 0; +#X connect 37 1 18 0; +#X connect 37 1 12 0; +#X connect 38 1 1 0; +#X connect 39 0 37 0; +#X connect 41 0 37 0; From e3beacf4a7380d5f8b98596edb87300aa9462694 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 23:25:46 +0100 Subject: [PATCH 128/222] Parse attributes for fl.contextcontrol~ in pd --- FrameLib_PD_Objects/framelib_pd.cpp | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 9d75e741f..36ae39b23 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -29,6 +29,43 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base : mPDContext{ true, canvas_getcurrent(), gensym("") } , mContext(mGlobal->makeContext(mPDContext)) { + long i = 0; + + // Parse attribute tags + + while (i < argc) + { + t_symbol *sym = atom_getsymbol_default(argv + i++); + + if (PDClass::isAttributeTag(sym)) + { + // Check attributes are valid + + if (!PDClass::isNamedAttributeTag(sym, "rt") && !PDClass::isNamedAttributeTag(sym, "id")) + { + pd_error(asObject(), "unknown attribute %s", sym->s_name); + continue; + } + + // Check for missing values + + if ((i >= argc) || PDClass::isTag(argv + i)) + { + pd_error(asObject(), "no values given for attribute %s", sym->s_name); + continue; + } + + if (PDClass::isNamedAttributeTag(sym, "rt")) + rtSet(atom_getfloat(argv + i++)); + else if (PDClass::isNamedAttributeTag(sym, "id")) + idSet(atom_getsymbol_default(argv + i++)); + + if (i < argc && !PDClass::isTag(argv + i)) + pd_error(asObject(), "stray items after attribute %s", sym->s_name); + } + else + pd_error(asObject(), "additional unrecognised arguments"); + } } ~FrameLib_PDClass_ContextControl() From 4d6ff3228730fa1f29c20b743a6cffeb826679a7 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 3 Aug 2022 23:37:18 +0100 Subject: [PATCH 129/222] Allow the context control to resolve graphs where needed --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 7 +++++++ FrameLib_PD_Objects/framelib_pd.cpp | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index bc372d6e8..8d9bde979 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -78,6 +78,7 @@ struct FrameLib_PDPrivate static inline const char *messageUnwrap() { return "__fl.unwrap"; } static inline const char *messageIsWrapper() { return "__fl.is_wrapper"; } static inline const char *messageFindAudioObjects() { return "__fl.find_audio_objects"; } + static inline const char *messageResolveContext() { return "__fl.resolve_context"; } static inline const char *messageResolveConnections() { return "__fl.resolve_connections"; } static inline const char *messageMarkUnresolved() { return "__fl.mark_unresolved"; } static inline const char *messageMakeAutoOrdering() { return "__fl.make_auto_ordering"; } @@ -859,6 +860,7 @@ class FrameLib_PDClass : public PDClass_Base // External Methods + addMethod(c, (t_method) &extResolveContext, FrameLib_PDPrivate::messageResolveContext()); addMethod(c, (t_method) &extResolveConnections, FrameLib_PDPrivate::messageResolveConnections()); addMethod(c, (t_method) &extMarkUnresolved, FrameLib_PDPrivate::messageMarkUnresolved()); addMethod(c, (t_method) &extMakeAutoOrdering, FrameLib_PDPrivate::messageMakeAutoOrdering()); @@ -1300,6 +1302,11 @@ class FrameLib_PDClass : public PDClass_Base objects->push_back(FrameLib_PDNRTAudio{x->mObject.get(), x->mBuffer}); } + static void extResolveContext(FrameLib_PDClass *x) + { + x->resolveGraph(sys_getsr(), static_cast(maxBlockSize()), false); + } + static void extResolveConnections(FrameLib_PDClass *x, intptr_t *flag) { bool updated = x->resolveConnections(); diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 36ae39b23..4275b0e06 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -138,8 +138,7 @@ class FrameLib_PDClass_ContextControl : public PDClass_Base return; } - // FIX - //objectMethod(object, FrameLib_PDPrivate::messageResolveContext()); + objectMethod(object, FrameLib_PDPrivate::messageResolveContext()); auto replace = FrameLib_TypeAliases::makeReplaceStrings(); From 48cce9e5dab495f1de1d434249336dd29e547e31 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 05:08:37 +0100 Subject: [PATCH 130/222] Remove unused commented code --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1 - 1 file changed, 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 8d9bde979..b2ada5388 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -384,7 +384,6 @@ class FrameLib_PDGlobals : public PDClass_Base enum ConnectionMode : intptr_t { kConnect, kConfirm, kDoubleCheck }; using PDConnection = FrameLib_Connection; - //using ConnectAccept = FrameLib_MaxConnectAccept; using Lock = FrameLib_Lock; private: From 2d647e1729d7077ec4bfcf8ae4a16ce9a36463a6 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 05:16:25 +0100 Subject: [PATCH 131/222] Avoid issues when updating to NRT with DSP on --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index b2ada5388..42e856993 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -412,6 +412,7 @@ class FrameLib_PDGlobals : public PDClass_Base } }; + enum DSPDeferMode { kOff, kDefer, kNeedResume }; enum RefDataItem { kKey, kCount, kLock, kLastResolved, kFinal, kHandler, kQueuePtr }; using QueuePtr = std::unique_ptr; @@ -490,6 +491,7 @@ class FrameLib_PDGlobals : public PDClass_Base : mReportContextErrors(false) , mRTNotifier(&mRTGlobal) , mNRTNotifier(&mNRTGlobal) + , mDSPDefer(kOff) , mRTGlobal(nullptr) , mNRTGlobal(nullptr) {} @@ -599,6 +601,34 @@ class FrameLib_PDGlobals : public PDClass_Base PDConnection getConnection() const { return mConnection; } ConnectionMode getConnectionMode() const { return mConnectionMode; } + // DSP Resume (allows deferal when resolving contexts) + + void dspDeferResume(bool state) + { + if (state) + { + if (mDSPDefer == kOff) + mDSPDefer = kDefer; + } + else + { + post("end resolve %ld", mDSPDefer == kNeedResume); + + if (mDSPDefer == kNeedResume) + dspResume(true); + + mDSPDefer = kOff; + } + } + + void dspResumeRequest(bool oldState) + { + if (oldState && mDSPDefer != kOff) + mDSPDefer = kNeedResume; + else + dspResume(oldState); + } + private: // Context methods @@ -689,6 +719,8 @@ class FrameLib_PDGlobals : public PDClass_Base std::deque mQueue; RefMap mContextRefs; + DSPDeferMode mDSPDefer; + FrameLib_Global *mRTGlobal; FrameLib_Global *mNRTGlobal; }; @@ -1398,6 +1430,9 @@ class FrameLib_PDClass : public PDClass_Base if (context != mObject->getContext()) { + if (!mGlobal->isRealtime(context)) + mGlobal->dspDeferResume(true); + matchContext(context, true); // FIX - multiple issues @@ -1446,7 +1481,7 @@ class FrameLib_PDClass : public PDClass_Base mGlobal->pushToQueue(asObject()); - dspResume(oldState); + mGlobal->dspResumeRequest(oldState); } // Private connection methods @@ -1487,6 +1522,8 @@ class FrameLib_PDClass : public PDClass_Base intptr_t updated = false; + mGlobal->dspDeferResume(true); + mGlobal->setReportContextErrors(true); traversePatch(FrameLib_PDPrivate::messageMarkUnresolved()); traversePatch(FrameLib_PDPrivate::messageResolveConnections(), &updated); @@ -1506,6 +1543,8 @@ class FrameLib_PDClass : public PDClass_Base if (updated || force) traversePatch(FrameLib_PDPrivate::messageReset(), &sampleRate, vecSize); + + mGlobal->dspDeferResume(false); } void resolveNRTGraph(double sampleRate, bool forceReset) From c211c3b10877add56511c9e69a382dc699d52135 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 08:02:59 +0100 Subject: [PATCH 132/222] Remove debug / comments --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 42e856993..5e9015a25 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -612,8 +612,6 @@ class FrameLib_PDGlobals : public PDClass_Base } else { - post("end resolve %ld", mDSPDefer == kNeedResume); - if (mDSPDefer == kNeedResume) dspResume(true); @@ -1434,9 +1432,7 @@ class FrameLib_PDClass : public PDClass_Base mGlobal->dspDeferResume(true); matchContext(context, true); - - // FIX - multiple issues - + if (!isRealtime()) resolveNRTGraph(0.0, false); } From e419c1e53d2d388c07d46c89825c421bba0c6092 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 08:07:08 +0100 Subject: [PATCH 133/222] Correct proxy name --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 5e9015a25..e088f7367 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -854,7 +854,7 @@ class FrameLib_PDClass : public PDClass_Base // If handles audio/scheduler then make wrapper class and name the inner object differently.. std::string internalClassName = className; - std::string proxyClassName; + std::string proxyClassName = className; if (T::sHandlesAudio) internalClassName.insert(0, "unsynced."); From c79e499c7c32715dccc3feaf64e190b8ccef7785 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 08:13:29 +0100 Subject: [PATCH 134/222] Proxies should not be patchable --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index e088f7367..844b90fa8 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -861,7 +861,7 @@ class FrameLib_PDClass : public PDClass_Base proxyClassName.append(".proxy"); PDClass_Base::makeClass(internalClassName.c_str()); - PDClass_Base::makeClass(proxyClassName.c_str()); + PDClass_Base::makeClass(proxyClassName.c_str(), CLASS_PD); } static void classInit(t_class *c, const char *classname) From 912dd597978e3ef28186c045fbb0e2ce675610d4 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 13:13:41 +0100 Subject: [PATCH 135/222] Remove unused methods --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 844b90fa8..179ba7f22 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -88,8 +88,6 @@ struct FrameLib_PDPrivate static inline const char *messageConnectionConfirm() { return "__fl.connection_confirm"; } static inline const char *messageConnectionUpdate() { return "__fl.connection_update"; } static inline const char *messageGetFrameLibObject() { return "__fl.get_framelib_object"; } - static inline const char *messageGetNumAudioIns() { return "__fl.get_num_audio_ins"; } - static inline const char *messageGetNumAudioOuts() { return "__fl.get_num_audio_outs"; } static FrameLib_Multistream *toFrameLibObject(t_object *object, uint64_t& versionCheck) { @@ -899,8 +897,6 @@ class FrameLib_PDClass : public PDClass_Base addMethod(c, (t_method) &extConnectionConfirm, FrameLib_PDPrivate::messageConnectionConfirm()); addMethod(c, (t_method) &extConnectionUpdate, FrameLib_PDPrivate::messageConnectionUpdate()); addMethod(c, (t_method) &extGetFLObject, FrameLib_PDPrivate::messageGetFrameLibObject()); - addMethod(c, (t_method) &extGetNumAudioIns, FrameLib_PDPrivate::messageGetNumAudioIns()); - addMethod(c, (t_method) &extGetNumAudioOuts, FrameLib_PDPrivate::messageGetNumAudioOuts()); } // Tag checks @@ -1383,16 +1379,6 @@ class FrameLib_PDClass : public PDClass_Base return (intptr_t) x->mDirectlyConnected[index]; } - static intptr_t extGetNumAudioIns(FrameLib_PDClass *x) - { - return x->getNumAudioIns(); - } - - static intptr_t extGetNumAudioOuts(FrameLib_PDClass *x) - { - return x->getNumAudioOuts(); - } - // id attribute void idSet(t_symbol *name) @@ -1570,20 +1556,6 @@ class FrameLib_PDClass : public PDClass_Base return mismatch; } - // Get the number of audio ins/outs safely from a generic pointer - - static long getNumAudioIns(t_object *x) - { - intptr_t numAudioIns = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioIns()); - return static_cast(numAudioIns); - } - - static long getNumAudioOuts(t_object *x) - { - intptr_t numAudioOuts = objectMethod(x, FrameLib_PDPrivate::messageGetNumAudioOuts()); - return static_cast(numAudioOuts); - } - // Helpers for connection methods static bool isOrderingInput(long index, FLObject *object) From df39487ce080df8d62868f8822e163f5266567ae Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 13:14:21 +0100 Subject: [PATCH 136/222] Update base class to support additional signal ins (created in the class constructor) --- FrameLib_PD_Objects/Common/PDClass_Base.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index ce07ca56e..364c94283 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -283,19 +283,19 @@ class PDClass_Base static void dspInit(t_class *c) { class_addmethod(c, nullfn, gensym("signal"), A_NULL); } - void dspSetup(unsigned long numSigIns, unsigned long numSigOuts) + void dspSetup(size_t numSigIns, size_t numSigOuts) { mSigIns.resize(numSigIns); mSigOuts.resize(numSigOuts); // Create signal inlets - for (unsigned long i = 0; numSigIns && i < (numSigIns - 1); i++) + for (size_t i = 0; numSigIns && i < (numSigIns - 1); i++) signalinlet_new(asObject(), 0.0); // Create signal outlets - for (unsigned long i = 0; i < numSigOuts; i++) + for (size_t i = 0; i < numSigOuts; i++) outlet_new(asObject(), gensym("signal")); } @@ -322,6 +322,13 @@ class PDClass_Base { canvas_resume_dsp(oldState); } + + // Use if you need to create signal inlets external to the dspSetup method (to attach proxies etc.) + + void dspInsResize(size_t numSigIns) + { + mSigIns.resize(std::max(numSigIns, mSigIns.size())); + } const t_sample *getAudioIn(unsigned long idx) { return mSigIns[idx]; } t_sample *getAudioOut(unsigned long idx) { return mSigOuts[idx]; } From fad63503bb5f1063be25c1cd09ac8daeac93b348 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 13:16:13 +0100 Subject: [PATCH 137/222] Remove "unsynced." prefix --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 179ba7f22..3d32bda2b 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -854,9 +854,6 @@ class FrameLib_PDClass : public PDClass_Base std::string internalClassName = className; std::string proxyClassName = className; - if (T::sHandlesAudio) - internalClassName.insert(0, "unsynced."); - proxyClassName.append(".proxy"); PDClass_Base::makeClass(internalClassName.c_str()); PDClass_Base::makeClass(proxyClassName.c_str(), CLASS_PD); From 9c6f7f0bdf3fddc5bf745cc99a1fab96c8b4e31d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 14:05:18 +0100 Subject: [PATCH 138/222] Allow both inputs and outputs to be resized --- FrameLib_PD_Objects/Common/PDClass_Base.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 364c94283..66c332fe5 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -325,9 +325,10 @@ class PDClass_Base // Use if you need to create signal inlets external to the dspSetup method (to attach proxies etc.) - void dspInsResize(size_t numSigIns) + void dspResize(size_t numSigIns, size_t numSigOuts) { mSigIns.resize(std::max(numSigIns, mSigIns.size())); + mSigOuts.resize(std::max(numSigOuts, mSigOuts.size())); } const t_sample *getAudioIn(unsigned long idx) { return mSigIns[idx]; } From 5a68b00b20ac1648087b5a940a5646d2852669c3 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 14:25:40 +0100 Subject: [PATCH 139/222] Preliminary signal synchronisation pd wrapper --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 117 ++++++++++-------- 1 file changed, 64 insertions(+), 53 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 3d32bda2b..5989a4de5 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -24,12 +24,6 @@ #include #include -extern "C" -{ - t_signal *signal_newfromcontext(int borrowed); - void signal_makereusable(t_signal *sig); -} - // Deal with private strings and versioning struct FrameLib_PDPrivate @@ -738,27 +732,37 @@ class FrameLib_PDClass : public PDClass_Base using NumericType = FrameLib_Parameters::NumericType; using ClipMode = FrameLib_Parameters::ClipMode; - struct PDProxy : public PDClass_Base + struct PDInputProxy : public PDClass_Base { static t_pd *create(FrameLib_PDClass *owner, int index) { - t_pd *proxy = pd_new(*PDProxy::getClassPointer()); + t_pd *proxy = pd_new(*PDInputProxy::getClassPointer()); - ((PDProxy *)proxy)->mOwner = owner; - ((PDProxy *)proxy)->mIndex = index; + ((PDInputProxy *)proxy)->mOwner = owner; + ((PDInputProxy *)proxy)->mIndex = index; return proxy; } static void classInit(t_class *c, const char *classname) { - addMethod(c, "frame"); + dspInit(c); + + addMethod(c, "anything"); + } + + PDInputProxy(t_object *x, t_symbol *sym, long ac, t_atom *av) : mOwner(nullptr), mIndex(-1) {} + + void anything(t_symbol *s, long ac, t_atom *av) + { + if (!s) + mOwner->frameInlet(mIndex); } - PDProxy(t_object *x, t_symbol *sym, long ac, t_atom *av) : mOwner(nullptr), mIndex(-1) {} void frame() { + post("frame"); mOwner->frameInlet(mIndex); } @@ -856,13 +860,13 @@ class FrameLib_PDClass : public PDClass_Base proxyClassName.append(".proxy"); PDClass_Base::makeClass(internalClassName.c_str()); - PDClass_Base::makeClass(proxyClassName.c_str(), CLASS_PD); + PDClass_Base::makeClass(proxyClassName.c_str(), CLASS_PD); } static void classInit(t_class *c, const char *classname) { addMethod, &FrameLib_PDClass::info>(c, "info"); - addMethod, &FrameLib_PDClass::frame>(c, "frame"); + addMethod, &FrameLib_PDClass::frame>(c, "signal"); addMethod, &FrameLib_PDClass::dsp>(c); // Attributes @@ -878,8 +882,6 @@ class FrameLib_PDClass : public PDClass_Base addMethod, &FrameLib_PDClass::process>(c, "process"); addMethod(c, (t_method) &extFindAudio, FrameLib_PDPrivate::messageFindAudioObjects()); - - dspInit(c); } // External Methods @@ -969,26 +971,33 @@ class FrameLib_PDClass : public PDClass_Base mOutputs.resize(getNumOuts()); mDirectlyConnected.resize(getNumIns(), false); + // Create signal inlets + signal outlets + dspSetup(getNumAudioIns(), getNumAudioOuts()); - // Create frame inlets - N.B. - we create a proxy if the inlet is not the first inlet (not the first frame input or the object handles audio) + // Create frame inlets + // N.B. - we create a proxy if the inlet is not the first inlet (not the first frame input or the object has audio ins) for (long i = 0; i < numIns; i++) { - if (i || handlesAudio()) + if (i || getNumAudioIns()) { - t_pd *proxy = PDProxy::create(this, (int) (getNumAudioIns() + i)); - inlet_new(asObject(), proxy, gensym("frame"), gensym("frame")); + t_pd *proxy = PDInputProxy::create(this, (int) (getNumAudioIns() + i)); + inlet_new(asObject(), proxy, gensym("signal"), gensym("signal")); mInputs[i] = Input(proxy, asObject(), i); } else mInputs[i] = Input(nullptr, asObject(), i); } - // Create frame outlets + // Create frame outlets (as signals) for (unsigned long i = 0; i < getNumOuts(); i++) - mOutputs[i] = outlet_new(asObject(), gensym("frame")); + mOutputs[i] = outlet_new(asObject(), gensym("signal")); + + // Resize the signal IO + + dspResize(getNumAudioIns() + numIns, getNumAudioOuts() + getNumOuts()); } ~FrameLib_PDClass() @@ -1123,12 +1132,10 @@ class FrameLib_PDClass : public PDClass_Base bool handlesAudio() const { return T::sHandlesAudio; } bool supportsOrderingConnections() const { return mObject->supportsOrderingConnections(); } - long audioIOSize(long chans) const { return chans + (handlesAudio() ? 1 : 0); } - long getNumIns() const { return static_cast(mObject->getNumIns()); } long getNumOuts() const { return static_cast(mObject->getNumOuts()); } - long getNumAudioIns() const { return audioIOSize(mObject->getNumAudioIns()); } - long getNumAudioOuts() const { return audioIOSize(mObject->getNumAudioOuts()); } + long getNumAudioIns() const { return mObject->getNumAudioIns(); } + long getNumAudioOuts() const { return mObject->getNumAudioOuts(); } unsigned long getSpecifiedStreams() const { return mSpecifiedStreams; } @@ -1138,21 +1145,29 @@ class FrameLib_PDClass : public PDClass_Base { // FIX - use alloca / revise perform and dsp - // Copy Audio In - - for (int i = 0; i < (getNumAudioIns() - 1); i++) - for (int j = 0; j < vec_size; j++) - mSigIns[i][j] = getAudioIn(i + 1)[j]; - - // N.B. Plus one due to sync inputs + if (isRealtime()) + { + // Copy Audio In - mObject->blockUpdate(mSigIns.data(), mSigOuts.data(), vec_size); + for (int i = 0; i < getNumAudioIns(); i++) + for (int j = 0; j < vec_size; j++) + mSigIns[i][j] = getAudioIn(i)[j]; + + mObject->blockUpdate(mSigIns.data(), mSigOuts.data(), vec_size); - for (int i = 0; i < (getNumAudioOuts() - 1); i++) - for (int j = 0; j < vec_size; j++) - getAudioOut(i + 1)[j] = mSigOuts[i][j]; + for (int i = 0; i < getNumAudioOuts(); i++) + for (int j = 0; j < vec_size; j++) + getAudioOut(i)[j] = mSigOuts[i][j]; - mGlobal->contextMessages(getContext(), asObject()); + mGlobal->contextMessages(getContext(), asObject()); + } + else + { + // Zero outputs + + for (int i = 0; i < getNumAudioOuts(); i++) + std::fill_n(getAudioOut(i), vec_size, t_sample(0)); + } } void dsp(t_signal **sp) @@ -1167,10 +1182,8 @@ class FrameLib_PDClass : public PDClass_Base // Reset DSP - t_signal *temp = signal_newfromcontext(0); - double samplingRate = temp->s_sr; - int vec_size = temp->s_vecsize; - signal_makereusable(temp); + double samplingRate = sp[0]->s_sr; + int vec_size = sp[0]->s_vecsize; mObject->reset(samplingRate, vec_size); @@ -1186,16 +1199,16 @@ class FrameLib_PDClass : public PDClass_Base addPerform::perform>(sp); mGlobal->finalObject(getContext()) = asObject(); - mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts() -2)); - mSigIns.resize(getNumAudioIns() - 1); - mSigOuts.resize(getNumAudioOuts() - 1); + mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts())); + mSigIns.resize(getNumAudioIns()); + mSigOuts.resize(getNumAudioOuts()); double *inVecs = mTemp.data(); - double *outVecs = inVecs + ((getNumAudioIns() - 1) * vec_size); + double *outVecs = inVecs + (getNumAudioIns() * vec_size); - for (int i = 0; i < getNumAudioIns() - 1; i++) + for (int i = 0; i < getNumAudioIns(); i++) mSigIns[i] = inVecs + (i * vec_size); - for (int i = 0; i < getNumAudioOuts() - 1; i++) + for (int i = 0; i < getNumAudioOuts(); i++) mSigOuts[i] = outVecs + (i * vec_size); } } @@ -1285,15 +1298,13 @@ class FrameLib_PDClass : public PDClass_Base void frame() { - frameInlet(0); + frameInlet(-getNumAudioIns()); } void frameInlet(long index) { const PDConnection connection = mGlobal->getConnection(); - - index -= getNumAudioIns(); - + // Make sure there's an object to connect that has the same framelib version if (!connection.mObject || versionMismatch(connection.mObject, index, true)) @@ -1613,7 +1624,7 @@ class FrameLib_PDClass : public PDClass_Base { mGlobal->setConnection(PDConnection(asObject(), index)); mGlobal->setConnectionMode(mode); - outlet_anything(mOutputs[index], gensym("frame"), 0, nullptr); + outlet_anything(mOutputs[index], gensym("signal"), 0, nullptr); mGlobal->setConnection(PDConnection()); } From ff5fbd5796ced05983249567f05e4236d9f88315 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 14:25:48 +0100 Subject: [PATCH 140/222] Update test patches for pd --- Testing/02_PD/fl_test1.pd | 16 +++--- Testing/02_PD/fl_test2.pd | 74 +++++++++++++------------- Testing/02_PD/fl_test3.pd | 106 +++++++++++++++++++------------------- 3 files changed, 96 insertions(+), 100 deletions(-) diff --git a/Testing/02_PD/fl_test1.pd b/Testing/02_PD/fl_test1.pd index bd1c7630d..614208266 100644 --- a/Testing/02_PD/fl_test1.pd +++ b/Testing/02_PD/fl_test1.pd @@ -1,12 +1,10 @@ #N canvas 280 199 486 473 12; -#X obj 74 37 unsynced.fl.interval~ 4000; -#X obj 155 228 unsynced.fl.sink~; -#X obj 327 50 noise~; +#X obj 193 46 noise~; #X obj 136 314 dac~; -#X obj 160 142 unsynced.fl.source~ /length 2000; -#X connect 0 0 4 0; -#X connect 0 1 4 2; -#X connect 1 1 3 0; -#X connect 2 0 4 1; +#X obj 270 41 fl.interval~ 4000; +#X obj 160 142 fl.source~ /length 2000; +#X obj 155 228 fl.sink~; +#X connect 0 0 3 0; +#X connect 2 0 3 1; +#X connect 3 0 4 0; #X connect 4 0 1 0; -#X connect 4 1 1 1; diff --git a/Testing/02_PD/fl_test2.pd b/Testing/02_PD/fl_test2.pd index d4fea5369..b1454a7f8 100644 --- a/Testing/02_PD/fl_test2.pd +++ b/Testing/02_PD/fl_test2.pd @@ -1,6 +1,4 @@ #N canvas 316 325 1076 735 12; -#X obj 81 551 unsynced.fl.sink~; -#X obj 227 550 unsynced.fl.sink~; #X obj 193 610 *~ 0.2; #X obj 336 601 *~ 0.2; #X obj 188 653 dac~; @@ -36,43 +34,43 @@ be in the search path; #000000 #000000; #X obj 404 538 fl.topd~ =4; #X obj 372 123 fl.*~ 1000; -#X obj 99 21 unsynced.fl.interval~ 50; -#X connect 0 1 2 0; -#X connect 1 1 3 0; -#X connect 2 0 4 0; -#X connect 3 0 4 1; -#X connect 5 0 0 1; -#X connect 6 0 1 1; -#X connect 7 0 5 1; -#X connect 8 0 6 1; -#X connect 8 0 32 0; -#X connect 9 0 5 0; -#X connect 9 0 6 0; -#X connect 10 0 22 0; +#X obj 111 19 fl.interval~ 50; +#X obj 124 554 fl.sink~; +#X obj 277 556 fl.sink~; +#X connect 0 0 2 0; +#X connect 1 0 2 1; +#X connect 3 0 33 0; +#X connect 4 0 34 0; +#X connect 5 0 3 1; +#X connect 6 0 4 1; +#X connect 6 0 30 0; +#X connect 7 0 3 0; +#X connect 7 0 4 0; +#X connect 8 0 20 0; +#X connect 9 0 8 0; +#X connect 10 0 9 0; #X connect 11 0 10 0; -#X connect 12 0 11 0; -#X connect 13 0 12 0; -#X connect 14 0 17 0; -#X connect 15 0 33 0; -#X connect 16 0 18 0; -#X connect 17 0 21 0; -#X connect 18 0 23 0; -#X connect 19 0 20 0; +#X connect 12 0 15 0; +#X connect 13 0 31 0; +#X connect 14 0 16 0; +#X connect 15 0 19 0; +#X connect 16 0 21 0; +#X connect 17 0 18 0; +#X connect 18 0 5 0; +#X connect 18 0 6 0; +#X connect 19 0 11 1; #X connect 20 0 7 0; -#X connect 20 0 8 0; -#X connect 21 0 13 1; -#X connect 22 0 9 0; -#X connect 23 0 22 1; +#X connect 21 0 20 1; +#X connect 22 0 23 0; #X connect 24 0 25 0; -#X connect 26 0 27 0; -#X connect 27 0 24 0; -#X connect 32 0 30 0; -#X connect 32 0 31 0; -#X connect 33 0 11 1; -#X connect 34 0 0 0; +#X connect 25 0 22 0; +#X connect 30 0 28 0; +#X connect 30 0 29 0; +#X connect 31 0 9 1; +#X connect 32 0 12 0; +#X connect 32 0 13 0; +#X connect 32 0 14 0; +#X connect 32 0 17 0; +#X connect 32 0 11 0; +#X connect 33 0 0 0; #X connect 34 0 1 0; -#X connect 34 1 14 0; -#X connect 34 1 15 0; -#X connect 34 1 16 0; -#X connect 34 1 19 0; -#X connect 34 1 13 0; diff --git a/Testing/02_PD/fl_test3.pd b/Testing/02_PD/fl_test3.pd index 11c1ba4c8..9940c12f5 100644 --- a/Testing/02_PD/fl_test3.pd +++ b/Testing/02_PD/fl_test3.pd @@ -1,8 +1,7 @@ -#N canvas 358 90 1114 850 12; -#X obj 244 577 unsynced.fl.sink~; -#X obj 210 637 *~ 0.2; -#X obj 353 628 *~ 0.2; -#X obj 205 680 dac~; +#N canvas 537 146 1114 850 12; +#X obj 34 647 *~ 0.2; +#X obj 241 639 *~ 0.2; +#X obj 151 735 dac~; #X obj 153 540 fl.*~; #X obj 302 538 fl.*~; #X obj 184 507 fl.cos~; @@ -29,8 +28,8 @@ #X obj 921 370 table samps; #X obj 389 150 fl.*~ 1000; #N canvas 0 22 450 278 (subpatch) 0; -#X array array 17942 float 2; -#X coords 0 1 17942 -1 200 140 1 0 0; +#X array array 13293 float 2; +#X coords 0 1 13293 -1 200 140 1 0 0; #X restore 651 641 graph; #X obj 434 635 send array; #X obj 433 598 list prepend 0; @@ -38,9 +37,7 @@ #X obj 468 458 fl.length~; #X msg 506 555 \; array resize \$1; #X obj 433 526 fl.topd~ =2; -#X msg 265 41 rt 1; -#X obj 45 77 unsynced.fl.interval~ 500 -rt 0; -#X obj 28 607 unsynced.fl.sink~ -buffer outputs; +#X msg 279 28 rt 1; #X msg 119 31 process 60000; #X obj 820 432 table outputs 120000; #X msg 61 30 reset; @@ -49,49 +46,52 @@ needs to be in the search path; #X text 631 559 This seems to make the audio pause if I select a menu ; -#X connect 0 1 2 0; -#X connect 1 0 3 0; -#X connect 2 0 3 1; -#X connect 4 0 38 1; -#X connect 5 0 0 1; +#X obj 27 607 fl.sink~ -buffer outputs; +#X obj 244 577 fl.sink~; +#X obj 53 70 fl.interval~ 500 -rt 0; +#X msg 296 59 rt 0; +#X connect 0 0 2 0; +#X connect 1 0 2 1; +#X connect 3 0 41 0; +#X connect 4 0 42 0; +#X connect 5 0 3 1; #X connect 6 0 4 1; -#X connect 7 0 5 1; -#X connect 8 0 4 0; -#X connect 8 0 5 0; -#X connect 8 0 32 0; -#X connect 8 0 33 0; -#X connect 9 0 21 0; +#X connect 7 0 3 0; +#X connect 7 0 4 0; +#X connect 7 0 31 0; +#X connect 7 0 32 0; +#X connect 8 0 20 0; +#X connect 9 0 8 0; #X connect 10 0 9 0; #X connect 11 0 10 0; -#X connect 12 0 11 0; -#X connect 13 0 16 0; -#X connect 14 0 28 0; -#X connect 15 0 17 0; -#X connect 16 0 20 0; -#X connect 17 0 22 0; -#X connect 18 0 19 0; -#X connect 19 0 6 0; -#X connect 19 0 7 0; -#X connect 20 0 12 1; -#X connect 21 0 8 0; -#X connect 22 0 21 1; -#X connect 23 0 24 0; -#X connect 25 0 26 0; -#X connect 26 0 23 0; -#X connect 28 0 10 1; -#X connect 31 0 30 0; -#X connect 32 0 35 0; -#X connect 33 0 32 1; -#X connect 35 0 31 0; -#X connect 35 1 34 0; -#X connect 36 0 37 0; -#X connect 37 0 0 0; -#X connect 37 0 38 0; -#X connect 37 1 13 0; -#X connect 37 1 14 0; -#X connect 37 1 15 0; -#X connect 37 1 18 0; -#X connect 37 1 12 0; -#X connect 38 1 1 0; -#X connect 39 0 37 0; -#X connect 41 0 37 0; +#X connect 12 0 15 0; +#X connect 13 0 27 0; +#X connect 14 0 16 0; +#X connect 15 0 19 0; +#X connect 16 0 21 0; +#X connect 17 0 18 0; +#X connect 18 0 5 0; +#X connect 18 0 6 0; +#X connect 19 0 11 1; +#X connect 20 0 7 0; +#X connect 21 0 20 1; +#X connect 22 0 23 0; +#X connect 24 0 25 0; +#X connect 25 0 22 0; +#X connect 27 0 9 1; +#X connect 30 0 29 0; +#X connect 31 0 34 0; +#X connect 32 0 31 1; +#X connect 34 0 30 0; +#X connect 34 1 33 0; +#X connect 35 0 43 0; +#X connect 36 0 43 0; +#X connect 38 0 43 0; +#X connect 41 0 0 0; +#X connect 42 0 1 0; +#X connect 43 0 12 0; +#X connect 43 0 11 0; +#X connect 43 0 13 0; +#X connect 43 0 14 0; +#X connect 43 0 17 0; +#X connect 44 0 43 0; From 064c3d16aa8dfa7039be2bdb9d6d7892f3510f64 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 15:00:20 +0100 Subject: [PATCH 141/222] Fix indices --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 5989a4de5..6c27b81cc 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -734,7 +734,7 @@ class FrameLib_PDClass : public PDClass_Base struct PDInputProxy : public PDClass_Base { - static t_pd *create(FrameLib_PDClass *owner, int index) + static t_pd *create(FrameLib_PDClass *owner, long index) { t_pd *proxy = pd_new(*PDInputProxy::getClassPointer()); @@ -746,8 +746,6 @@ class FrameLib_PDClass : public PDClass_Base static void classInit(t_class *c, const char *classname) { - dspInit(c); - addMethod(c, "anything"); } @@ -755,11 +753,9 @@ class FrameLib_PDClass : public PDClass_Base void anything(t_symbol *s, long ac, t_atom *av) { - if (!s) - mOwner->frameInlet(mIndex); + mOwner->frameInlet(mIndex); } - void frame() { post("frame"); @@ -767,7 +763,7 @@ class FrameLib_PDClass : public PDClass_Base } FrameLib_PDClass *mOwner; - int mIndex; + long mIndex; }; struct ConnectionConfirmation @@ -980,9 +976,10 @@ class FrameLib_PDClass : public PDClass_Base for (long i = 0; i < numIns; i++) { + post("create in %ld", i); if (i || getNumAudioIns()) { - t_pd *proxy = PDInputProxy::create(this, (int) (getNumAudioIns() + i)); + t_pd *proxy = PDInputProxy::create(this, i); inlet_new(asObject(), proxy, gensym("signal"), gensym("signal")); mInputs[i] = Input(proxy, asObject(), i); } From b16f66dee9e511d71911a525dfce8a52d639330b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 15:48:12 +0100 Subject: [PATCH 142/222] Remove debug post --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1 - 1 file changed, 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 6c27b81cc..410d21a04 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -976,7 +976,6 @@ class FrameLib_PDClass : public PDClass_Base for (long i = 0; i < numIns; i++) { - post("create in %ld", i); if (i || getNumAudioIns()) { t_pd *proxy = PDInputProxy::create(this, i); From 328c9406bec74371ce444672b30304b69d1eab3a Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 16:51:32 +0100 Subject: [PATCH 143/222] Rename for clarity --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 410d21a04..41a8a808f 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1147,21 +1147,26 @@ class FrameLib_PDClass : public PDClass_Base for (int i = 0; i < getNumAudioIns(); i++) for (int j = 0; j < vec_size; j++) - mSigIns[i][j] = getAudioIn(i)[j]; + mTempIns[i][j] = getAudioIn(i)[j]; - mObject->blockUpdate(mSigIns.data(), mSigOuts.data(), vec_size); + mObject->blockUpdate(mTempIns.data(), mTempOuts.data(), vec_size); for (int i = 0; i < getNumAudioOuts(); i++) for (int j = 0; j < vec_size; j++) - getAudioOut(i)[j] = mSigOuts[i][j]; + getAudioOut(i)[j] = mTempOuts[i][j]; + // Zero frame outputs + + for (int i = getNumAudioOuts(); i < getNumAudioOuts() + getNumOuts(); i++) + std::fill_n(getAudioOut(i), vec_size, t_sample(0)); + mGlobal->contextMessages(getContext(), asObject()); } else { // Zero outputs - for (int i = 0; i < getNumAudioOuts(); i++) + for (int i = 0; i < getNumAudioOuts() + getNumOuts(); i++) std::fill_n(getAudioOut(i), vec_size, t_sample(0)); } } @@ -1196,16 +1201,16 @@ class FrameLib_PDClass : public PDClass_Base mGlobal->finalObject(getContext()) = asObject(); mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts())); - mSigIns.resize(getNumAudioIns()); - mSigOuts.resize(getNumAudioOuts()); + mTempIns.resize(getNumAudioIns()); + mTempOuts.resize(getNumAudioOuts()); double *inVecs = mTemp.data(); double *outVecs = inVecs + (getNumAudioIns() * vec_size); for (int i = 0; i < getNumAudioIns(); i++) - mSigIns[i] = inVecs + (i * vec_size); + mTempIns[i] = inVecs + (i * vec_size); for (int i = 0; i < getNumAudioOuts(); i++) - mSigOuts[i] = outVecs + (i * vec_size); + mTempOuts[i] = outVecs + (i * vec_size); } } @@ -1316,14 +1321,7 @@ class FrameLib_PDClass : public PDClass_Base mInputs[index].reportError(Input::kExtra); } } - - // Get Audio Outputs - - std::vector &getAudioOuts() - { - return mSigOuts; - } - + // External methods (A_CANT) static void extFindAudio(FrameLib_PDClass *x, std::vector *objects) @@ -1956,8 +1954,8 @@ class FrameLib_PDClass : public PDClass_Base std::vector mInputs; std::vector mOutputs; - std::vector mSigIns; - std::vector mSigOuts; + std::vector mTempIns; + std::vector mTempOuts; std::vector mTemp; t_glist *mCanvas; From 878ecdb93b380acc3567ba0680cef85bd1093e33 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 16:51:40 +0100 Subject: [PATCH 144/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 9dbd416c5..01bdf5880 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -13,7 +13,7 @@ I'm not sure if there should be a VS project for windows or not. **Testing** - I've started a test folder at Testing/02\_PD with a couple of simple demos -- Note that the first outlet and inlet of unsynced objects are the sync IO +- Note that the first outlet and inlet of unsynced objects are the sync IO (these will likely dissapear soon) **Key Issues** @@ -23,6 +23,7 @@ I'm not sure if there should be a VS project for windows or not. - At the moment in pd you get "unsynced" objects and must make these connections manually - Miller suggesting making all outputs signal outputs, which would work but isn't nice and is wasteful - My next step is to try to understand d_ugen.c to understand how the dsp graph is built and if there is a better way +- Having looked at this there doesn't appear to be any way other than using signal IO for everything so I've started that [REVIEW] - Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) - At the moment you can't connect framelib objects between different subpatchers @@ -31,7 +32,7 @@ I'm not sure if there should be a VS project for windows or not. - Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good -- Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful) +- Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful). There's no mechanism for this in pd so work needs to be done to report errors correctly only [REVIEW / CODE] - Attributes - non-realtime in Max is set by attributes. Part of the misssing support in pd is to sort these (which must be supported manually) - My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. From b970e1ebad850e8baaa545c382b4fe4dcb7a8616 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 16:57:29 +0100 Subject: [PATCH 145/222] Remove lock that is superfluous in pd --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 41a8a808f..77ab6f017 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -376,7 +376,6 @@ class FrameLib_PDGlobals : public PDClass_Base enum ConnectionMode : intptr_t { kConnect, kConfirm, kDoubleCheck }; using PDConnection = FrameLib_Connection; - using Lock = FrameLib_Lock; private: @@ -405,10 +404,10 @@ class FrameLib_PDGlobals : public PDClass_Base }; enum DSPDeferMode { kOff, kDefer, kNeedResume }; - enum RefDataItem { kKey, kCount, kLock, kLastResolved, kFinal, kHandler, kQueuePtr }; + enum RefDataItem { kKey, kCount, kLastResolved, kFinal, kHandler, kQueuePtr }; using QueuePtr = std::unique_ptr; - using RefData = std::tuple; + using RefData = std::tuple; using RefMap = std::unordered_map, Hash>; public: @@ -582,7 +581,6 @@ class FrameLib_PDGlobals : public PDClass_Base } bool isRealtime(FrameLib_Context c) const { return c.getGlobal() == mRTGlobal; } - Lock *getLock(FrameLib_Context c) { return &data(c); } t_object *&finalObject(FrameLib_Context c) { return data(c); } void setReportContextErrors(bool report) { mReportContextErrors = report; } @@ -728,7 +726,6 @@ class FrameLib_PDClass : public PDClass_Base using FLObject = FrameLib_Multistream; using FLConnection = FrameLib_Object::Connection; using PDConnection = FrameLib_PDGlobals::PDConnection; - using LockHold = FrameLib_LockHolder; using NumericType = FrameLib_Parameters::NumericType; using ClipMode = FrameLib_Parameters::ClipMode; @@ -1221,10 +1218,7 @@ class FrameLib_PDClass : public PDClass_Base void reset(t_deffloatarg sampleRate = 0.0) { if (!isRealtime()) - { - LockHold lock(mGlobal->getLock(getContext())); resolveNRTGraph(sampleRate > 0.0 ? sampleRate.mValue : sys_getsr(), true); - } } void process(t_floatarg length) @@ -1235,7 +1229,6 @@ class FrameLib_PDClass : public PDClass_Base if (!updateLength || isRealtime()) return; - LockHold lock(mGlobal->getLock(getContext())); resolveNRTGraph(0.0, false); // Retrieve all the audio objects in a list From 50a878c0a5321470061ef35d2388f8cb02a4bba3 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 17:00:14 +0100 Subject: [PATCH 146/222] Remove debug post --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1 - 1 file changed, 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 77ab6f017..4f8514644 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -755,7 +755,6 @@ class FrameLib_PDClass : public PDClass_Base void frame() { - post("frame"); mOwner->frameInlet(mIndex); } From e1d66f3b19f8c4499cdd9e13c394047b2db4fe8a Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 17:05:42 +0100 Subject: [PATCH 147/222] Rework so that outlets are always zeroed --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 4f8514644..3a11811eb 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1135,9 +1135,9 @@ class FrameLib_PDClass : public PDClass_Base void perform(int vec_size) { - // FIX - use alloca / revise perform and dsp + // FIX - use alloca? - if (isRealtime()) + if (handlesAudio() && isRealtime()) { // Copy Audio In @@ -1169,20 +1169,21 @@ class FrameLib_PDClass : public PDClass_Base void dsp(t_signal **sp) { - if (!isRealtime()) - return; + bool realtime = isRealtime(); + double samplingRate = sp[0]->s_sr; + int vec_size = sp[0]->s_vecsize; // Resolve connections (in case there are no schedulers left in the patch) and mark unresolved for next time - resolveConnections(); - mResolved = false; + if (realtime) + { + resolveConnections(); + mResolved = false; - // Reset DSP + // Reset DSP - double samplingRate = sp[0]->s_sr; - int vec_size = sp[0]->s_vecsize; - - mObject->reset(samplingRate, vec_size); + mObject->reset(samplingRate, vec_size); + } // Add a perform routine to the chain if the object handles audio @@ -1190,23 +1191,27 @@ class FrameLib_PDClass : public PDClass_Base { // Resolve this context - if (getType() == ObjectType::Scheduler && mGlobal->setLastResolved(mObject->getContext(), clock_getlogicaltime())) + if (realtime && getType() == ObjectType::Scheduler && mGlobal->setLastResolved(mObject->getContext(), clock_getlogicaltime())) resolveGraph(samplingRate, vec_size, true); addPerform::perform>(sp); - mGlobal->finalObject(getContext()) = asObject(); - + + // Prepare temporary memory + mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts())); mTempIns.resize(getNumAudioIns()); mTempOuts.resize(getNumAudioOuts()); - double *inVecs = mTemp.data(); - double *outVecs = inVecs + (getNumAudioIns() * vec_size); - for (int i = 0; i < getNumAudioIns(); i++) - mTempIns[i] = inVecs + (i * vec_size); + mTempIns[i] = mTemp.data() + (i * vec_size); for (int i = 0; i < getNumAudioOuts(); i++) - mTempOuts[i] = outVecs + (i * vec_size); + mTempOuts[i] = (mTemp.data() + (getNumAudioIns() * vec_size)) + (i * vec_size); + + // If realtime set the final object + // FIX - this may not work if the context changes... + + if (realtime) + mGlobal->finalObject(getContext()) = asObject(); } } From 678fbe1a1aa2b164ef932f8729f1f1d29cdff35e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 17:08:12 +0100 Subject: [PATCH 148/222] Remove directly connected code --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 3a11811eb..fe34082da 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -78,7 +78,6 @@ struct FrameLib_PDPrivate static inline const char *messageMakeAutoOrdering() { return "__fl.make_auto_ordering"; } static inline const char *messageClearAutoOrdering() { return "__fl.clear_auto_ordering"; } static inline const char *messageReset() { return "__fl.reset"; } - static inline const char *messageIsDirectlyConnected() { return "__fl.is_directly_connected"; } static inline const char *messageConnectionConfirm() { return "__fl.connection_confirm"; } static inline const char *messageConnectionUpdate() { return "__fl.connection_update"; } static inline const char *messageGetFrameLibObject() { return "__fl.get_framelib_object"; } @@ -884,7 +883,6 @@ class FrameLib_PDClass : public PDClass_Base addMethod(c, (t_method) &extMakeAutoOrdering, FrameLib_PDPrivate::messageMakeAutoOrdering()); addMethod(c, (t_method) &extClearAutoOrdering, FrameLib_PDPrivate::messageClearAutoOrdering()); addMethod(c, (t_method) &extReset, FrameLib_PDPrivate::messageReset()); - addMethod(c, (t_method) &extIsDirectlyConnected, FrameLib_PDPrivate::messageIsDirectlyConnected()); addMethod(c, (t_method) &extConnectionConfirm, FrameLib_PDPrivate::messageConnectionConfirm()); addMethod(c, (t_method) &extConnectionUpdate, FrameLib_PDPrivate::messageConnectionUpdate()); addMethod(c, (t_method) &extGetFLObject, FrameLib_PDPrivate::messageGetFrameLibObject()); @@ -961,7 +959,6 @@ class FrameLib_PDClass : public PDClass_Base mInputs.resize(numIns); mOutputs.resize(getNumOuts()); - mDirectlyConnected.resize(getNumIns(), false); // Create signal inlets + signal outlets @@ -1373,11 +1370,6 @@ class FrameLib_PDClass : public PDClass_Base x->makeConnection(index, mode); } - static intptr_t extIsDirectlyConnected(FrameLib_PDClass *x, unsigned long index) - { - return (intptr_t) x->mDirectlyConnected[index]; - } - // id attribute void idSet(t_symbol *name) @@ -1956,9 +1948,7 @@ class FrameLib_PDClass : public PDClass_Base std::vector mTemp; t_glist *mCanvas; - - std::vector mDirectlyConnected; - + ConnectionConfirmation *mConfirmation; unsigned long mSpecifiedStreams; From 815ef14a6f877ff6ed440047afe5ae551391ade6 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 17:10:17 +0100 Subject: [PATCH 149/222] Remove commented out code --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index fe34082da..b3b8f8c79 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1487,9 +1487,7 @@ class FrameLib_PDClass : public PDClass_Base } void resolveGraph(double sampleRate, intptr_t vecSize, bool force) - { - //bool markUnresolved = isRealtime(); - + { if (!force && isRealtime() && dspIsRunning()) return; @@ -1510,10 +1508,7 @@ class FrameLib_PDClass : public PDClass_Base traversePatch(FrameLib_PDPrivate::messageClearAutoOrdering()); traversePatch(FrameLib_PDPrivate::messageMakeAutoOrdering()); } - - //if (markUnresolved) - // traversePatch(FrameLib_PDPrivate::messageMarkUnresolved()); - + if (updated || force) traversePatch(FrameLib_PDPrivate::messageReset(), &sampleRate, vecSize); From 5f016314b448af7ccc6b096098e87b05960ef352 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 18:24:39 +0100 Subject: [PATCH 150/222] Avoid crashes with framelib objects and the "signal" message --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index b3b8f8c79..095734977 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -858,6 +858,7 @@ class FrameLib_PDClass : public PDClass_Base { addMethod, &FrameLib_PDClass::info>(c, "info"); addMethod, &FrameLib_PDClass::frame>(c, "signal"); + addMethod(c, "anything"); addMethod, &FrameLib_PDClass::dsp>(c); // Attributes @@ -1316,6 +1317,12 @@ class FrameLib_PDClass : public PDClass_Base } } + void anything(t_symbol *s, long ac, t_atom *av) + { + if (s) + pd_error(asPD(), "%s: no method for '%s'", class_getname(*asPD()), s->s_name); + } + // External methods (A_CANT) static void extFindAudio(FrameLib_PDClass *x, std::vector *objects) @@ -1487,7 +1494,7 @@ class FrameLib_PDClass : public PDClass_Base } void resolveGraph(double sampleRate, intptr_t vecSize, bool force) - { + { if (!force && isRealtime() && dspIsRunning()) return; From 8682fc4eee2fa7ac014bced410801b478f8b080a Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 20:39:37 +0100 Subject: [PATCH 151/222] Account for the signal message arriving either as a nullptr or as a signal symbol --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 095734977..80b90406f 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -749,7 +749,8 @@ class FrameLib_PDClass : public PDClass_Base void anything(t_symbol *s, long ac, t_atom *av) { - mOwner->frameInlet(mIndex); + if (!s || s == gensym("signal")) + mOwner->frameInlet(mIndex); } void frame() @@ -1319,7 +1320,7 @@ class FrameLib_PDClass : public PDClass_Base void anything(t_symbol *s, long ac, t_atom *av) { - if (s) + if (s && s != gensym("signal")) pd_error(asPD(), "%s: no method for '%s'", class_getname(*asPD()), s->s_name); } From 4b8da3c0b277f25728ce7aa30483baadef966887 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 20:55:35 +0100 Subject: [PATCH 152/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 01bdf5880..b595a1fa2 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -3,7 +3,7 @@ - All (165 out of 165) framelib objects get built to a single library files - Realtime operation and non-realtime operation is supported -- There are some key issues to note below and some minor niggles to be ironed out +- There are some key issues to note below which I'm working through To build you should be able to run make on this directory and then copy framelib_pd.d_fat and set it to load on startup @@ -13,7 +13,6 @@ I'm not sure if there should be a VS project for windows or not. **Testing** - I've started a test folder at Testing/02\_PD with a couple of simple demos -- Note that the first outlet and inlet of unsynced objects are the sync IO (these will likely dissapear soon) **Key Issues** @@ -23,7 +22,7 @@ I'm not sure if there should be a VS project for windows or not. - At the moment in pd you get "unsynced" objects and must make these connections manually - Miller suggesting making all outputs signal outputs, which would work but isn't nice and is wasteful - My next step is to try to understand d_ugen.c to understand how the dsp graph is built and if there is a better way -- Having looked at this there doesn't appear to be any way other than using signal IO for everything so I've started that [REVIEW] +- Having looked at this there doesn't appear to be any way other than using signal IO for everything so I've implemented that [REVIEW] - Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) - At the moment you can't connect framelib objects between different subpatchers From 2b0fe1b50199642ff9ab02a39153a1d55461c9aa Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 22:03:11 +0100 Subject: [PATCH 153/222] Correct type --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 80b90406f..4302eab5a 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1152,7 +1152,7 @@ class FrameLib_PDClass : public PDClass_Base // Zero frame outputs - for (int i = getNumAudioOuts(); i < getNumAudioOuts() + getNumOuts(); i++) + for (long i = getNumAudioOuts(); i < getNumAudioOuts() + getNumOuts(); i++) std::fill_n(getAudioOut(i), vec_size, t_sample(0)); mGlobal->contextMessages(getContext(), asObject()); From 8a87f9cfb9ecf56dbf799fed378b107a27bfe2b2 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 4 Aug 2022 22:03:19 +0100 Subject: [PATCH 154/222] Remove comment --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 4302eab5a..d37d17ba2 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1134,8 +1134,6 @@ class FrameLib_PDClass : public PDClass_Base void perform(int vec_size) { - // FIX - use alloca? - if (handlesAudio() && isRealtime()) { // Copy Audio In From 4f17a32f2c7113b9871221087b217d2e71df1821 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 07:44:34 +0100 Subject: [PATCH 155/222] Always adda perform routine --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index d37d17ba2..a494c0564 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1182,17 +1182,17 @@ class FrameLib_PDClass : public PDClass_Base mObject->reset(samplingRate, vec_size); } - // Add a perform routine to the chain if the object handles audio + // Add a perform routine to the chain whether or not the object handles audio (RT or Non-RT) + addPerform::perform>(sp); + if (handlesAudio()) { // Resolve this context if (realtime && getType() == ObjectType::Scheduler && mGlobal->setLastResolved(mObject->getContext(), clock_getlogicaltime())) resolveGraph(samplingRate, vec_size, true); - - addPerform::perform>(sp); - + // Prepare temporary memory mTemp.resize(vec_size * (getNumAudioIns() + getNumAudioOuts())); From bb9158ca38c3c9826f48e4c07d1123fc7e37ba5f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 07:44:53 +0100 Subject: [PATCH 156/222] Only pass on frame sync when needed --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index a494c0564..78769e79e 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1293,7 +1293,8 @@ class FrameLib_PDClass : public PDClass_Base void frame() { - frameInlet(-getNumAudioIns()); + if (!getNumAudioIns()) + frameInlet(0); } void frameInlet(long index) From c99453f1fb2497fe45b079fc7e2b08a02d4f04ab Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 08:47:18 +0100 Subject: [PATCH 157/222] Don't restart audio whilst in a dsp routine wait until audio would start) --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 78769e79e..1c326e0f1 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -482,9 +482,25 @@ class FrameLib_PDGlobals : public PDClass_Base , mRTNotifier(&mRTGlobal) , mNRTNotifier(&mNRTGlobal) , mDSPDefer(kOff) + , mInDSP(false) + , mRequireDSPRestart(false) , mRTGlobal(nullptr) , mNRTGlobal(nullptr) - {} + { + pd_bind(asPD(), gensym("pd-dsp-started")); + } + + ~FrameLib_PDGlobals() + { + pd_unbind(asPD(), gensym("pd-dsp-started")); + } + + // + + static void classInit(t_class *c, const char *classname) + { + addMethod(c, "bang"); + } // Pd global item methods @@ -590,7 +606,23 @@ class FrameLib_PDGlobals : public PDClass_Base PDConnection getConnection() const { return mConnection; } ConnectionMode getConnectionMode() const { return mConnectionMode; } - // DSP Resume (allows deferal when resolving contexts) + // DSP Handling / Suspending + Resume (allows deferal when resolving contexts) + + void dspStartNotification() + { + post("notification"); + if (mRequireDSPRestart) + { + post("DSP Restart"); + mRequireDSPRestart = false; + canvas_resume_dsp(canvas_suspend_dsp()); + } + } + + void dspBuilding(bool state) + { + mInDSP = state; + } void dspDeferResume(bool state) { @@ -608,6 +640,17 @@ class FrameLib_PDGlobals : public PDClass_Base } } + bool dspSuspendRequest() + { + if (mInDSP) + { + mRequireDSPRestart = true; + return false; + } + + return dspSuspend(); + } + void dspResumeRequest(bool oldState) { if (oldState && mDSPDefer != kOff) @@ -707,6 +750,8 @@ class FrameLib_PDGlobals : public PDClass_Base RefMap mContextRefs; DSPDeferMode mDSPDefer; + bool mInDSP; + bool mRequireDSPRestart; FrameLib_Global *mRTGlobal; FrameLib_Global *mNRTGlobal; @@ -1166,6 +1211,8 @@ class FrameLib_PDClass : public PDClass_Base void dsp(t_signal **sp) { + mGlobal->dspBuilding(true); + bool realtime = isRealtime(); double samplingRate = sp[0]->s_sr; int vec_size = sp[0]->s_vecsize; @@ -1210,6 +1257,8 @@ class FrameLib_PDClass : public PDClass_Base if (realtime) mGlobal->finalObject(getContext()) = asObject(); } + + mGlobal->dspBuilding(false); } // Non-realtime processing @@ -1450,7 +1499,7 @@ class FrameLib_PDClass : public PDClass_Base newObject->setFixedInput(i, values, size); if (mGlobal->isRealtime(context) || mGlobal->isRealtime(current)) - oldState = dspSuspend(); + oldState = mGlobal->dspSuspendRequest(); mPDContext = pdContext; mGlobal->retainContext(context); From 7bfb9e286d2c06cd33233a8fd43fddf4befa6e3b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 08:48:45 +0100 Subject: [PATCH 158/222] Remove debug posts --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 1c326e0f1..0c982d9f7 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -610,10 +610,8 @@ class FrameLib_PDGlobals : public PDClass_Base void dspStartNotification() { - post("notification"); if (mRequireDSPRestart) { - post("DSP Restart"); mRequireDSPRestart = false; canvas_resume_dsp(canvas_suspend_dsp()); } From 863745f4b70149d8c8bebec6c716a9f6c33c4829 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 08:51:44 +0100 Subject: [PATCH 159/222] Remove unused code / add error for unknown messages --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 0c982d9f7..7d4396c91 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -794,11 +794,8 @@ class FrameLib_PDClass : public PDClass_Base { if (!s || s == gensym("signal")) mOwner->frameInlet(mIndex); - } - - void frame() - { - mOwner->frameInlet(mIndex); + else + pd_error(mOwner->asPD(), "%s: no method for '%s'", class_getname(*mOwner->asPD()), s->s_name); } FrameLib_PDClass *mOwner; From 869fd0b610c062e73a4a297874c76468a8bd5a44 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 09:32:24 +0100 Subject: [PATCH 160/222] Reorder dsp defer code to make sure value is set before re-entering --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 7d4396c91..caa7d68f8 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -631,10 +631,12 @@ class FrameLib_PDGlobals : public PDClass_Base } else { - if (mDSPDefer == kNeedResume) - dspResume(true); - + bool willResume = mDSPDefer == kNeedResume; + mDSPDefer = kOff; + + if (willResume) + dspResume(true); } } From 6ca17c07b2aff8c2f36fd5f5f6696c0a7f7187d1 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 09:53:16 +0100 Subject: [PATCH 161/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index b595a1fa2..25a4cc8a3 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -1,5 +1,5 @@ -**Status and Building** +**Status / Building / Testing** - All (165 out of 165) framelib objects get built to a single library files - Realtime operation and non-realtime operation is supported @@ -10,12 +10,17 @@ To build you should be able to run make on this directory and then copy framelib Building *should* work on linux (it works on apple) but I've not tested. I'm not sure if there should be a VS project for windows or not. -**Testing** - - I've started a test folder at Testing/02\_PD with a couple of simple demos **Key Issues** +- Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) +- At the moment you can't connect framelib objects between different subpatchers + +- Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. + +- Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good + - *Audio synchronisation* - this is the main issue with finishing pd support and the Max approach won't work here - Because audio inputs and outputs are in different objects they must process audio in the correct order - In Max this is achieved by making these objects own subpatches with the actual object inside and making invisible audio connections to force the ordering @@ -24,14 +29,7 @@ I'm not sure if there should be a VS project for windows or not. - My next step is to try to understand d_ugen.c to understand how the dsp graph is built and if there is a better way - Having looked at this there doesn't appear to be any way other than using signal IO for everything so I've implemented that [REVIEW] -- Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) -- At the moment you can't connect framelib objects between different subpatchers - -- Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. - -- Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good - -- Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful). There's no mechanism for this in pd so work needs to be done to report errors correctly only [REVIEW / CODE] +- Connection handling - Max has the facility both to notify objects when connection change and allow objects to refuse connections - this is used to make connections prior to dsp time and also to prevent multiple connections - I have left this out and not yet investigated if pd has something similar (it's non-essential but useful). There's no mechanism for this in pd so work needs to be done to make sure errors report correctly only, which appears covered by the pre-existing code [REVIEW] - Attributes - non-realtime in Max is set by attributes. Part of the misssing support in pd is to sort these (which must be supported manually) - My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. @@ -42,12 +40,12 @@ I'm not sure if there should be a VS project for windows or not. - Some pd correctness has been reviewed (DONE): - Float arguments (t_floatarg?) - Assist strings? (don't exist for pd) + - Messages that would take ints in Max + - resetting dsp when resolving connections - Some pd correctness needs review: - PD-specific or custom objects (read/info/topd/frompd/contextcontrol/expressions) - - Messages that would take ints in Max - Whether garray_usedindsp should be used - - resetting dsp when resolving connections **Documentation** From f623930ab3daedcdae7cf79e27f22e2cb1ae34a8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 10:57:33 +0100 Subject: [PATCH 162/222] Restart of audio should deal with dsp() use of finalObject() in pd --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 1 - 1 file changed, 1 deletion(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index caa7d68f8..1d85cde76 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1249,7 +1249,6 @@ class FrameLib_PDClass : public PDClass_Base mTempOuts[i] = (mTemp.data() + (getNumAudioIns() * vec_size)) + (i * vec_size); // If realtime set the final object - // FIX - this may not work if the context changes... if (realtime) mGlobal->finalObject(getContext()) = asObject(); From cb3830cf6ea815e27329d1efa90f4ec1d1c5c07b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 13:00:42 +0100 Subject: [PATCH 163/222] Order messages by patch position --- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 1d85cde76..063edb060 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -181,8 +181,6 @@ class MessageHandler : public PDClass_Base { bool operator()(const Message& a, const Message& b) const { - // FIX - ordering comparison - // Use time if (a.mInfo.mTime != b.mInfo.mTime) @@ -193,7 +191,17 @@ class MessageHandler : public PDClass_Base if (a.mInfo.mProxy == b.mInfo.mProxy) return a.mInfo.mStream < b.mInfo.mStream; - return a.mInfo.mProxy < b.mInfo.mProxy; + // Use object positions + + const short ax = a.mInfo.mProxy->getOwner()->te_xpix; + const short ay = a.mInfo.mProxy->getOwner()->te_ypix; + const short bx = b.mInfo.mProxy->getOwner()->te_xpix; + const short by = b.mInfo.mProxy->getOwner()->te_ypix; + + if (ax != bx) + return ax < bx; + + return ay < by; } }; From 2c5ce17e36eba8b1bb85b7ef65a9c95fbc9c9bbc Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 5 Aug 2022 13:00:58 +0100 Subject: [PATCH 164/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 25a4cc8a3..5d42f8201 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -17,8 +17,6 @@ I'm not sure if there should be a VS project for windows or not. - Subpatches - my understanding is that pd processes the audio in subpatchers in one go (Max does not) which makes ordering an issue (as above) - At the moment you can't connect framelib objects between different subpatchers -- Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd. - - Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good - *Audio synchronisation* - this is the main issue with finishing pd support and the Max approach won't work here @@ -35,6 +33,8 @@ I'm not sure if there should be a VS project for windows or not. - My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. - sigmund~ uses dashes like the command line so I've copied that for now. [REVIEW] +- Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd but logically patch position would seem to make sense, so I'm implenting that [REVIEW] + **Review** - Some pd correctness has been reviewed (DONE): From c7b09d07608b3901737fb27bbbda28b1ee0d76f5 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 14:22:07 +0100 Subject: [PATCH 165/222] Use std namespace --- FrameLib_Dependencies/RandomGenerator.hpp | 6 ++--- FrameLib_Dependencies/SpectralFunctions.hpp | 2 +- FrameLib_Dependencies/Statistics.hpp | 14 +++++----- FrameLib_Framework/FrameLib_FixedPoint.cpp | 2 +- .../FrameLib_Scaling_Functions.h | 26 +++++++++---------- FrameLib_Objects/Spatial/FrameLib_Spatial.cpp | 4 +-- .../Time_Smoothing/FrameLib_TimeMedian.cpp | 4 +-- FrameLib_Objects/Vector/FrameLib_Peaks.cpp | 6 ++--- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/FrameLib_Dependencies/RandomGenerator.hpp b/FrameLib_Dependencies/RandomGenerator.hpp index 066e4f5dc..7d4e001a0 100755 --- a/FrameLib_Dependencies/RandomGenerator.hpp +++ b/FrameLib_Dependencies/RandomGenerator.hpp @@ -219,7 +219,7 @@ class random_generator R = (x * x) + (y * y); } - R = sqrt((-2.0 * log(R)) / R); + R = sqrt((-2.0 * std::log(R)) / R); } // This is adapted from http://home.online.no/~pjacklam/notes/invnorm/impl/sprouse/ltqnorm.c @@ -310,7 +310,7 @@ class random_generator { /* Rational approximation for lower region */ - q = sqrt(-2.0*log(p)); + q = sqrt(-2.0*std::log(p)); return (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1); } @@ -318,7 +318,7 @@ class random_generator { /* Rational approximation for upper region */ - q = sqrt(-2.0*log(1-p)); + q = sqrt(-2.0*std::log(1-p)); return -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1); } diff --git a/FrameLib_Dependencies/SpectralFunctions.hpp b/FrameLib_Dependencies/SpectralFunctions.hpp index 443d63262..8d8ecec19 100644 --- a/FrameLib_Dependencies/SpectralFunctions.hpp +++ b/FrameLib_Dependencies/SpectralFunctions.hpp @@ -179,7 +179,7 @@ namespace impl void operator()(T& r_out, T& i_out, const T& r_in, const T& i_in, uintptr_t i) { static T min_power = std::pow(10.0, -300.0 / 10.0); - store(r_out, i_out, T(0.5) * log(std::max(r_in * r_in + i_in * i_in, min_power)), T(0)); + store(r_out, i_out, T(0.5) * std::log(std::max(r_in * r_in + i_in * i_in, min_power)), T(0)); } }; diff --git a/FrameLib_Dependencies/Statistics.hpp b/FrameLib_Dependencies/Statistics.hpp index ef6f48789..13c3cbbff 100644 --- a/FrameLib_Dependencies/Statistics.hpp +++ b/FrameLib_Dependencies/Statistics.hpp @@ -15,10 +15,10 @@ namespace impl struct pow3 { template T operator()(T a) const { return a * a * a; } }; struct pow4 { template T operator()(T a) const { return pow2()(pow2()(a)); } }; struct absolute { template T operator()(T a) const { return std::abs(a); } }; - struct logarithm { template T operator()(T a) const { return log(a); } }; + struct logarithm { template T operator()(T a) const { return std::log(a); } }; struct indices { template double operator[](T a) const { return static_cast(a); } }; - struct log_indices { template double operator[](T a) const { return a ? log2(static_cast(a)) : 0.0; } }; + struct log_indices { template double operator[](T a) const { return a ? std::log2(static_cast(a)) : 0.0; } }; template struct modified_data @@ -256,7 +256,7 @@ double stat_mean_squares(const T input, size_t size) template double stat_geometric_mean(const T input, size_t size) { - return exp(stat_sum_logs(input, size) / stat_length(input, size)); + return std::exp(stat_sum_logs(input, size) / stat_length(input, size)); } // Variance @@ -331,14 +331,14 @@ double stat_kurtosis(const T input, size_t size) template double stat_log_centroid(const T input, size_t size) { - return exp2(stat_weighted_sum(impl::log_indices(), input, size) / (stat_sum(input, size))); + return std::exp2(stat_weighted_sum(impl::log_indices(), input, size) / (stat_sum(input, size))); } template double stat_log_spread(const T input, size_t size) { double centroid = stat_log_centroid(input, size); - return sqrt(stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), input, size) / stat_sum(input, size)); + return sqrt(stat_weighted_sum(impl::log_indices_diff_op(std::log2(centroid)), input, size) / stat_sum(input, size)); } template @@ -346,7 +346,7 @@ double stat_log_skewness(const T input, size_t size) { double centroid = stat_log_centroid(input, size); double denominator = impl::pow3()(stat_log_spread(input, size)) * stat_sum(input, size); - return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), input, size) / denominator : 0.0; + return denominator ? stat_weighted_sum(impl::log_indices_diff_op(std::log2(centroid)), input, size) / denominator : 0.0; } template @@ -354,7 +354,7 @@ double stat_log_kurtosis(const T input, size_t size) { double centroid = stat_log_centroid(input, size); double denominator = impl::pow4()(stat_log_spread(input, size)) * stat_sum(input, size); - return denominator ? stat_weighted_sum(impl::log_indices_diff_op(log2(centroid)), input, size) / denominator : std::numeric_limits::infinity(); + return denominator ? stat_weighted_sum(impl::log_indices_diff_op(std::log2(centroid)), input, size) / denominator : std::numeric_limits::infinity(); } // Flatness diff --git a/FrameLib_Framework/FrameLib_FixedPoint.cpp b/FrameLib_Framework/FrameLib_FixedPoint.cpp index 30998de85..594179ecb 100644 --- a/FrameLib_Framework/FrameLib_FixedPoint.cpp +++ b/FrameLib_Framework/FrameLib_FixedPoint.cpp @@ -280,7 +280,7 @@ FL_FP::FL_FP(const double& val) else { mInt = static_cast(absVal); - mFrac = static_cast(round((absVal - floor(absVal)) * 18446744073709551616.0)); + mFrac = static_cast(round((absVal - std::floor(absVal)) * 18446744073709551616.0)); } } diff --git a/FrameLib_Objects/Common_Utilities/FrameLib_Scaling_Functions.h b/FrameLib_Objects/Common_Utilities/FrameLib_Scaling_Functions.h index 9430ccf83..e26307fbc 100644 --- a/FrameLib_Objects/Common_Utilities/FrameLib_Scaling_Functions.h +++ b/FrameLib_Objects/Common_Utilities/FrameLib_Scaling_Functions.h @@ -8,22 +8,22 @@ // Common Conversions template -T dbToAmp(T x) { return pow(10.0, x / 20.0); } +T dbToAmp(T x) { return std::pow(10.0, x / 20.0); } template -T ampToDb(T x) { return log10(x) * 20.0; } +T ampToDb(T x) { return std::log10(x) * 20.0; } template -T midiToFreq(T x) { return exp2((x - 69.0) / 12.0) * 440.0; } +T midiToFreq(T x) { return std::exp2((x - 69.0) / 12.0) * 440.0; } template -T freqToMidi(T x) { return log2(x / 440.0) * 12.0 + 69.0; } +T freqToMidi(T x) { return std::log2(x / 440.0) * 12.0 + 69.0; } template -T semitonesToRatio(T x) { return exp2(x / 12.0); } +T semitonesToRatio(T x) { return std::exp2(x / 12.0); } template -T ratioToSemitones(T x) { return log2(x) * 12.0; } +T ratioToSemitones(T x) { return std::log2(x) * 12.0; } // Scaling of Vectors @@ -69,17 +69,17 @@ struct LinScaler : public ScaleCoefficients template struct LogScaler : public ScaleCoefficients { - LogScaler(T inLo, T inHi, T outLo, T outHi) : ScaleCoefficients(log(inLo), log(inHi), outLo, outHi) {} + LogScaler(T inLo, T inHi, T outLo, T outHi) : ScaleCoefficients(std::log(inLo), std::log(inHi), outLo, outHi) {} LogScaler(const ScaleCoefficients& coeff) : ScaleCoefficients(coeff) {} - template U operator()(U x) const { return log(x) * ScaleCoefficients::mMul - ScaleCoefficients::mSub; } + template U operator()(U x) const { return std::log(x) * ScaleCoefficients::mMul - ScaleCoefficients::mSub; } template void operator()(U *output, const U *input, unsigned long size) const { scaleVector(output, input, size, *this); } }; template struct ExpScaler : public ScaleCoefficients { - ExpScaler(T inLo, T inHi, T outLo, T outHi) : ScaleCoefficients(inLo, inHi, log(outLo), log(outHi)) {} + ExpScaler(T inLo, T inHi, T outLo, T outHi) : ScaleCoefficients(inLo, inHi, std::log(outLo), std::log(outHi)) {} ExpScaler(const ScaleCoefficients& coeff) : ScaleCoefficients(coeff) {} template U operator()(U x) const { return exp((x * ScaleCoefficients::mMul) - ScaleCoefficients::mSub); } @@ -100,7 +100,7 @@ struct PowScaler exponent = mExponent; } - template U operator()(U x) const { return mOutputScaler(pow(mInputScaler(x), mExponent)); } + template U operator()(U x) const { return mOutputScaler(std::pow(mInputScaler(x), mExponent)); } template void operator()(U *output, const U *input, unsigned long size) const { scaleVector(output, input, size, *this); } LinScaler mInputScaler; @@ -135,14 +135,14 @@ LinClipScaler : public ClipScaler> template struct LogClipScaler : public ClipScaler> { - LogClipScaler(T inLo, T inHi, T outLo, T outHi) : ClipScaler>(log(inLo), log(inHi), outLo, outHi) {} + LogClipScaler(T inLo, T inHi, T outLo, T outHi) : ClipScaler>(std::log(inLo), std::log(inHi), outLo, outHi) {} LogClipScaler(const ScaleCoefficients& coeff, T min, T max) : ClipScaler>(LogScaler(coeff), min, max) {} }; template struct ExpClipScaler : public ClipScaler> { - ExpClipScaler(T inLo, T inHi, T outLo, T outHi) : ClipScaler>(ExpScaler(inLo, inHi, log(outLo), log(outHi)), outLo, outHi) {} + ExpClipScaler(T inLo, T inHi, T outLo, T outHi) : ClipScaler>(ExpScaler(inLo, inHi, std::log(outLo), std::log(outHi)), outLo, outHi) {} ExpClipScaler(const ScaleCoefficients& coeff, T min, T max) : ClipScaler>(ExpScaler(coeff), min, max) {} }; @@ -150,7 +150,7 @@ template struct PowClipScaler : public ClipScaler> { PowClipScaler(T inLo, T inHi, T outLo, T outHi, T exponent) - : ClipScaler>(PowScaler(inLo, inHi, log(outLo), log(outHi)), outLo, outHi, exponent) {} + : ClipScaler>(PowScaler(inLo, inHi, std::log(outLo), std::log(outHi)), outLo, outHi, exponent) {} PowClipScaler(const ScaleCoefficients& inCoeff, const ScaleCoefficients& outCoeff, T exponent, T min, T max) : ClipScaler>(PowScaler(inCoeff, outCoeff, exponent), min, max) {} }; diff --git a/FrameLib_Objects/Spatial/FrameLib_Spatial.cpp b/FrameLib_Objects/Spatial/FrameLib_Spatial.cpp index a3d6e868a..6b543553c 100644 --- a/FrameLib_Objects/Spatial/FrameLib_Spatial.cpp +++ b/FrameLib_Objects/Spatial/FrameLib_Spatial.cpp @@ -528,7 +528,7 @@ void FrameLib_Spatial::process() const double rolloff = mParameters.getValue(kRolloff); const double pointFactor = mParameters.getValue(kPointFactor); - const double rolloffFactor = rolloff / (20 * log10(2.0)); + const double rolloffFactor = rolloff / (20 * std::log10(2.0)); const double blur2 = blur * blur; maxSpeakers = maxSpeakers == 0 ? numSpeakers : maxSpeakers; @@ -573,7 +573,7 @@ void FrameLib_Spatial::process() double sqDistance = xDelta * xDelta + yDelta * yDelta + zDelta * zDelta; double weight = i < weightsSize ? weights[i] : 1.0; - coefficients[i] = weight / pow(sqDistance + blur2, 0.5 * rolloffFactor); + coefficients[i] = weight / std::pow(sqDistance + blur2, 0.5 * rolloffFactor); if (i == 0 || (sqDistance < minDistance)) { diff --git a/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMedian.cpp b/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMedian.cpp index 01eef741e..19a1656d3 100644 --- a/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMedian.cpp +++ b/FrameLib_Objects/Time_Smoothing/FrameLib_TimeMedian.cpp @@ -30,12 +30,12 @@ void FrameLib_TimeMedian::resetSize(unsigned long maxFrames, unsigned long size) bool compareLess(double a, double b) { - return (a < b || (isnan(b) && !isnan(a))); + return (a < b || (std::isnan(b) && !std::isnan(a))); } bool compareMore(double a, double b) { - return (a > b || (isnan(a) && !isnan(b))); + return (a > b || (std::isnan(a) && !std::isnan(b))); } unsigned long find(double input, double *channel, unsigned long numFrames) diff --git a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp index b665c5fd6..9c3b8bf4b 100644 --- a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp +++ b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp @@ -173,14 +173,14 @@ void refineParabolicLog(double *positions, double *values, const double *data, u // N.B. we assume a max of -80dB difference between samples to prevent extreme overshoot double limit = std::max(std::max(data[idx-1], data[idx+1]) * 0.0001, std::numeric_limits::min()); - auto logLim = [&](double x) { return log(std::max(x, limit)); }; + auto logLim = [&](double x) { return std::log(std::max(x, limit)); }; double position, value; parabolicInterp(position, value, idx, logLim(data[idx-1]), logLim(data[idx]), logLim(data[idx+1])); positions[peak] = position; - values[peak] = exp(value); + values[peak] = std::exp(value); } // Process @@ -302,7 +302,7 @@ void FrameLib_Peaks::process() case kMidpoint: { - peakEnd = static_cast(ceil((output2[peak] + output2[peak + 1]) / 2.0)); + peakEnd = static_cast(std::ceil((output2[peak] + output2[peak + 1]) / 2.0)); break; } } From 32a913a225ca30a72fee249b80291ffc7f97e61b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 14:22:14 +0100 Subject: [PATCH 166/222] Remove ampersands --- FrameLib_Dependencies/SpectralProcessor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Dependencies/SpectralProcessor.hpp b/FrameLib_Dependencies/SpectralProcessor.hpp index 1e49aeadb..6e08687fc 100644 --- a/FrameLib_Dependencies/SpectralProcessor.hpp +++ b/FrameLib_Dependencies/SpectralProcessor.hpp @@ -165,7 +165,7 @@ class spectral_processor void correlate(T *output, in_ptr in1, in_ptr in2, EdgeMode mode) { - binary_op<&ir_correlate_real, &arrange_correlate>(output, in1, in2, mode); + binary_op>(output, in1, in2, mode); } // Phase From 5f665a2e9af12b875d0edf08301d851725cd47ab Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 14:22:24 +0100 Subject: [PATCH 167/222] Set null thread for linux --- FrameLib_Framework/FrameLib_Threading.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/FrameLib_Framework/FrameLib_Threading.h b/FrameLib_Framework/FrameLib_Threading.h index 9b5de1c7d..84c4d4888 100644 --- a/FrameLib_Framework/FrameLib_Threading.h +++ b/FrameLib_Framework/FrameLib_Threading.h @@ -29,6 +29,8 @@ namespace OS_Specific using OSSemaphoreType = sem_t; typedef void *OSThreadFunctionType(void *arg); + inline OSThreadType nullThread() { return pthread_t(0); } + inline void threadNanosleep() { std::this_thread::sleep_for(std::chrono::nanoseconds(100)); @@ -55,6 +57,8 @@ namespace OS_Specific using OSSemaphoreType = semaphore_t; typedef void *OSThreadFunctionType(void *arg); + inline OSThreadType nullThread() { return nullptr; } + inline void threadNanosleep() { std::this_thread::sleep_for(std::chrono::nanoseconds(100)); @@ -80,6 +84,8 @@ namespace OS_Specific using OSSemaphoreType = struct WinSemaphore { HANDLE mHandle; long mMaxCount; }; typedef DWORD WINAPI OSThreadFunctionType(LPVOID arg); + inline OSThreadType nullThread() { return nullptr; } + inline void threadNanosleep() { SwitchToThread(); @@ -304,7 +310,7 @@ class FrameLib_Thread } FrameLib_Thread(PriorityLevel priority, ThreadFunctionType *threadFunction, void *arg) - : mInternal(nullptr), mPriority(priority), mThreadFunction(threadFunction), mArg(arg), mValid(false) + : mInternal(OS_Specific::nullThread()), mPriority(priority), mThreadFunction(threadFunction), mArg(arg), mValid(false) {} ~FrameLib_Thread(); From 436f928da1aaa8438f76a6148d4f1dd62fe43491 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 14:24:23 +0100 Subject: [PATCH 168/222] Add missing headers --- FrameLib_PD_Objects/Common/PDClass_Base.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 66c332fe5..76ee29458 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -3,6 +3,9 @@ #define __PD_BASE_H__ #include + +#include +#include #include #include From 4062a3b54ac6190c207bec2a0ce1d61f92b30553 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 14:24:30 +0100 Subject: [PATCH 169/222] Update pd TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 5d42f8201..77963a498 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -7,10 +7,10 @@ To build you should be able to run make on this directory and then copy framelib_pd.d_fat and set it to load on startup -Building *should* work on linux (it works on apple) but I've not tested. -I'm not sure if there should be a VS project for windows or not. +Building works on apple and finishes on linux (although I've not confirmed that my settings are correct as I'm building online for that). +I'm not sure if there should be a VS project for windows or that should also be done via make, and if the latter how to do that. -- I've started a test folder at Testing/02\_PD with a couple of simple demos +- I've started a test folder at Testing/02\_PD with a few simple demos **Key Issues** @@ -55,7 +55,7 @@ I'm not sure if there should be a VS project for windows or not. **Build System and Distribution** -- The makefile is very basic and currently builds 64 bit only -- Improve the makefile or build system to support all necessary platforms and OSes +- The makefile is very basic and currently builds the default architecture only +- I need to understand what file names/architectures etc. should be for different systems +- I need to improve the makefile or build system to support all necessary platforms and OSes - At the moment object files go into the main PD folder - I'd like them to go into a build directory but I don't know make well enough -- At the moment I suppress undefined symbols at link, but that means that if there was a non-pd-related link error it wouldn't be caught, so if something nicer is possible that would be good. From 91b9472090325d185d38e544e2554ce1ed96c36f Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 14:24:50 +0100 Subject: [PATCH 170/222] Correctly export setup for Window dll --- FrameLib_PD_Objects/framelib_pd.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 4275b0e06..fb229d744 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -7,6 +7,15 @@ #include "pd_buffer.h" +// PD_API define + +#if defined(_WIN32) +// Export the symbol to the DLL interface +#define PD_API extern "C" __declspec(dllexport) +#else +#define PD_API extern "C" +#endif + // Context Control - A pd class to communicate with the current pd class FrameLib_PDClass_ContextControl : public PDClass_Base @@ -509,7 +518,7 @@ struct FrameLib_PDClass_ComplexExpression : public FrameLib_PDClass_ComplexExpre // Main setup routine -extern "C" void framelib_pd_setup(void) +PD_API void framelib_pd_setup(void) { // Context Control @@ -752,7 +761,7 @@ extern "C" void framelib_pd_setup(void) // Buffer - // TODO - info is not correct + // FIX - info is not correct FrameLib_PDClass_Expand::makeClass("fl.info~"); FrameLib_PDClass_Read::makeClass("fl.read~"); From 8b7a5c1a3f49e3e167e7bfd7a0d211dac413d0fd Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 20:34:34 +0100 Subject: [PATCH 171/222] Check that there is a valid FL object before disconnecting ordering connections --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 3382de437..bca5ad168 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -2484,7 +2484,11 @@ class FrameLib_MaxClass : public MaxClass_Base return; if (isOrderingInput(inIdx)) - mObject->deleteOrderingConnection(toFLConnection(connection)); + { + auto flConnection = toFLConnection(connection); + if (flConnection.mObject) + mObject->deleteOrderingConnection(flConnection); + } else mObject->deleteConnection(inIdx); From 08a6ad810fc4eb20707f3547cf956a7a5bcdb970 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 20:34:47 +0100 Subject: [PATCH 172/222] Allow ordering connections to be confirmed --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index bca5ad168..48e69c1a9 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -2423,7 +2423,7 @@ class FrameLib_MaxClass : public MaxClass_Base bool confirmConnection(MaxConnection connection, unsigned long inIndex, ConnectionMode mode) { - if (!validInput(inIndex) || !connection.mObject) + if ((!validInput(inIndex) && !isOrderingInput(inIndex)) || !connection.mObject) return false; ConnectionConfirmation confirmation(connection, inIndex); From 664e5bd3225a7b14f16c62164d669e2d3f002493 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 22:10:15 +0100 Subject: [PATCH 173/222] Ordering connection fixes from main --- FrameLib_Max_Objects/Common/FrameLib_MaxClass.h | 8 ++++++-- FrameLib_PD_Objects/Common/FrameLib_PDClass.h | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h index 3382de437..48e69c1a9 100644 --- a/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h +++ b/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h @@ -2423,7 +2423,7 @@ class FrameLib_MaxClass : public MaxClass_Base bool confirmConnection(MaxConnection connection, unsigned long inIndex, ConnectionMode mode) { - if (!validInput(inIndex) || !connection.mObject) + if ((!validInput(inIndex) && !isOrderingInput(inIndex)) || !connection.mObject) return false; ConnectionConfirmation confirmation(connection, inIndex); @@ -2484,7 +2484,11 @@ class FrameLib_MaxClass : public MaxClass_Base return; if (isOrderingInput(inIdx)) - mObject->deleteOrderingConnection(toFLConnection(connection)); + { + auto flConnection = toFLConnection(connection); + if (flConnection.mObject) + mObject->deleteOrderingConnection(flConnection); + } else mObject->deleteConnection(inIdx); diff --git a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h index 063edb060..53e821daa 100644 --- a/FrameLib_PD_Objects/Common/FrameLib_PDClass.h +++ b/FrameLib_PD_Objects/Common/FrameLib_PDClass.h @@ -1673,7 +1673,7 @@ class FrameLib_PDClass : public PDClass_Base bool confirmConnection(PDConnection connection, unsigned long inIndex, ConnectionMode mode) { - if (!validInput(inIndex) || !connection.mObject) + if ((!validInput(inIndex) && !isOrderingInput(inIndex)) || !connection.mObject) return false; ConnectionConfirmation confirmation(connection, inIndex); @@ -1734,7 +1734,11 @@ class FrameLib_PDClass : public PDClass_Base return; if (isOrderingInput(inIdx)) - mObject->deleteOrderingConnection(toFLConnection(connection)); + { + auto flConnection = toFLConnection(connection); + if (flConnection.mObject) + mObject->deleteOrderingConnection(flConnection); + } else mObject->deleteConnection(inIdx); From 4ab356030be2001e91f4f127b20c675fa710c184 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 8 Aug 2022 22:11:57 +0100 Subject: [PATCH 174/222] Triple-platform compliant makefile for pd --- FrameLib_PD_Objects/Common/pd_symbols.txt | 1 + FrameLib_PD_Objects/makefile | 103 ++++++++++++++++------ 2 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 FrameLib_PD_Objects/Common/pd_symbols.txt diff --git a/FrameLib_PD_Objects/Common/pd_symbols.txt b/FrameLib_PD_Objects/Common/pd_symbols.txt new file mode 100644 index 000000000..a63bd7661 --- /dev/null +++ b/FrameLib_PD_Objects/Common/pd_symbols.txt @@ -0,0 +1 @@ +.__array .__class .__outlet .__inlet .__binbuf .__clock .__outconnect .__glist .__instancemidi .__instanceinter .__instancecanvas .__instanceugen .__instancestuff .__garray .__widgetbehavior .__parentwidgetbehavior ._pd_objectmaker ._pd_canvasmaker ._pd_typedmess ._pd_forwardmess ._gensym ._getfn ._zgetfn ._nullfn ._pd_vmess ._obj_list ._pd_newest ._getbytes ._getzbytes ._copybytes ._freebytes ._resizebytes ._atom_getfloat ._t_atom_getint ._atom_getsymbol ._atom_gensym ._atom_getfloatarg ._t_atom_getintarg ._atom_getsymbolarg ._atom_string ._binbuf_new ._binbuf_free ._binbuf_duplicate ._binbuf_text ._binbuf_gettext ._binbuf_clear ._binbuf_add ._binbuf_addv ._binbuf_addbinbuf ._binbuf_addsemi ._binbuf_restore ._binbuf_print ._binbuf_getnatom ._binbuf_getvec ._binbuf_resize ._binbuf_eval ._binbuf_read ._binbuf_read_via_canvas ._binbuf_read_via_path ._binbuf_write ._binbuf_evalfile ._binbuf_realizedollsym ._clock_new ._clock_set ._clock_delay ._clock_unset ._clock_setunit ._clock_getlogicaltime ._clock_getsystime ._clock_gettimesince ._clock_gettimesincewithunits ._clock_getsystimeafter ._clock_free ._pd_new ._pd_free ._pd_bind ._pd_unbind ._pd_findbyclass ._pd_pushsym ._pd_popsym ._pd_getfilename ._pd_getdirname ._pd_bang ._pd_pointer ._pd_float ._pd_symbol ._pd_list ._pd_anything ._gpointer_init ._gpointer_copy ._gpointer_unset ._gpointer_check ._inlet_new ._pointerinlet_new ._floatinlet_new ._symbolinlet_new ._signalinlet_new ._inlet_free ._outlet_new ._outlet_bang ._outlet_pointer ._outlet_float ._outlet_symbol ._outlet_list ._outlet_anything ._outlet_getsymbol ._outlet_free ._pd_checkobject ._glob_setfilename ._canvas_setargs ._canvas_getargs ._canvas_getcurrentdir ._canvas_getcurrent ._canvas_makefilename ._canvas_getdir ._sys_font ._sys_fontweight ._sys_hostfontsize ._sys_zoomfontwidth ._sys_zoomfontheight ._sys_fontwidth ._sys_fontheight ._canvas_dataproperties ._canvas_open ._pd_getparentwidget ._class_new ._class_addcreator ._class_addmethod ._class_addbang ._class_addpointer ._class_doaddfloat ._class_addsymbol ._class_addlist ._class_addanything ._class_sethelpsymbol ._class_setwidget ._class_setparentwidget ._class_parentwidget ._class_getname ._class_gethelpname ._class_gethelpdir ._class_setdrawcommand ._class_isdrawcommand ._class_domainsignalin ._class_set_ ._dir ._class_setsavefn ._class_getsavefn ._obj_saveformat ._class_setpropertiesfn ._class_getpropertiesfn ._post ._startpost ._poststring ._postfloat ._postatom ._endpost ._error ._verbose ._bug ._pd_error ._logpost ._sys_logerror ._sys_unixerror ._sys_ouch ._sys_isreadablefile ._sys_isabsolutepath ._sys_bashfilename ._sys_unbashfilename ._open_via_path ._sched_geteventno ._sys_getrealtime ._sys_idlehook ._sys_open ._sys_close ._sys_fopen ._sys_fclose ._sys_lock ._sys_unlock ._sys_trylock ._plus_perform ._zero_perform ._copy_perform ._dsp_add_plus ._dsp_add_copy ._dsp_add_scalarcopy ._dsp_add_zero ._sys_getblksize ._sys_getsr ._sys_get_inchannels ._sys_get_outchannels ._dsp_add ._dsp_addv ._pd_fft ._ilog2 ._mayer_fht ._mayer_fft ._mayer_ifft ._mayer_realfft ._mayer_realifft ._cos_table ._canvas_suspend_dsp ._canvas_resume_dsp ._canvas_update_dsp ._canvas_dspstate ._resample_init ._resample_free ._resample_dsp ._resamplefrom_dsp ._resampleto_dsp ._mtof ._ftom ._rmstodb ._powtodb ._dbtorms ._dbtopow ._q8_sqrt ._q8_rsqrt ._qsqrt ._qrsqrt ._garray_class ._garray_getfloatarray ._garray_getfloatwords ._garray_redraw ._garray_npoints ._garray_vec ._garray_resize ._garray_resize_long ._garray_usedindsp ._garray_setsaveit ._garray_getglist ._garray_getarray ._scalar_class ._value_get ._value_release ._value_getfloat ._value_setfloat ._sys_vgui ._sys_gui ._sys_pretendguibytes ._sys_queuegui ._sys_unqueuegui ._gfxstub_new ._gfxstub_deleteforkey ._c_extern ._c_addmess ._sys_getversion ._pd_maininstance ._pdinstance_new ._pd_setinstance ._pdinstance_free ._pd_instances ._pd_ninstances ._s_pointer ._s_float ._s_symbol ._s_bang ._s_list ._s_anything ._pd_getcanvaslist ._pd_getdspstate \ No newline at end of file diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index 3615b2061..66062e1a2 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -1,49 +1,94 @@ -.SUFFIXES:.so -FL_FRAMEWORK=../FrameLib_Framework -FL_DEPENDENCIES=../FrameLib_Dependencies -FL_OBJECTS=../FrameLib_Objects +SHELL = /bin/sh -VPATH=../FrameLib_Dependencies/tlsf +DUMP_MACHINE = $(shell cc -dumpmachine) +MACHINE_TYPE = $(word 2, $(subst -, , $(DUMP_MACHINE))) +PLATFORM_TYPE = $(MACHINE_TYPE) + +# Detect windows -FL_CPP= \ +ifeq ($(MACHINE_TYPE), w64) +PLATFORM_TYPE = win +endif +ifeq ($(MACHINE_TYPE), w32) +PLATFORM_TYPE = win +endif + +# Paths + +FL_FRAMEWORK = ../FrameLib_Framework +FL_DEPENDENCIES = ../FrameLib_Dependencies +FL_OBJECTS = ../FrameLib_Objects + +VPATH = ../FrameLib_Dependencies/tlsf + +FL_CPP = \ $(wildcard $(FL_FRAMEWORK)/FrameLib_*.cpp)\ $(wildcard $(FL_OBJECTS)/*/FrameLib_*.cpp)\ $(FL_DEPENDENCIES)/HISSTools_FFT/HISSTools_FFT.cpp -FL_OBJ_DIR=$(FL_CPP:.cpp=.o) tlsf.o -FL_OBJ=$(notdir $(FL_OBJ_DIR)) +FL_OBJ_DIR = $(FL_CPP:.cpp=.o) tlsf.o +FL_OBJ = $(notdir $(FL_OBJ_DIR)) -INCLUDE_PATHS=\ +INCLUDE_PATHS = \ -ICommon\ -I$(FL_FRAMEWORK)\ -I$(FL_DEPENDENCIES)\ -I$(FL_OBJECTS)/Common_Utilities/ -MAIN_OBJ=framelib_pd.o -OPTIMISATION=-O3 - -CFLAGS+=$(OPTIMISATION) -CXXFLAGS+=$(OPTIMISATION) -CPPFLAGS+=-DNDEBUG -DFRAMELIB_RT_DSP_CHECK -#OPT=-g - -DUMP_MACHINE=$(shell cc -dumpmachine) -MACHINE_TYPE=$(word 2, $(subst -, , $(DUMP_MACHINE))) - -framelib_pd.d_fat: $(MAIN_OBJ) $(FL_OBJ_DIR); -ifeq ($(MACHINE_TYPE), apple) - cc $(CPPFLAGS) $(CXXFLAGS) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ - $(FL_OBJ) -lstdc++ -lpthread -framework Accelerate -else - cc$(CPPFLAGS) $(CXXFLAGS) -arch x86_64 -bundle -flat_namespace -undefined suppress -o framelib_pd.d_fat $(MAIN_OBJ) \ - $(FL_OBJ) -lstdc++ -lpthread +MAIN_OBJ = framelib_pd.o + +# Options + +OPTIMISATION = -O3 + +CFLAGS = $(OPTIMISATION) +CPPFLAGS = -DNDEBUG -DFRAMELIB_RT_DSP_CHECK +CXXFLAGS = $(OPTIMISATION) + +# Platform Options + +ifeq ($(PLATFORM_TYPE), apple) +EXTENSION = d_fat +ARCH_FLAGS = -arch arm64 -arch x86_64 +LINK_FLAGS = $(shell sed 's/\./-Wl,-U,/g' Common/pd_symbols.txt) -lstdc++ -lpthread -framework Accelerate +PLATFORM_FLAGS = -bundle -flat_namespace -fPIC +endif + +ifeq ($(PLATFORM_TYPE), linux) +CXXFLAGS += -Wno-ignored-attributes -Wno-stringop-overflow +ARCH_FLAGS = +EXTENSION = pd_linux +LINK_FLAGS = $(shell sed 's/\./-Wl,-u,/g' Common/pd_symbols.txt) -lm -lstdc++ -lpthread -latomic +PLATFORM_FLAGS = -no-pie -rdynamic -fPIC -shared +endif + +ifeq ($(PLATFORM_TYPE), win) +CPPFLAGS += -D_USE_MATH_DEFINES -DMSW -DNT +CXXFLAGS += -Wno-ignored-attributes -Wno-stringop-overflow +ARCH_FLAGS = +EXTENSION = dll +#$(shell sed 's/\._/-Wl,-ignore-unresolved-symbol,__imp_/g' Common/pd_symbols.txt) +LINK_FLAGS = -lm -lstdc++ -latomic +DLL = ../../pd-0.52-2/bin/pd.dll +PLATFORM_FLAGS = -static -static-libgcc -static-libstdc++ -Wl,--enable-auto-import "$(DLL)" -shared endif +ifeq ($(MACHINE_TYPE), w64) +CPPFLAGS += -DPD_LONGINTTYPE=intptr_t +endif + +OUTPUT_NAME = framelib_pd.$(EXTENSION) + +# Targets and pattern rules + +framelib_pd: $(MAIN_OBJ) $(FL_OBJ_DIR); + cc $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) $(PLATFORM_FLAGS) -o $(OUTPUT_NAME) $(MAIN_OBJ) $(FL_OBJ) $(LINK_FLAGS) + %.o : %.cpp - g++ $(CPPFLAGS) $(CXXFLAGS) -arch x86_64 -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< + g++ $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< %.o : %.c - cc $(CPPFLAGS) $(CFLAGS) -arch x86_64 -fPIC $(INCLUDE_PATHS) -c $< + cc $(CPPFLAGS) $(CFLAGS) $(ARCH_FLAGS) -fPIC $(INCLUDE_PATHS) -c $< clean: rm $(MAIN_OBJ) $(FL_OBJ) From 628c4fe3e2e79b7011f262fe4471d2f3bfdfd7ad Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 9 Aug 2022 14:44:31 +0100 Subject: [PATCH 175/222] Fix change of phase for single sample inputs --- FrameLib_Dependencies/SpectralProcessor.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/FrameLib_Dependencies/SpectralProcessor.hpp b/FrameLib_Dependencies/SpectralProcessor.hpp index 1e49aeadb..ded7c783b 100644 --- a/FrameLib_Dependencies/SpectralProcessor.hpp +++ b/FrameLib_Dependencies/SpectralProcessor.hpp @@ -175,6 +175,14 @@ class spectral_processor uintptr_t fft_size_log2 = calc_fft_size_log2((uintptr_t) std::round(size * time_multiplier)); uintptr_t fft_size = uintptr_t(1) << fft_size_log2; + // Special case for a single sample input + + if (size == 1) + { + output[0] = input[0]; + return; + } + temporary_buffers<1> buffer(m_allocator, fft_size >> 1); rfft(buffer.m_spectra[0], input, size, fft_size_log2); From 6a9de07eaa76e50fcc7eb979cad5716c84a9a9b9 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 9 Aug 2022 14:45:16 +0100 Subject: [PATCH 176/222] Correct and make safe single sample complex convolution/correlation --- FrameLib_Dependencies/SpectralProcessor.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/FrameLib_Dependencies/SpectralProcessor.hpp b/FrameLib_Dependencies/SpectralProcessor.hpp index ded7c783b..021887faf 100644 --- a/FrameLib_Dependencies/SpectralProcessor.hpp +++ b/FrameLib_Dependencies/SpectralProcessor.hpp @@ -563,6 +563,11 @@ class spectral_processor template void binary_op(T *r_out, T *i_out, in_ptr r_in1, in_ptr i_in1, in_ptr r_in2, in_ptr i_in2, EdgeMode mode) { + auto get_first = [](in_ptr ptr) + { + return ptr.m_size ? ptr.m_ptr[0] : 0.0; + }; + uintptr_t size1 = std::max(r_in1.m_size, i_in1.m_size); uintptr_t size2 = std::max(r_in2.m_size, i_in2.m_size); @@ -573,8 +578,8 @@ class spectral_processor if (size1 == 1 && size2 == 1) { - r_out[0] = r_in1.m_ptr[0] * r_in2.m_ptr[0] + i_in1.m_ptr[0] * i_in2.m_ptr[0]; - i_out[0] = r_in1.m_ptr[0] * i_in2.m_ptr[0] - i_in1.m_ptr[0] * i_in1.m_ptr[0]; + r_out[0] = get_first(r_in1) * get_first(r_in2) - get_first(i_in1) * get_first(i_in2); + i_out[0] = get_first(r_in1) * get_first(i_in2) + get_first(i_in1) * get_first(r_in2); return; } From c0301db38f032553daddb13b516a9ce517660b81 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 9 Aug 2022 16:10:35 +0100 Subject: [PATCH 177/222] Fix FFTs of size 1 --- FrameLib_Dependencies/SpectralProcessor.hpp | 27 ++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/FrameLib_Dependencies/SpectralProcessor.hpp b/FrameLib_Dependencies/SpectralProcessor.hpp index 021887faf..530c8d9c9 100644 --- a/FrameLib_Dependencies/SpectralProcessor.hpp +++ b/FrameLib_Dependencies/SpectralProcessor.hpp @@ -116,32 +116,47 @@ class spectral_processor void fft(Split& io, uintptr_t fft_size_log2) { - hisstools_fft(m_fft_setup, &io, fft_size_log2); + if (fft_size_log2) + hisstools_fft(m_fft_setup, &io, fft_size_log2); } void rfft(Split& io, uintptr_t fft_size_log2) { - hisstools_rfft(m_fft_setup, &io, fft_size_log2); + if (!fft_size_log2) + io[0] * T(2); + else + hisstools_rfft(m_fft_setup, &io, fft_size_log2); } void rfft(Split& output, const T *input, uintptr_t size, uintptr_t fft_size_log2) { - hisstools_rfft(m_fft_setup, input, &output, size, fft_size_log2); + if (!fft_size_log2) + { + output.realp[0] = input[0] * T(2); + output.imagp[0] = T(0); + } + else + hisstools_rfft(m_fft_setup, input, &output, size, fft_size_log2); } void ifft(Split& io, uintptr_t fft_size_log2) { - hisstools_ifft(m_fft_setup, &io, fft_size_log2); + if (fft_size_log2) + hisstools_ifft(m_fft_setup, &io, fft_size_log2); } void rifft(Split& io, uintptr_t fft_size_log2) { - hisstools_rifft(m_fft_setup, &io, fft_size_log2); + if (fft_size_log2) + hisstools_rifft(m_fft_setup, &io, fft_size_log2); } void rifft(T *output, Split& input, uintptr_t fft_size_log2) { - hisstools_rifft(m_fft_setup, &input, output, fft_size_log2); + if (!fft_size_log2) + output[0] = input.realp[0]; + else + hisstools_rifft(m_fft_setup, &input, output, fft_size_log2); } // Convolution From f9b5bc6647d59924d1bae7b80d1ad7eed71ec4a2 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 9 Aug 2022 16:11:36 +0100 Subject: [PATCH 178/222] Fix FFT and iFFT objects for FFTs of size 1 --- FrameLib_Objects/Spectral/FrameLib_FFT.cpp | 12 ++++++++---- FrameLib_Objects/Spectral/FrameLib_iFFT.cpp | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/FrameLib_Objects/Spectral/FrameLib_FFT.cpp b/FrameLib_Objects/Spectral/FrameLib_FFT.cpp index b1fad667c..e2f3810ac 100644 --- a/FrameLib_Objects/Spectral/FrameLib_FFT.cpp +++ b/FrameLib_Objects/Spectral/FrameLib_FFT.cpp @@ -144,9 +144,12 @@ void FrameLib_FFT::process() // Move Nyquist Bin - spectrum.realp[FFTSize >> 1] = spectrum.imagp[0]; - spectrum.imagp[FFTSize >> 1] = 0.0; - spectrum.imagp[0] = 0.0; + if (FFTSizeLog2) + { + spectrum.realp[FFTSize >> 1] = spectrum.imagp[0]; + spectrum.imagp[FFTSize >> 1] = 0.0; + spectrum.imagp[0] = 0.0; + } // Mirror Spectrum @@ -162,7 +165,8 @@ void FrameLib_FFT::process() // Scale - double scale = ((mMode == kComplex) ? 1.0 : 0.5) / (mNormalise ? (double) (FFTSize >> 1) : 1.0); + const bool normalise = (mNormalise && FFTSize > 1); + const double scale = ((mMode == kComplex) ? 1.0 : 0.5) / (normalise ? static_cast(FFTSize) / 2 : 1.0); mProcessor.scale_spectrum(spectrum, sizeOut, scale); } diff --git a/FrameLib_Objects/Spectral/FrameLib_iFFT.cpp b/FrameLib_Objects/Spectral/FrameLib_iFFT.cpp index 705add1b7..dc2ddd0ea 100644 --- a/FrameLib_Objects/Spectral/FrameLib_iFFT.cpp +++ b/FrameLib_Objects/Spectral/FrameLib_iFFT.cpp @@ -150,7 +150,8 @@ void FrameLib_iFFT::process() if (spectrum.realp) { - double scale = mNormalise ? 0.5 : 1.0 / static_cast(1 << FFTSizeLog2); + const bool normalise = (mNormalise && FFTSizeLog2); + const double scale = normalise ? 0.5 : 1.0 / static_cast(1 << FFTSizeLog2); // Copy Spectrum From 826d4fdb8720d73762bf09d615a18dad89538149 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 9 Aug 2022 21:17:10 +0100 Subject: [PATCH 179/222] Fix off by one error in the median filter --- FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp b/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp index 30e29adc8..65af821b8 100644 --- a/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp +++ b/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp @@ -114,7 +114,7 @@ template void filter(T in, double *out, double *data, unsigned long* indices, long width, long size, unsigned long pos) { long o1 = width >> 1; - long o2 = width - o1; + long o2 = width - o1 -1; // Calculate the first percentile From 54971a25f4d933ef88068fe8a8237da9b4f59e43 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 9 Aug 2022 21:18:07 +0100 Subject: [PATCH 180/222] Clarity --- FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp b/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp index 65af821b8..4c3505117 100644 --- a/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp +++ b/FrameLib_Objects/Vector/FrameLib_MedianFilter.cpp @@ -114,7 +114,7 @@ template void filter(T in, double *out, double *data, unsigned long* indices, long width, long size, unsigned long pos) { long o1 = width >> 1; - long o2 = width - o1 -1; + long o2 = (width - o1) - 1; // Calculate the first percentile From faf63db6bbaf8c5393141bbc24b0ee6b6f75f435 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 14 Aug 2022 23:06:39 +0100 Subject: [PATCH 181/222] Update headers and DLL preprocessor items --- FrameLib_PD_Objects/Common/PDClass_Base.h | 2 +- FrameLib_PD_Objects/Common/pd_buffer.h | 2 +- FrameLib_PD_Objects/framelib_pd.cpp | 13 +++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/FrameLib_PD_Objects/Common/PDClass_Base.h b/FrameLib_PD_Objects/Common/PDClass_Base.h index 76ee29458..a798846f5 100644 --- a/FrameLib_PD_Objects/Common/PDClass_Base.h +++ b/FrameLib_PD_Objects/Common/PDClass_Base.h @@ -2,7 +2,7 @@ #ifndef __PD_BASE_H__ #define __PD_BASE_H__ -#include +#include "m_pd.h" #include #include diff --git a/FrameLib_PD_Objects/Common/pd_buffer.h b/FrameLib_PD_Objects/Common/pd_buffer.h index e931360a3..0a0d898e4 100644 --- a/FrameLib_PD_Objects/Common/pd_buffer.h +++ b/FrameLib_PD_Objects/Common/pd_buffer.h @@ -2,7 +2,7 @@ #ifndef PD_BUFFER_H #define PD_BUFFER_H -#include "TableReader.hpp" +#include "../../FrameLib_Dependencies/TableReader.hpp" class pd_buffer { diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index fb229d744..892f75c9f 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -1,11 +1,20 @@ -#include "FrameLib_PDClass.h" +#include "Common/FrameLib_PDClass.h" #include "../FrameLib_Exports/FrameLib_Objects.h" #include "../FrameLib_Exports/FrameLib_TypeAliases.h" // Buffer -#include "pd_buffer.h" +#include "Common/pd_buffer.h" + +// PD_API define + +#if defined(_WIN32) +// Export the symbol to the DLL interface +#define PD_API extern "C" __declspec(dllexport) +#else +#define PD_API extern "C" +#endif // PD_API define From 212ff87bf76077834b5ffa69ba9f0836f314ca01 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 14 Aug 2022 23:06:48 +0100 Subject: [PATCH 182/222] Update PD TO DO --- FrameLib_PD_Objects/PD_TO_DO.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 77963a498..26315a0d4 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -3,12 +3,8 @@ - All (165 out of 165) framelib objects get built to a single library files - Realtime operation and non-realtime operation is supported -- There are some key issues to note below which I'm working through -To build you should be able to run make on this directory and then copy framelib_pd.d_fat and set it to load on startup - -Building works on apple and finishes on linux (although I've not confirmed that my settings are correct as I'm building online for that). -I'm not sure if there should be a VS project for windows or that should also be done via make, and if the latter how to do that. +To build you should be able to run make on this directory and then copy /build/framelib_pd.* and set it to load on startup - I've started a test folder at Testing/02\_PD with a few simple demos @@ -33,7 +29,7 @@ I'm not sure if there should be a VS project for windows or that should also be - My memory is that sigmund uses an attribute-style system so I want to choose something idiomatic to pd for setting these in the box. - sigmund~ uses dashes like the command line so I've copied that for now. [REVIEW] -- Message ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd but logically patch position would seem to make sense, so I'm implenting that [REVIEW] +- Message Ordering - If messages are sent to pd then currently the message time and stream determines the order. In Max there are further considerations to do with object position in a patch so that ordering makes sense - I'm not sure what would be idomatic in pd but logically patch position would seem to make sense, so I'm implenting that [REVIEW] **Review** @@ -55,7 +51,5 @@ I'm not sure if there should be a VS project for windows or that should also be **Build System and Distribution** -- The makefile is very basic and currently builds the default architecture only - I need to understand what file names/architectures etc. should be for different systems -- I need to improve the makefile or build system to support all necessary platforms and OSes -- At the moment object files go into the main PD folder - I'd like them to go into a build directory but I don't know make well enough +- Building currently works with CI on apple (arm / x86_64), linux (i386 / x86_64) and windows (x86_64) From d13e4c27277768f4a59dd155b1222bfc00b9d3de Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sun, 14 Aug 2022 23:07:21 +0100 Subject: [PATCH 183/222] Improve makefile for object location and multiplatform builds --- FrameLib_PD_Objects/makefile | 60 +++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index 66062e1a2..dced82f43 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -8,11 +8,17 @@ PLATFORM_TYPE = $(MACHINE_TYPE) ifeq ($(MACHINE_TYPE), w64) PLATFORM_TYPE = win +BUILD_TYPE ?= x86_64 endif ifeq ($(MACHINE_TYPE), w32) PLATFORM_TYPE = win +BUILD_TYPE ?= i386 endif +BUILD_TYPE ?= +BUILD_DIR ?= ../build +INTERMEDIATE_DIR ?= $(BUILD_DIR)/objects + # Paths FL_FRAMEWORK = ../FrameLib_Framework @@ -26,16 +32,15 @@ FL_CPP = \ $(wildcard $(FL_OBJECTS)/*/FrameLib_*.cpp)\ $(FL_DEPENDENCIES)/HISSTools_FFT/HISSTools_FFT.cpp -FL_OBJ_DIR = $(FL_CPP:.cpp=.o) tlsf.o -FL_OBJ = $(notdir $(FL_OBJ_DIR)) +FL_OBJ = $(FL_CPP:.cpp=.o) tlsf.o +FL_OBJ_OUT = $(addprefix $(INTERMEDIATE_DIR)/, $(notdir $(FL_OBJ))) INCLUDE_PATHS = \ - -ICommon\ -I$(FL_FRAMEWORK)\ - -I$(FL_DEPENDENCIES)\ -I$(FL_OBJECTS)/Common_Utilities/ MAIN_OBJ = framelib_pd.o +MAIN_OBJ_OUT = $(INTERMEDIATE_DIR)/$(MAIN_OBJ) # Options @@ -56,39 +61,52 @@ endif ifeq ($(PLATFORM_TYPE), linux) CXXFLAGS += -Wno-ignored-attributes -Wno-stringop-overflow -ARCH_FLAGS = EXTENSION = pd_linux LINK_FLAGS = $(shell sed 's/\./-Wl,-u,/g' Common/pd_symbols.txt) -lm -lstdc++ -lpthread -latomic PLATFORM_FLAGS = -no-pie -rdynamic -fPIC -shared +ARCH_FLAGS = +ifeq ($(BUILD_TYPE), i386) +ARCH_FLAGS = -m32 -march=i386 +endif endif ifeq ($(PLATFORM_TYPE), win) -CPPFLAGS += -D_USE_MATH_DEFINES -DMSW -DNT +CPPFLAGS += -D_USE_MATH_DEFINES -DMSW -DNT -DPD_LONGINTTYPE=intptr_t CXXFLAGS += -Wno-ignored-attributes -Wno-stringop-overflow -ARCH_FLAGS = EXTENSION = dll -#$(shell sed 's/\._/-Wl,-ignore-unresolved-symbol,__imp_/g' Common/pd_symbols.txt) LINK_FLAGS = -lm -lstdc++ -latomic DLL = ../../pd-0.52-2/bin/pd.dll PLATFORM_FLAGS = -static -static-libgcc -static-libstdc++ -Wl,--enable-auto-import "$(DLL)" -shared +ARCH_FLAGS = +ifeq ($(BUILD_TYPE), i386) +DLL = ../../pd-0.52-2-i386/bin/pd.dll +ARCH_FLAGS = -march=i386 endif - -ifeq ($(MACHINE_TYPE), w64) -CPPFLAGS += -DPD_LONGINTTYPE=intptr_t endif -OUTPUT_NAME = framelib_pd.$(EXTENSION) +OUTPUT_NAME = $(BUILD_DIR)/framelib_pd.$(EXTENSION) # Targets and pattern rules -framelib_pd: $(MAIN_OBJ) $(FL_OBJ_DIR); - cc $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) $(PLATFORM_FLAGS) -o $(OUTPUT_NAME) $(MAIN_OBJ) $(FL_OBJ) $(LINK_FLAGS) - -%.o : %.cpp - g++ $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< +framelib_pd: $(MAIN_OBJ) $(FL_OBJ) build_directory; + cc $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) $(PLATFORM_FLAGS) -o $(OUTPUT_NAME) $(MAIN_OBJ_OUT) $(FL_OBJ_OUT) $(LINK_FLAGS) -%.o : %.c - cc $(CPPFLAGS) $(CFLAGS) $(ARCH_FLAGS) -fPIC $(INCLUDE_PATHS) -c $< - +build_directory: + mkdir -p $(BUILD_DIR) + +intermediate_directory: + mkdir -p $(INTERMEDIATE_DIR) + +%.o : %.cpp intermediate_directory + g++ $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) -std=c++11 -fPIC $(INCLUDE_PATHS) -c $< -o $(INTERMEDIATE_DIR)/$(@F) + +%.o : %.c intermediate_directory + cc $(CPPFLAGS) $(CFLAGS) $(ARCH_FLAGS) -fPIC $(INCLUDE_PATHS) -c $< -o $(INTERMEDIATE_DIR)/$(@F) + +.PHONY: clean + clean: - rm $(MAIN_OBJ) $(FL_OBJ) + rm -f -r $(INTERMEDIATE_DIR) + rm -f $(OUTPUT_NAME) + + From 3f8a6108c8c68105628e1c319eb90b01a62fadc1 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 23 Aug 2022 16:05:01 +0100 Subject: [PATCH 184/222] Sampling rate updates (allow the value to be taken from the network) --- FrameLib_Objects/Buffer/FrameLib_Info.cpp | 4 +++- FrameLib_Objects/Buffer/FrameLib_Read.cpp | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/FrameLib_Objects/Buffer/FrameLib_Info.cpp b/FrameLib_Objects/Buffer/FrameLib_Info.cpp index ce73c0bd4..ee292da7f 100644 --- a/FrameLib_Objects/Buffer/FrameLib_Info.cpp +++ b/FrameLib_Objects/Buffer/FrameLib_Info.cpp @@ -72,7 +72,9 @@ void FrameLib_Info::update() void FrameLib_Info::process() { - double samplingRate = 0.0; + // Default the sampling rate to use the network rate + + double samplingRate = mSamplingRate; double conversionFactor = 1.0; unsigned long length = 0; unsigned long chans = 0; diff --git a/FrameLib_Objects/Buffer/FrameLib_Read.cpp b/FrameLib_Objects/Buffer/FrameLib_Read.cpp index f787fee54..6729d1388 100644 --- a/FrameLib_Objects/Buffer/FrameLib_Read.cpp +++ b/FrameLib_Objects/Buffer/FrameLib_Read.cpp @@ -133,7 +133,9 @@ void FrameLib_Read::process() double *output = getOutput(0, &size); - double samplingRate = 0.0; + // Default the sampling rate to use the network rate + + double samplingRate = mSamplingRate; unsigned long length = 0; // Get buffer @@ -152,9 +154,6 @@ void FrameLib_Read::process() double scale = 1.0; double lengthM1 = length - 1.0; - if (!samplingRate) - samplingRate = mSamplingRate; - switch (mParameters.getEnum(kUnits)) { case kSamples: scale = 1.0; break; From 091d52a2e62b58b4e4efc96404cea8d212280993 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 23 Aug 2022 16:05:51 +0100 Subject: [PATCH 185/222] Implement multichannel pd buffers and fl.info~ for pd --- FrameLib_PD_Objects/Common/pd_buffer.h | 87 +++++++++++++++++++++----- FrameLib_PD_Objects/framelib_pd.cpp | 72 ++++++++++++++++----- 2 files changed, 126 insertions(+), 33 deletions(-) diff --git a/FrameLib_PD_Objects/Common/pd_buffer.h b/FrameLib_PD_Objects/Common/pd_buffer.h index 0a0d898e4..443d4ae59 100644 --- a/FrameLib_PD_Objects/Common/pd_buffer.h +++ b/FrameLib_PD_Objects/Common/pd_buffer.h @@ -21,29 +21,31 @@ class pd_buffer public: - pd_buffer() : m_array(nullptr), m_table(nullptr), m_length(0) {} + pd_buffer() : m_name(nullptr), m_length(0) {} - pd_buffer(t_symbol *name) : m_table(nullptr), m_length(0) + pd_buffer(t_symbol *name) : m_name(name), m_length(0) { - m_array = (t_garray *) pd_findbyclass(name, garray_class); - - if (m_array) - garray_getfloatwords(m_array, &m_length, &m_table); + get_buffer_data(); } - bool is_valid() const { return m_table && (m_length > 0); } + bool is_valid() const { return m_length > 0; } int get_length() const { return m_length; } - - void read(double *output, const double *positions, unsigned long size, double amp, InterpType interp, EdgeMode edges, bool bound) + int get_num_chans() const { return m_num_chans; } + + void read(double *output, const double *positions, unsigned long size, double amp, long chan, InterpType interp, EdgeMode edges, bool bound) { - table_read_edges(fetch(m_table, m_length), output, positions, size, amp, interp, edges, bound); + t_word *table = get_array_data(static_cast(chan)); + + if (table) + table_read_edges(fetch(table, m_length), output, positions, size, amp, interp, edges, bound); } void read(double *output, size_t length, size_t offset, size_t chan) { - intptr_t read_length = static_cast(constrain_length(length, chan, offset)); + t_word *table = get_array_data(chan); + intptr_t read_length = table ? static_cast(constrain_length(length, chan, offset)) : 0; - fetch fetcher(m_table, m_length); + fetch fetcher(table, m_length); for (intptr_t i = 0; i < read_length; i++) output[i] = fetcher(offset + i); @@ -55,24 +57,75 @@ class pd_buffer void write(const double *input, size_t length, size_t offset, size_t chan) { + t_garray *array = get_array(chan); + t_word *table = get_array_data(array); length = constrain_length(length, chan, offset); - fetch writer(m_table, m_length); + fetch writer(table, m_length); for (size_t i = 0; i < length; i++) writer(i + offset) = static_cast(input[i]); if (length) - garray_redraw(m_array); + garray_redraw(array); } private: + void get_buffer_data() + { + m_length = 0; + m_num_chans = 0; + + int length; + + for (; ; m_num_chans++) + { + if (!get_array_data(m_num_chans, &length)) + return; + + m_length = m_num_chans ? std::min(m_length, length) : length; + } + } + + t_garray *get_array(size_t chan) const + { + t_symbol *name = m_name; + + if (chan || !pd_findbyclass(name, garray_class)) + { + char name_string[MAXPDSTRING]; + int number = static_cast(chan + 1); + + snprintf(name_string, MAXPDSTRING, "%s-%d", m_name->s_name, number); + + name = gensym(name_string); + } + + return (t_garray *) pd_findbyclass(name, garray_class); + } + + t_word *get_array_data(t_garray *array, int *length = nullptr) + { + t_word *data = nullptr; + int local_length = 0; + + if (array) + garray_getfloatwords(array, length ? length : &local_length, &data); + + return data; + } + + t_word *get_array_data(size_t chan, int *length = nullptr) + { + return get_array_data(get_array(chan), length); + } + size_t constrain_length(size_t length, size_t chan, size_t offset) { // Request is entirely outside of the buffer's memory - if (offset >= static_cast(m_length)) + if (chan >= static_cast(m_num_chans) || offset >= static_cast(m_length)) return 0; // Request is partially outside of the buffer's memory @@ -83,8 +136,8 @@ class pd_buffer return length; } - t_garray *m_array; - t_word *m_table; + t_symbol *m_name; + int m_num_chans; int m_length; }; diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index 892f75c9f..c7075dfae 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -16,15 +16,6 @@ #define PD_API extern "C" #endif -// PD_API define - -#if defined(_WIN32) -// Export the symbol to the DLL interface -#define PD_API extern "C" __declspec(dllexport) -#else -#define PD_API extern "C" -#endif - // Context Control - A pd class to communicate with the current pd class FrameLib_PDClass_ContextControl : public PDClass_Base @@ -363,9 +354,10 @@ class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand void acquire(unsigned long& length, double& samplingRate) override { + // Leave the sampling rate as it is (pd provides no sr for tables) + mBuffer = pd_buffer(mBufferName); - length = mBuffer.get_length(); - samplingRate = 0.0; + length = static_cast(mBuffer.get_length()); } void release() override @@ -375,7 +367,8 @@ class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand void read(double *output, const double *positions, unsigned long size, long chan, InterpType interp, EdgeMode edges, bool bound) override { - mBuffer.read(output, positions, size, 1.0, interp, edges, bound); + chan = std::max(0L, std::min(chan, static_cast(mBuffer.get_num_chans() - 1))); + mBuffer.read(output, positions, size, 1.0, chan, interp, edges, bound); } FrameLib_Read::Proxy *clone() const override @@ -397,6 +390,55 @@ class FrameLib_PDClass_Read : public FrameLib_PDClass_Expand : FrameLib_PDClass(x, s, argc, argv, new ReadProxy(x)) {} }; +// PD Info Class + +class FrameLib_PDClass_Info : public FrameLib_PDClass_Expand +{ + struct InfoProxy : public FrameLib_Info::Proxy, public FrameLib_PDProxy + { + InfoProxy(t_object *x) + : FrameLib_PDProxy(x) + , mBuffer(nullptr) + {} + + void update(const char *name) override + { + mBufferName = gensym(name); + } + + void acquire(unsigned long& length, double& samplingRate, unsigned long& chans) override + { + // Leave the sampling rate as it is (pd provides no sr for tables) + + mBuffer = pd_buffer(mBufferName); + length = static_cast(mBuffer.get_length()); + chans = static_cast(mBuffer.get_num_chans()); + } + + void release() override + { + mBuffer = pd_buffer(); + }; + + FrameLib_Info::Proxy *clone() const override + { + return new InfoProxy(*this); + } + + private: + + pd_buffer mBuffer; + t_symbol *mBufferName; + }; + +public: + + // Constructor + + FrameLib_PDClass_Info(t_object *x, t_symbol *s, long argc, t_atom *argv) + : FrameLib_PDClass(x, s, argc, argv, new InfoProxy(x)) {} +}; + // PD Expression Classes // The expression objects parses arguments differently to normal, which is handled by pre-parsing the atoms into a different format @@ -769,9 +811,7 @@ PD_API void framelib_pd_setup(void) FrameLib_PDClass_Expand::makeClass("fl.complex.pow~"); // Buffer - - // FIX - info is not correct - - FrameLib_PDClass_Expand::makeClass("fl.info~"); + + FrameLib_PDClass_Info::makeClass("fl.info~"); FrameLib_PDClass_Read::makeClass("fl.read~"); } From d75f199cf717363a263b8423335768e1f951c1dd Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 23 Aug 2022 16:06:00 +0100 Subject: [PATCH 186/222] update PD TODO --- FrameLib_PD_Objects/PD_TO_DO.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FrameLib_PD_Objects/PD_TO_DO.md b/FrameLib_PD_Objects/PD_TO_DO.md index 26315a0d4..317ab950b 100644 --- a/FrameLib_PD_Objects/PD_TO_DO.md +++ b/FrameLib_PD_Objects/PD_TO_DO.md @@ -14,6 +14,7 @@ To build you should be able to run make on this directory and then copy /build/f - At the moment you can't connect framelib objects between different subpatchers - Multichannel buffers - my understanding is that pd buffers are mono only - buffers for framelib can be used both for reading and also for non-realtime operation, so figuring out how to support multichannel in an idomatic way would be good +- I've implemented what should be the same as flucoma but there's two decisions (order of elements in the name and 0/1 indexing) [REVIEW] - *Audio synchronisation* - this is the main issue with finishing pd support and the Max approach won't work here - Because audio inputs and outputs are in different objects they must process audio in the correct order @@ -51,5 +52,6 @@ To build you should be able to run make on this directory and then copy /build/f **Build System and Distribution** -- I need to understand what file names/architectures etc. should be for different systems -- Building currently works with CI on apple (arm / x86_64), linux (i386 / x86_64) and windows (x86_64) +- I need to understand what file names/architectures etc. should be for different systems and compiler flags and get linux tested for arm +- Building currently works with CI on apple (arm / x86_64), linux (i386 / x86_64 / armv6 / armv7 / aarch64) and windows (i386 / x86_64) + From 0c4c5436ab17f47c3125f384e6387fda9f1f892c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 23 Aug 2022 16:06:15 +0100 Subject: [PATCH 187/222] Arm support improvements from HISSTools_Library --- .../HISSTools_FFT/HISSTools_FFT_Core.h | 10 +- FrameLib_Dependencies/SIMDSupport.hpp | 189 +++++++++++++----- 2 files changed, 146 insertions(+), 53 deletions(-) diff --git a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h index 3b3cfcb67..7e7d90eff 100755 --- a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h +++ b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h @@ -5,7 +5,7 @@ #include #include -#if defined(__arm__) || defined(__arm64) +#if defined(__arm__) || defined(__arm64) || defined(__aarch64__) #include #include #elif defined(__APPLE__) || defined(__linux__) || defined(_WIN32) @@ -56,7 +56,7 @@ namespace hisstools_fft_impl{ template<> struct SIMDLimits { static constexpr int max_size = 2; }; template<> struct SIMDLimits { static constexpr int max_size = 4; }; -#elif defined(__arm__) || defined(__arm64__) +#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__) template<> struct SIMDLimits { static constexpr int max_size = 4; }; @@ -78,7 +78,7 @@ namespace hisstools_fft_impl{ return nullptr; } -#elif defined(__arm__) || defined(__arm64__) +#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__) template T *allocate_aligned(size_t size) @@ -314,7 +314,7 @@ namespace hisstools_fft_impl{ #endif -#if defined(__arm__) || defined(__arm64__) +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) template<> struct SIMDVector : public SIMDVectorBase @@ -594,7 +594,7 @@ namespace hisstools_fft_impl{ #endif -#if defined(__arm__) || defined(__arm64__) +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) // Template Specialisation for an ARM Float Packed (1 SIMD Element) diff --git a/FrameLib_Dependencies/SIMDSupport.hpp b/FrameLib_Dependencies/SIMDSupport.hpp index 6ead306a6..1ae92dc68 100755 --- a/FrameLib_Dependencies/SIMDSupport.hpp +++ b/FrameLib_Dependencies/SIMDSupport.hpp @@ -9,7 +9,7 @@ #include #include -#if defined(__arm__) || defined(__arm64) +#if defined(__arm__) || defined(__arm64) || defined(__aarch64__) #include #include #include @@ -81,10 +81,10 @@ struct SIMDLimits static constexpr int byte_width = 32; }; -#elif defined(__SSE__) || defined(__arm__) || defined(__arm64) +#elif defined(__SSE__) || defined(__arm__) || defined(__arm64) || defined(__aarch64__) #define SIMD_COMPILER_SUPPORT_LEVEL SIMD_COMPILER_SUPPORT_VEC128 -#if defined (__SSE__) || defined(__arm64) +#if defined (__SSE__) || defined(__arm64) || defined(__aarch64__) template<> struct SIMDLimits { @@ -170,12 +170,19 @@ struct SIMDDenormals #if (SIMD_COMPILER_SUPPORT_LEVEL >= SIMD_COMPILER_SUPPORT_VEC128) #if defined SIMD_COMPILER_SUPPORT_NEON -#if defined(__arm64) +#if defined(__arm64) || defined(__aarch64__) + static constexpr unsigned long long ftz() + { + // __fpcr_flush_to_zero on apple, but better to be portable + + return 0x01000000ULL; + } + static denormal_flags flags() { fenv_t env; fegetenv(&env); - return make_flags(false, env.__fpcr & __fpcr_flush_to_zero); + return make_flags(false, env.__fpcr & ftz()); } static void set(denormal_flags flags) @@ -184,18 +191,31 @@ struct SIMDDenormals fegetenv(&env); if (flags.test(1)) - env.__fpcr |= __fpcr_flush_to_zero; + env.__fpcr |= ftz(); else - env.__fpcr ^= __fpcr_flush_to_zero; + env.__fpcr ^= ftz(); fesetenv(&env); } #else + + static unsigned int& get_fpscr(fenv_t& env) + { + return env.__cw; + } + + static constexpr unsigned int ftz() + { + // __fpscr_flush_to_zero on apple, but better to be portable + + return 0x01000000U; + } + static denormal_flags flags() { fenv_t env; fegetenv(&env); - return make_flags(false, env.__fpscr & __fpscr_flush_to_zero); + return make_flags(false, get_fpscr(env) & ftz()); } static void set(denormal_flags flags) @@ -204,9 +224,9 @@ struct SIMDDenormals fegetenv(&env); if (flags.test(1)) - env.__fpscr |= & __fpscr_flush_to_zero; + get_fpscr(env) |= ftz(); else - env.__fpscr |= ^ __fpscr_flush_to_zero; + get_fpscr(env) ^= ftz(); fesetenv(&env); } @@ -420,10 +440,10 @@ struct SIMDType SIMDType& operator *= (const SIMDType& b) { return (*this = *this * b); } SIMDType& operator /= (const SIMDType& b) { return (*this = *this / b); } - friend SIMDType sqrt(const SIMDType& a) { return sqrt(a.mVal); } + friend SIMDType sqrt(const SIMDType& a) { return std::sqrt(a.mVal); } - friend SIMDType round(const SIMDType& a) { return round(a.mVal); } - friend SIMDType trunc(const SIMDType& a) { return trunc(a.mVal); } + friend SIMDType round(const SIMDType& a) { return std::round(a.mVal); } + friend SIMDType trunc(const SIMDType& a) { return std::trunc(a.mVal); } friend SIMDType min(const SIMDType& a, const SIMDType& b) { return std::min(a.mVal, b.mVal); } friend SIMDType max(const SIMDType& a, const SIMDType& b) { return std::max(a.mVal, b.mVal); } @@ -463,10 +483,10 @@ struct SIMDType SIMDType& operator *= (const SIMDType& b) { return (*this = *this * b); } SIMDType& operator /= (const SIMDType& b) { return (*this = *this / b); } - friend SIMDType sqrt(const SIMDType& a) { return sqrtf(a.mVal); } + friend SIMDType sqrt(const SIMDType& a) { return std::sqrt(a.mVal); } - friend SIMDType round(const SIMDType& a) { return roundf(a.mVal); } - friend SIMDType trunc(const SIMDType& a) { return truncf(a.mVal); } + friend SIMDType round(const SIMDType& a) { return std::round(a.mVal); } + friend SIMDType trunc(const SIMDType& a) { return std::trunc(a.mVal); } friend SIMDType min(const SIMDType& a, const SIMDType& b) { return std::min(a.mVal, b.mVal); } friend SIMDType max(const SIMDType& a, const SIMDType& b) { return std::max(a.mVal, b.mVal); } @@ -529,21 +549,27 @@ struct SIMDType #ifdef SIMD_COMPILER_SUPPORT_NEON /* Neon Intrinsics */ -#if defined(__arm64) +#if defined(__arm64) || defined(__aarch64__) template<> struct SIMDType : public SIMDVector { private: - template + template + static SIMDType compare(const SIMDType& a, const SIMDType& b) + { + return vreinterpretq_f64_u64(Op(a.mVal, b.mVal)); + } + + template static SIMDType bitwise(const SIMDType& a, const SIMDType& b) { - return vreinterpretq_s64_f64(Op(vreinterpretq_s64_f64(a.mVal), vreinterpretq_s64_f64(b.mVal))); + return vreinterpretq_f64_u64(Op(vreinterpretq_u64_f64(a.mVal), vreinterpretq_u64_f64(b.mVal))); } - static float64x2_t neq(float64x2_t a, float64x2_t b) + static float64x2_t neq(const SIMDType& a, const SIMDType& b) { - return vreinterpretq_s32_f64(vmvnq_s32(vreinterpretq_s32_f64(vceqq_f64(a, b)))); + return vreinterpretq_f64_u32(vmvnq_u32(vreinterpretq_u32_u64(vceqq_f64(a.mVal, b.mVal)))); } public: @@ -586,17 +612,17 @@ struct SIMDType : public SIMDVector friend SIMDType sel(const SIMDType& a, const SIMDType& b, const SIMDType& c) { return and_not(c, a) | (b & c); } // N.B. - operand swap for and_not - friend SIMDType and_not(const SIMDType& a, const SIMDType& b) { return bitwise(b, a); } - friend SIMDType operator & (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } - friend SIMDType operator | (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } - friend SIMDType operator ^ (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } - - friend SIMDType operator == (const SIMDType& a, const SIMDType& b) { return vceqq_f64(a.mVal, b.mVal); } - friend SIMDType operator != (const SIMDType& a, const SIMDType& b) { return neq(a.mVal, b.mVal); } - friend SIMDType operator > (const SIMDType& a, const SIMDType& b) { return vcgtq_f64(a.mVal, b.mVal); } - friend SIMDType operator < (const SIMDType& a, const SIMDType& b) { return vcltq_f64(a.mVal, b.mVal); } - friend SIMDType operator >= (const SIMDType& a, const SIMDType& b) { return vcgeq_f64(a.mVal, b.mVal); } - friend SIMDType operator <= (const SIMDType& a, const SIMDType& b) { return vcleq_f64(a.mVal, b.mVal); } + friend SIMDType and_not(const SIMDType& a, const SIMDType& b) { return bitwise(b, a); } + friend SIMDType operator & (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } + friend SIMDType operator | (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } + friend SIMDType operator ^ (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } + + friend SIMDType operator == (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator != (const SIMDType& a, const SIMDType& b) { return neq(a, b); } + friend SIMDType operator > (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator < (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator >= (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator <= (const SIMDType& a, const SIMDType& b) { return compare(a, b); } /* template static SIMDType shuffle(const SIMDType& a, const SIMDType& b) @@ -613,24 +639,79 @@ struct SIMDType : public SIMDVector return SIMDType(static_cast(vals[0]), static_cast(vals[1])); } }; -#endif /* defined (__arm64) */ +#endif /* defined (__arm64) || defined(__aarch64__) */ template<> struct SIMDType : public SIMDVector { private: - template + template + static SIMDType compare(const SIMDType& a, const SIMDType& b) + { + return vreinterpretq_f32_u32(Op(a.mVal, b.mVal)); + } + + template static SIMDType bitwise(const SIMDType& a, const SIMDType& b) { - return vreinterpretq_s32_f32(Op(vreinterpretq_s32_f32(a.mVal), vreinterpretq_s32_f32(b.mVal))); + return vreinterpretq_f32_u32(Op(vreinterpretq_u32_f32(a.mVal), vreinterpretq_u32_f32(b.mVal))); } - static float32x4_t neq(float32x4_t a, float32x4_t b) + static float32x4_t neq(const SIMDType& a, const SIMDType& b) { - return vreinterpretq_s32_f32(vmvnq_s32(vreinterpretq_s32_f32(vceqq_f32(a, b)))); + return vreinterpretq_f32_u32(vmvnq_u32(vceqq_f32(a.mVal, b.mVal))); + } + +#if !defined(__arm64) && !defined(__aarch64__) + + // Helpers for single value iteration + + template + static void iterate(V out[4], float temp[4], const float32x4_t& a) + { + vst1q_f32(temp, a); + + out[0] = Op(temp[0]); + out[1] = Op(temp[1]); + out[2] = Op(temp[2]); + out[3] = Op(temp[3]); } + template + static float32x4_t unary(const float32x4_t& a) + { + float vals[4]; + + iterate(vals, vals, a); + + return vld1q_f32(vals); + } + + static double cast_f64_f2(float a) { return static_cast(a); } + + // Emulate these for 32 bit + + static float32x4_t vsqrtq_f32(const float32x4_t& a) { return unary(a); } + static float32x4_t vrndq_f32(const float32x4_t& a) { return unary(a); } + + static float32x4_t vdivq_f32(const float32x4_t& a, const float32x4_t& b) + { + float vals_a[4], vals_b[4]; + + vst1q_f32(vals_a, a); + vst1q_f32(vals_b, b); + + vals_a[0] /= vals_b[0]; + vals_a[1] /= vals_b[1]; + vals_a[2] /= vals_b[2]; + vals_a[3] /= vals_b[3]; + + return vld1q_f32(vals_a); + } + +#endif + public: SIMDType() {} @@ -661,17 +742,17 @@ struct SIMDType : public SIMDVector friend SIMDType sel(const SIMDType& a, const SIMDType& b, const SIMDType& c) { return and_not(c, a) | (b & c); } // N.B. - operand swap for and_not - friend SIMDType and_not(const SIMDType& a, const SIMDType& b) { return bitwise(b, a); } - friend SIMDType operator & (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } - friend SIMDType operator | (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } - friend SIMDType operator ^ (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } - - friend SIMDType operator == (const SIMDType& a, const SIMDType& b) { return vceqq_f32(a.mVal, b.mVal); } - friend SIMDType operator != (const SIMDType& a, const SIMDType& b) { return neq(a.mVal, b.mVal); } - friend SIMDType operator > (const SIMDType& a, const SIMDType& b) { return vcgtq_f32(a.mVal, b.mVal); } - friend SIMDType operator < (const SIMDType& a, const SIMDType& b) { return vcltq_f32(a.mVal, b.mVal); } - friend SIMDType operator >= (const SIMDType& a, const SIMDType& b) { return vcgeq_f32(a.mVal, b.mVal); } - friend SIMDType operator <= (const SIMDType& a, const SIMDType& b) { return vcleq_f32(a.mVal, b.mVal); } + friend SIMDType and_not(const SIMDType& a, const SIMDType& b) { return bitwise(b, a); } + friend SIMDType operator & (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } + friend SIMDType operator | (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } + friend SIMDType operator ^ (const SIMDType& a, const SIMDType& b) { return bitwise(a, b); } + + friend SIMDType operator == (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator != (const SIMDType& a, const SIMDType& b) { return neq(a, b); } + friend SIMDType operator > (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator < (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator >= (const SIMDType& a, const SIMDType& b) { return compare(a, b); } + friend SIMDType operator <= (const SIMDType& a, const SIMDType& b) { return compare(a, b); } /* template static SIMDType shuffle(const SIMDType& a, const SIMDType& b) @@ -679,6 +760,7 @@ struct SIMDType : public SIMDVector return _mm_shuffle_ps(a.mVal, b.mVal, ((z<<6)|(y<<4)|(x<<2)|w)); }*/ +#if defined(__arm64) || defined(__aarch64__) operator SizedVector() const { SizedVector vec; @@ -688,6 +770,17 @@ struct SIMDType : public SIMDVector return vec; } +#else + operator SizedVector() const + { + float vals[4]; + SizedVector vec; + + iterate(vec.mData, vals, mVal); + + return vec; + } +#endif }; template<> From d1324b0e12f558d55ec908f5c33b2544ba29b320 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 23 Aug 2022 16:06:34 +0100 Subject: [PATCH 188/222] Update makefile for improved PD builds --- FrameLib_PD_Objects/makefile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/FrameLib_PD_Objects/makefile b/FrameLib_PD_Objects/makefile index dced82f43..d1b617cc4 100644 --- a/FrameLib_PD_Objects/makefile +++ b/FrameLib_PD_Objects/makefile @@ -1,6 +1,7 @@ SHELL = /bin/sh DUMP_MACHINE = $(shell cc -dumpmachine) +ARCH_TYPE = $(word 1, $(subst -, , $(DUMP_MACHINE))) MACHINE_TYPE = $(word 2, $(subst -, , $(DUMP_MACHINE))) PLATFORM_TYPE = $(MACHINE_TYPE) @@ -15,9 +16,10 @@ PLATFORM_TYPE = win BUILD_TYPE ?= i386 endif -BUILD_TYPE ?= +BUILD_TYPE ?= $(ARCH_TYPE) BUILD_DIR ?= ../build INTERMEDIATE_DIR ?= $(BUILD_DIR)/objects +NAME_SUFFIX ?= $(BUILD_TYPE) # Paths @@ -28,11 +30,11 @@ FL_OBJECTS = ../FrameLib_Objects VPATH = ../FrameLib_Dependencies/tlsf FL_CPP = \ + $(FL_DEPENDENCIES)/HISSTools_FFT/HISSTools_FFT.cpp\ $(wildcard $(FL_FRAMEWORK)/FrameLib_*.cpp)\ $(wildcard $(FL_OBJECTS)/*/FrameLib_*.cpp)\ - $(FL_DEPENDENCIES)/HISSTools_FFT/HISSTools_FFT.cpp -FL_OBJ = $(FL_CPP:.cpp=.o) tlsf.o +FL_OBJ = tlsf.o $(FL_CPP:.cpp=.o) FL_OBJ_OUT = $(addprefix $(INTERMEDIATE_DIR)/, $(notdir $(FL_OBJ))) INCLUDE_PATHS = \ @@ -68,6 +70,9 @@ ARCH_FLAGS = ifeq ($(BUILD_TYPE), i386) ARCH_FLAGS = -m32 -march=i386 endif +ifeq ($(ARCH_TYPE), arm) +ARCH_FLAGS = -mfpu=neon +endif endif ifeq ($(PLATFORM_TYPE), win) @@ -84,12 +89,12 @@ ARCH_FLAGS = -march=i386 endif endif -OUTPUT_NAME = $(BUILD_DIR)/framelib_pd.$(EXTENSION) +OUTPUT_NAME = $(BUILD_DIR)/framelib_pd-$(NAME_SUFFIX).$(EXTENSION) # Targets and pattern rules -framelib_pd: $(MAIN_OBJ) $(FL_OBJ) build_directory; - cc $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) $(PLATFORM_FLAGS) -o $(OUTPUT_NAME) $(MAIN_OBJ_OUT) $(FL_OBJ_OUT) $(LINK_FLAGS) +framelib_pd: build_directory $(FL_OBJ) $(MAIN_OBJ); + cc $(CPPFLAGS) $(CXXFLAGS) $(ARCH_FLAGS) $(PLATFORM_FLAGS) -o $(OUTPUT_NAME) $(FL_OBJ_OUT) $(MAIN_OBJ_OUT) $(LINK_FLAGS) build_directory: mkdir -p $(BUILD_DIR) From 641942ae6d9d904528ffc9a74c65ee68af919d65 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Tue, 23 Aug 2022 16:09:58 +0100 Subject: [PATCH 189/222] Add workflow builds --- .github/actions/mac-notarization/action.yml | 71 +++++++++ .github/workflows/max-build.yml | 88 ++++++++++++ .github/workflows/pd-build.yml | 150 ++++++++++++++++++++ 3 files changed, 309 insertions(+) create mode 100644 .github/actions/mac-notarization/action.yml create mode 100644 .github/workflows/max-build.yml create mode 100644 .github/workflows/pd-build.yml diff --git a/.github/actions/mac-notarization/action.yml b/.github/actions/mac-notarization/action.yml new file mode 100644 index 000000000..ae43db048 --- /dev/null +++ b/.github/actions/mac-notarization/action.yml @@ -0,0 +1,71 @@ +name: notarize-github +description: 'Uses xcode command line tools to sign the binaries and notarize them' +inputs: + folder: + description: 'Folder containing the binaries' + type: string + required: true + glob: + description: 'Glob for binaries' + type: string + required: true + default: '-e mxo' + apple_id: + description: 'Apple ID' + type: string + required: true + team_id: + description: 'Apple Team ID' + type: string + required: true + app_specific_pwd: + description: 'Apple Specific Password' + type: string + required: true + cert_pwd: + description: 'Certificate Password' + type: string + required: true + cert_base64: + description: 'Base64-encoded Certificate' + type: string + required: true + +runs: + using: "composite" + steps: + - name: Setup keychain and identities + shell: bash + env: + TEAM_ID: ${{ inputs.team_id }} + APPLE_ID: ${{ inputs.apple_id }} + APP_SPECIFIC_PWD: ${{ inputs.app_specific_pwd }} + CERT_PWD: ${{ inputs.cert_pwd }} + CERT_BASE64: ${{ inputs.cert_base64}} + CERTPATH: ${{ runner.temp }}/certificate.p12 + KEYCHAINPWD: temporarykeychainpassword + KEYCHAINPATH: ${{ runner.temp }}/app-signing.keychain-db + # create and setup a temporary keychain, then decode the certificate and setup creditials for codesigning and notarization + run: | + security create-keychain -p "$KEYCHAINPWD" "$KEYCHAINPATH" + security list-keychain -d user -s "$KEYCHAINPATH" + security set-keychain-settings "$KEYCHAINPATH" + security unlock-keychain -p "$KEYCHAINPWD" "$KEYCHAINPATH" + echo -n "$CERT_BASE64" | base64 --decode --output $CERTPATH + security import "$CERTPATH" -P "$CERT_PWD" -A -t cert -f pkcs12 -k "$KEYCHAINPATH" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:, -s -k "$KEYCHAINPATH" -D "$CERT_BASE64" -t private "$KEYCHAINPATH" + xcrun notarytool store-credentials "FRAMELIB-NOTARIZE" --apple-id $APPLE_ID --team-id $TEAM_ID --password $APP_SPECIFIC_PWD + - name: Mac notarization + shell: bash + # install fd /cd to package make temp folder with mxos / sign mxos / copy to folder / zip / notarize upload / deleete temps / staple + run: | + brew install fd + cd ${{ inputs.folder }} + mkdir -p Notarization + fd ${{ inputs.glob }} -E .git -I + fd ${{ inputs.glob }} -E .git -I -x codesign --force --timestamp --sign "Developer ID Application" {} + fd ${{ inputs.glob }} -E .git -I -x ditto {} Notarization/{/} + /usr/bin/ditto -c -k --keepParent Notarization Notarization.zip + xcrun notarytool submit Notarization.zip --keychain-profile "FRAMELIB-NOTARIZE" --wait + rm -rf Notarization Notarization.zip + fd ${{ inputs.glob }} -E .git -I -x xcrun stapler staple {} \ No newline at end of file diff --git a/.github/workflows/max-build.yml b/.github/workflows/max-build.yml new file mode 100644 index 000000000..6b24f9725 --- /dev/null +++ b/.github/workflows/max-build.yml @@ -0,0 +1,88 @@ +name: max-github +on: [ workflow_dispatch ] +jobs: + max-mac: + runs-on: macos-latest + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + with: + path: "framelib" + - name: Checkout max-sdk-base + uses: actions/checkout@v3 + with: + repository: 'Cycling74/max-sdk-base' + path: "max-sdk-base" + - name: Build mac max externals + run: xcodebuild -project 'framelib/framelib.xcodeproj' -scheme 'framelib Max (objects build)' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES + - name: Upload mac build + uses: actions/upload-artifact@v3 + with: + name: build-mac + path: framelib/Packaging/Max/FrameLib/externals + max-win: + runs-on: windows-2019 + steps: + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + - name: Checkout main repo + uses: actions/checkout@v3 + with: + path: "framelib" + - name: Checkout max-sdk-base + uses: actions/checkout@v3 + with: + repository: 'Cycling74/max-sdk-base' + path: "max-sdk-base" + - name: Build win max externals + run: msbuild "framelib/framelib.sln" /p:configuration="Release" /p:platform=x64 /t:framelib_objects_max /v:q /clp:ErrorsOnly /nologo /m + - name: Upload win build + uses: actions/upload-artifact@v3 + with: + name: build-win + path: framelib/Packaging/Max/FrameLib/externals + deploy-max: + runs-on: macos-latest + needs: [ max-mac, max-win ] + steps: + - name: Get current date / make build folder + id: date + run: | + echo "::set-output name=date::$(date +'%Y-%m-%d')" + mkdir ../build + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Build max documentation + run: xcodebuild -project 'framelib.xcodeproj' -scheme 'framelib Max Documentation' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES + - name: Download mac builds + uses: actions/download-artifact@v3 + with: + name: build-mac + path: Packaging/Max/FrameLib/externals + - name: Download win builds + uses: actions/download-artifact@v3 + with: + name: build-win + path: Packaging/Max/FrameLib/externals + - name: Sign and notarize + uses: ./.github/actions/mac-notarization + with: + glob: '-e mxo' + folder: Packaging/Max/FrameLib/externals + team_id: ${{ secrets.TEAM_ID }} + apple_id: ${{ secrets.APPLE_ID }} + app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} + cert_pwd: ${{ secrets.CERT_PWD }} + cert_base64: ${{ secrets.CERT_BASE64}} + - name: Zip package + run: /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/FrameLib.zip + - name: Make release + uses: "softprops/action-gh-release@v1" + with: + prerelease: true + fail_on_unmatched_files: true + files: ../build/FrameLib.zip + target_commitish: ${{ github.sha }} + tag_name: max-latest-${{ steps.date.outputs.date }} + body: This is an automated build of FrameLib for Max. + generate_release_notes: true diff --git a/.github/workflows/pd-build.yml b/.github/workflows/pd-build.yml new file mode 100644 index 000000000..32ca39ae3 --- /dev/null +++ b/.github/workflows/pd-build.yml @@ -0,0 +1,150 @@ +name: pd-github +on: [ workflow_dispatch ] +jobs: + pd-mac: + runs-on: macos-latest + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Build mac pd binary + run: | + cd FrameLib_PD_Objects/ + make + - name: Upload mac build + uses: actions/upload-artifact@v3 + with: + name: build-mac + path: build/*.d_fat + pd-linux-intel: + runs-on: ubuntu-latest + strategy: + matrix: + type: [ i386, x86_64 ] + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Install multi-libgcc + if: matrix.type != 'x86_64' + run: | + sudo apt-get update -y + sudo apt-get install -y gcc-multilib + sudo apt-get install -y g++-multilib + - name: Build linux intel pd binary + run: | + cd FrameLib_PD_Objects/ + make BUILD_TYPE=${{ matrix.type }} + - name: Upload linux intel build + uses: actions/upload-artifact@v3 + with: + name: ${{ format('build-linux-intel-{0}', matrix.type) }} + path: build/*.pd_linux + pd-linux-arm: + runs-on: ubuntu-latest + strategy: + matrix: + type: [ armv6, armv7, aarch64 ] + include: + - type: armv6 + cpu: arm1176 + base_image: raspios_lite:2022-01-28 + - type: armv7 + cpu: cortex-a7 + base_image: raspios_lite:2022-01-28 + - type: aarch64 + cpu: cortex-a8 + base_image: raspios_lite_arm64:2022-01-28 + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: ARM runner + uses: pguyot/arm-runner-action@v2 + with: + base_image: ${{ matrix.base_image }} + cpu: ${{ matrix.cpu }} + bind_mount_repository: true + image_additional_mb: 500 + commands: | + cd FrameLib_PD_Objects/ + make NAME_SUFFIX=${{ matrix.type }} + - name: Upload linux arm build + uses: actions/upload-artifact@v3 + with: + name: ${{ format('build-win-{0}', matrix.type) }} + path: build/*.pd_linux + pd-win: + runs-on: windows-2019 + strategy: + matrix: + type: [ i386 , x86_64 ] + steps: + - name: Set up MinGW + if: matrix.type == 'x86_64' + uses: egor-tensin/setup-mingw@v2 + with: + platform: x64 + - name: Set up MinGW 32bit + if: matrix.type == 'i386' + uses: egor-tensin/setup-mingw@v2 + with: + platform: x86 + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Build win pd binary + shell: bash + run: | + if [[ ${{ matrix.type }} == i386 ]]; then + PD_PACKAGE=https://msp.puredata.info/Software/pd-0.52-2-i386.msw.zip + MAKE_CMD=mingw32-make.exe + else + PD_PACKAGE=https://msp.puredata.info/Software/pd-0.52-2.msw.zip + MAKE_CMD=make + fi + cd FrameLib_PD_Objects/ + curl $PD_PACKAGE --output pdzipped.zip + unzip pdzipped.zip -d ../../ + $MAKE_CMD BUILD_TYPE=${{ matrix.type }} + - name: Upload win build + uses: actions/upload-artifact@v3 + with: + name: ${{ format('build-win-{0}', matrix.type) }} + path: build/*.dll + deploy-pd: + runs-on: macos-latest + needs: [ pd-mac, pd-linux-intel, pd-linux-arm, pd-win ] + steps: + - name: Prepare local actions + uses: actions/checkout@v1 + - name: Get current date / make build folder + id: date + run: | + echo "::set-output name=date::$(date +'%Y-%m-%d')" + mkdir ../build + - name: Download builds + uses: actions/download-artifact@v3 + with: + path: ../build/ + - name: Sign and notarize + if: ${{ false }} # disable for now + uses: ./.github/actions/mac-notarization + with: + glob: '-e d_fat' + folder: ../build/ + team_id: ${{ secrets.TEAM_ID }} + apple_id: ${{ secrets.APPLE_ID }} + app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} + cert_pwd: ${{ secrets.CERT_PWD }} + cert_base64: ${{ secrets.CERT_BASE64}} + - name: Zip files + run: | + cd ../build/ + find . -type f -execdir zip '{}.zip' '{}' \; + - name: Make release + uses: "softprops/action-gh-release@v1" + with: + prerelease: true + fail_on_unmatched_files: true + files: ../build/*/*.zip + target_commitish: ${{ github.sha }} + tag_name: pd-latest-${{ steps.date.outputs.date }} + body: This is an automated build of FrameLib for pd. + generate_release_notes: true From dd44f347f571a3844c3501c85e5210c4c5188450 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 13:37:52 +0000 Subject: [PATCH 190/222] Fix issue with generators reporting length parameter as integer (in practice it is a double) --- FrameLib_Objects/Generators/FrameLib_Gaussian.cpp | 2 +- FrameLib_Objects/Generators/FrameLib_MakeWindow.cpp | 2 +- FrameLib_Objects/Generators/FrameLib_Ramp.cpp | 2 +- FrameLib_Objects/Generators/FrameLib_Random.cpp | 2 +- FrameLib_Objects/Generators/FrameLib_Uniform.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FrameLib_Objects/Generators/FrameLib_Gaussian.cpp b/FrameLib_Objects/Generators/FrameLib_Gaussian.cpp index 6d07b7059..8ebb2912d 100644 --- a/FrameLib_Objects/Generators/FrameLib_Gaussian.cpp +++ b/FrameLib_Objects/Generators/FrameLib_Gaussian.cpp @@ -10,7 +10,7 @@ FrameLib_Gaussian::FrameLib_Gaussian(FrameLib_Context context, const FrameLib_Pa mParameters.addEnumItem(kRequestedLength, "requested"); mParameters.addEnumItem(kInLength, "input"); - mParameters.addInt(kLength, "length", 1, 1); + mParameters.addDouble(kLength, "length", 1, 1); mParameters.setMin(0); mParameters.addEnum(kUnits, "units", 2); diff --git a/FrameLib_Objects/Generators/FrameLib_MakeWindow.cpp b/FrameLib_Objects/Generators/FrameLib_MakeWindow.cpp index 428f74a05..a4fbd2378 100644 --- a/FrameLib_Objects/Generators/FrameLib_MakeWindow.cpp +++ b/FrameLib_Objects/Generators/FrameLib_MakeWindow.cpp @@ -11,7 +11,7 @@ FrameLib_MakeWindow::FrameLib_MakeWindow(FrameLib_Context context, const FrameLi mParameters.addEnumItem(kRequestedLength, "requested"); mParameters.addEnumItem(kInLength, "input"); - mParameters.addInt(kLength, "length", 512, 1); + mParameters.addDouble(kLength, "length", 512, 1); mParameters.setMin(0); mParameters.addEnum(kUnits, "units", 2); diff --git a/FrameLib_Objects/Generators/FrameLib_Ramp.cpp b/FrameLib_Objects/Generators/FrameLib_Ramp.cpp index eb22bdc45..0291ddcd4 100644 --- a/FrameLib_Objects/Generators/FrameLib_Ramp.cpp +++ b/FrameLib_Objects/Generators/FrameLib_Ramp.cpp @@ -10,7 +10,7 @@ FrameLib_Ramp::FrameLib_Ramp(FrameLib_Context context, const FrameLib_Parameters mParameters.addEnumItem(kRequestedLength, "requested"); mParameters.addEnumItem(kInLength, "input"); - mParameters.addInt(kLength, "length", 1, 1); + mParameters.addDouble(kLength, "length", 1, 1); mParameters.setMin(0); mParameters.addEnum(kUnits, "units", 2); diff --git a/FrameLib_Objects/Generators/FrameLib_Random.cpp b/FrameLib_Objects/Generators/FrameLib_Random.cpp index 7de4539e3..f1c618be6 100644 --- a/FrameLib_Objects/Generators/FrameLib_Random.cpp +++ b/FrameLib_Objects/Generators/FrameLib_Random.cpp @@ -10,7 +10,7 @@ FrameLib_Random::FrameLib_Random(FrameLib_Context context, const FrameLib_Parame mParameters.addEnumItem(kRequestedLength, "requested"); mParameters.addEnumItem(kInLength, "input"); - mParameters.addInt(kLength, "length", 1, 1); + mParameters.addDouble(kLength, "length", 1, 1); mParameters.setMin(0); mParameters.addEnum(kUnits, "units", 2); diff --git a/FrameLib_Objects/Generators/FrameLib_Uniform.cpp b/FrameLib_Objects/Generators/FrameLib_Uniform.cpp index 7b51f023a..9f9726e93 100644 --- a/FrameLib_Objects/Generators/FrameLib_Uniform.cpp +++ b/FrameLib_Objects/Generators/FrameLib_Uniform.cpp @@ -13,7 +13,7 @@ FrameLib_Uniform::FrameLib_Uniform(FrameLib_Context context, const FrameLib_Para mParameters.addEnumItem(kRequestedLength, "requested"); mParameters.addEnumItem(kInLength, "input"); - mParameters.addInt(kLength, "length", 1, 2); + mParameters.addDouble(kLength, "length", 1, 2); mParameters.setMin(0); mParameters.addEnum(kUnits, "units", 3); From a5c5584ad47c92083365d889cb8c0ae53ea41b73 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 13:56:22 +0000 Subject: [PATCH 191/222] Better documentation error reporting --- Documentation/Max Documentation/edit_xml.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/Max Documentation/edit_xml.py b/Documentation/Max Documentation/edit_xml.py index 5f0e396dd..5bc49c4a3 100644 --- a/Documentation/Max Documentation/edit_xml.py +++ b/Documentation/Max Documentation/edit_xml.py @@ -45,6 +45,8 @@ def find_object_category(obj_string: str) -> str: for obj in category_object_list: if obj == obj_string: return key + + raise RuntimeError(f"{obj_string} has no category entry") raw_xml_list = [x for x in docs.raw_xml_dir.rglob("fl.*.xml")] manual_xml_list = [x for x in docs.manual_xml_dir.rglob("fl.*.xml")] From aaed6c3a2af697f1d8390946e73c35fa43874528 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 13:58:04 +0000 Subject: [PATCH 192/222] Max documentation updates --- .../docs/refpages/framelib-ref/fl.gaussian~.maxref.xml | 4 ++-- .../refpages/framelib-ref/fl.makewindow~.maxref.xml | 4 ++-- .../docs/refpages/framelib-ref/fl.ramp~.maxref.xml | 4 ++-- .../docs/refpages/framelib-ref/fl.random~.maxref.xml | 4 ++-- .../docs/refpages/framelib-ref/fl.uniform~.maxref.xml | 4 ++-- Packaging/Max/FrameLib/help/fl.shift~.maxhelp | 10 +++++----- .../Max/FrameLib/interfaces/framelib-obj-jlookup.json | 10 +++++----- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.gaussian~.maxref.xml b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.gaussian~.maxref.xml index 272bef929..6afd8df63 100644 --- a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.gaussian~.maxref.xml +++ b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.gaussian~.maxref.xml @@ -13,7 +13,7 @@ Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter.

(default: 1, min: 0) @@ -61,7 +61,7 @@ This argument sets the mode parameter:

Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter diff --git a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.makewindow~.maxref.xml b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.makewindow~.maxref.xml index 3ef5543e2..964c5f52e 100644 --- a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.makewindow~.maxref.xml +++ b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.makewindow~.maxref.xml @@ -13,7 +13,7 @@ Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter.

(default: 512, min: 0) @@ -71,7 +71,7 @@ This argument sets the mode parameter:

Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter diff --git a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.ramp~.maxref.xml b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.ramp~.maxref.xml index 82af64754..e69ea0aa0 100644 --- a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.ramp~.maxref.xml +++ b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.ramp~.maxref.xml @@ -13,7 +13,7 @@ Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter.

(default: 1, min: 0) @@ -56,7 +56,7 @@ This argument sets the mode parameter:

Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter diff --git a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.random~.maxref.xml b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.random~.maxref.xml index 2235090e6..5d6fbe1f8 100644 --- a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.random~.maxref.xml +++ b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.random~.maxref.xml @@ -13,7 +13,7 @@ Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter.

(default: 1, min: 0) @@ -46,7 +46,7 @@ This argument sets the mode parameter:

Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter diff --git a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.uniform~.maxref.xml b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.uniform~.maxref.xml index 550270e1b..de1c3fa0a 100644 --- a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.uniform~.maxref.xml +++ b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.uniform~.maxref.xml @@ -18,7 +18,7 @@ Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter.

(default: 1, min: 0) @@ -59,7 +59,7 @@ This argument sets the mode parameter:

Controls how the output length is determined:

[0] - requested - the output length is set by the length parameter.[1] - input - the output length follows the length of the trigger input.

(default: requested) - + Sets the requested output length in the units specified by the units parameter diff --git a/Packaging/Max/FrameLib/help/fl.shift~.maxhelp b/Packaging/Max/FrameLib/help/fl.shift~.maxhelp index d76f038dc..aab192f69 100644 --- a/Packaging/Max/FrameLib/help/fl.shift~.maxhelp +++ b/Packaging/Max/FrameLib/help/fl.shift~.maxhelp @@ -186,7 +186,7 @@ "appversion": { "major": 8, "minor": 3, - "revision": 0, + "revision": 1, "architecture": "x64", "modernui": 1 }, @@ -257,7 +257,7 @@ "appversion": { "major": 8, "minor": 3, - "revision": 0, + "revision": 1, "architecture": "x64", "modernui": 1 }, @@ -508,7 +508,7 @@ "numinlets": 1, "numoutlets": 0, "patching_rect": [ - 336.5, + 312.75, 195.0, 138.0, 25.0 @@ -610,7 +610,7 @@ ], "parameter_enable": 0, "patching_rect": [ - 263.5, + 239.75, 195.0, 66.5, 23.0 @@ -899,7 +899,7 @@ ], "source": [ "obj-31", - 0 + 1 ] } }, diff --git a/Packaging/Max/FrameLib/interfaces/framelib-obj-jlookup.json b/Packaging/Max/FrameLib/interfaces/framelib-obj-jlookup.json index e304c4c8b..33c350ffd 100644 --- a/Packaging/Max/FrameLib/interfaces/framelib-obj-jlookup.json +++ b/Packaging/Max/FrameLib/interfaces/framelib-obj-jlookup.json @@ -850,7 +850,7 @@ "description": "Controls how the output length is determined:\n\nParameter Options:\n[0] - requested - the output length is set by the length parameter.\n[1] - input - the output length follows the length of the trigger input.\n\n(default: requested)" }, "3": { - "name": "/length [int]", + "name": "/length [double]", "description": "Sets the requested output length in the units specified by the units parameter.\n\n(default: 1, min: 0)" }, "4": { @@ -1072,7 +1072,7 @@ "description": "Controls how the output length is determined:\n\nParameter Options:\n[0] - requested - the output length is set by the length parameter.\n[1] - input - the output length follows the length of the trigger input.\n\n(default: requested)" }, "2": { - "name": "/length [int]", + "name": "/length [double]", "description": "Sets the requested output length in the units specified by the units parameter.\n\n(default: 1, min: 0)" }, "3": { @@ -1306,7 +1306,7 @@ "description": "Controls how the output length is determined:\n\nParameter Options:\n[0] - requested - the output length is set by the length parameter.\n[1] - input - the output length follows the length of the trigger input.\n\n(default: requested)" }, "2": { - "name": "/length [int]", + "name": "/length [double]", "description": "Sets the requested output length in the units specified by the units parameter.\n\n(default: 1, min: 0)" }, "3": { @@ -1374,7 +1374,7 @@ "description": "Controls how the output length is determined:\n\nParameter Options:\n[0] - requested - the output length is set by the length parameter.\n[1] - input - the output length follows the length of the trigger input.\n\n(default: requested)" }, "2": { - "name": "/length [int]", + "name": "/length [double]", "description": "Sets the requested output length in the units specified by the units parameter.\n\n(default: 512, min: 0)" }, "3": { @@ -1482,7 +1482,7 @@ "description": "Controls how the output length is determined:\n\nParameter Options:\n[0] - requested - the output length is set by the length parameter.\n[1] - input - the output length follows the length of the trigger input.\n\n(default: requested)" }, "2": { - "name": "/length [int]", + "name": "/length [double]", "description": "Sets the requested output length in the units specified by the units parameter.\n\n(default: 1, min: 0)" }, "3": { From 0652caa03b0b32e8de8790cc0146b8e3892c0ef4 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 18:54:54 +0000 Subject: [PATCH 193/222] Add unified build --- .github/workflows/distribution.yml | 211 +++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 .github/workflows/distribution.yml diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml new file mode 100644 index 000000000..cc9e23b6a --- /dev/null +++ b/.github/workflows/distribution.yml @@ -0,0 +1,211 @@ +name: distribution-github +on: [ workflow_dispatch ] +jobs: + max-mac: + runs-on: macos-latest + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + with: + path: "framelib" + - name: Checkout max-sdk-base + uses: actions/checkout@v3 + with: + repository: 'Cycling74/max-sdk-base' + path: "max-sdk-base" + - name: Build mac max externals + run: xcodebuild -project 'framelib/framelib.xcodeproj' -scheme 'framelib Max (objects build)' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES + - name: Upload mac build + uses: actions/upload-artifact@v3 + with: + name: build-mac + path: framelib/Packaging/Max/FrameLib/externals + max-win: + runs-on: windows-2019 + steps: + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + - name: Checkout main repo + uses: actions/checkout@v3 + with: + path: "framelib" + - name: Checkout max-sdk-base + uses: actions/checkout@v3 + with: + repository: 'Cycling74/max-sdk-base' + path: "max-sdk-base" + - name: Build win max externals + run: msbuild "framelib/framelib.sln" /p:configuration="Release" /p:platform=x64 /t:framelib_objects_max /v:q /clp:ErrorsOnly /nologo /m + - name: Upload win build + uses: actions/upload-artifact@v3 + with: + name: build-win + path: framelib/Packaging/Max/FrameLib/externals + pd-mac: + runs-on: macos-latest + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Build mac pd binary + run: | + cd FrameLib_PD_Objects/ + make + - name: Upload mac build + uses: actions/upload-artifact@v3 + with: + name: build-mac + path: build/*.d_fat + pd-linux-intel: + runs-on: ubuntu-latest + strategy: + matrix: + type: [ i386, x86_64 ] + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Install multi-libgcc + if: matrix.type != 'x86_64' + run: | + sudo apt-get update -y + sudo apt-get install -y gcc-multilib + sudo apt-get install -y g++-multilib + - name: Build linux intel pd binary + run: | + cd FrameLib_PD_Objects/ + make BUILD_TYPE=${{ matrix.type }} + - name: Upload linux intel build + uses: actions/upload-artifact@v3 + with: + name: ${{ format('build-linux-intel-{0}', matrix.type) }} + path: build/*.pd_linux + pd-linux-arm: + if: ${{ false }} + runs-on: ubuntu-latest + strategy: + matrix: + type: [ armv6, armv7, aarch64 ] + include: + - type: armv6 + cpu: arm1176 + base_image: raspios_lite:2022-01-28 + - type: armv7 + cpu: cortex-a7 + base_image: raspios_lite:2022-01-28 + - type: aarch64 + cpu: cortex-a8 + base_image: raspios_lite_arm64:2022-01-28 + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: ARM runner + uses: pguyot/arm-runner-action@v2 + with: + base_image: ${{ matrix.base_image }} + cpu: ${{ matrix.cpu }} + bind_mount_repository: true + image_additional_mb: 500 + commands: | + cd FrameLib_PD_Objects/ + make NAME_SUFFIX=${{ matrix.type }} + - name: Upload linux arm build + uses: actions/upload-artifact@v3 + with: + name: ${{ format('build-win-{0}', matrix.type) }} + path: build/*.pd_linux + pd-win: + runs-on: windows-2019 + strategy: + matrix: + type: [ i386 , x86_64 ] + steps: + - name: Set up MinGW + if: matrix.type == 'x86_64' + uses: egor-tensin/setup-mingw@v2 + with: + platform: x64 + - name: Set up MinGW 32bit + if: matrix.type == 'i386' + uses: egor-tensin/setup-mingw@v2 + with: + platform: x86 + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Build win pd binary + shell: bash + run: | + if [[ ${{ matrix.type }} == i386 ]]; then + PD_PACKAGE=https://msp.puredata.info/Software/pd-0.52-2-i386.msw.zip + MAKE_CMD=mingw32-make.exe + else + PD_PACKAGE=https://msp.puredata.info/Software/pd-0.52-2.msw.zip + MAKE_CMD=make + fi + cd FrameLib_PD_Objects/ + curl $PD_PACKAGE --output pdzipped.zip + unzip pdzipped.zip -d ../../ + $MAKE_CMD BUILD_TYPE=${{ matrix.type }} + - name: Upload win build + uses: actions/upload-artifact@v3 + with: + name: ${{ format('build-win-{0}', matrix.type) }} + path: build/*.dll + deploy: + runs-on: macos-latest + needs: [ max-mac, max-win, pd-mac, pd-linux-intel, pd-linux-arm, pd-win ] + steps: + - name: Checkout main repo + uses: actions/checkout@v3 + - name: Get current date / make build folder + id: date + run: | + echo "::set-output name=date::$(date +'%Y-%m-%d')" + mkdir ../build + - name: Build max documentation + run: xcodebuild -project 'framelib.xcodeproj' -scheme 'framelib Max Documentation' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES + - name: Download builds + uses: actions/download-artifact@v3 + with: + path: ../build/ + - name: Move max externals into place + run: | + mv ../build/build-mac/* Packaging/Max/FrameLib/externals + mv ../build/build-win/* Packaging/Max/FrameLib/externals + rm -d ../build/build-mac/ + rm -d ../build/build-win/ + - name: Sign and notarize max extnerals + uses: ./.github/actions/mac-notarization + with: + glob: '-e mxo' + folder: Packaging/Max/FrameLib/externals + team_id: ${{ secrets.TEAM_ID }} + apple_id: ${{ secrets.APPLE_ID }} + app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} + cert_pwd: ${{ secrets.CERT_PWD }} + cert_base64: ${{ secrets.CERT_BASE64}} + - name: Sign and notarize pd code + if: ${{ false }} # disable for now + uses: ./.github/actions/mac-notarization + with: + glob: '-e d_fat' + folder: ../build/ + team_id: ${{ secrets.TEAM_ID }} + apple_id: ${{ secrets.APPLE_ID }} + app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} + cert_pwd: ${{ secrets.CERT_PWD }} + cert_base64: ${{ secrets.CERT_BASE64}} + - name: Zip max package + run: /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/FrameLib_Max_Package.zip + - name: Zip pd files + run: | + cd ../build/ + find . -type f -execdir zip '{}.zip' '{}' \; + - name: Make release + uses: "softprops/action-gh-release@v1" + with: + prerelease: true + fail_on_unmatched_files: true + files: ../build/*/*.zip + target_commitish: ${{ github.sha }} + tag_name: pd-latest-${{ steps.date.outputs.date }} + body: This is an automated build of FrameLib for max/pd. + generate_release_notes: true From 84fe21b75f11ace3f41504b7079dcd3aa6568de8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 19:40:38 +0000 Subject: [PATCH 194/222] Rename release --- .github/workflows/distribution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index cc9e23b6a..0711fe833 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -206,6 +206,6 @@ jobs: fail_on_unmatched_files: true files: ../build/*/*.zip target_commitish: ${{ github.sha }} - tag_name: pd-latest-${{ steps.date.outputs.date }} + tag_name: framelib-latest-${{ github.ref_name }}- ${{ steps.date.outputs.date }} body: This is an automated build of FrameLib for max/pd. generate_release_notes: true From 8ff63e135ad7df51adf93d308bea35fb21e48c54 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 19:40:56 +0000 Subject: [PATCH 195/222] Don't require arm builds for now --- .github/workflows/distribution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 0711fe833..662a6126d 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -151,7 +151,7 @@ jobs: path: build/*.dll deploy: runs-on: macos-latest - needs: [ max-mac, max-win, pd-mac, pd-linux-intel, pd-linux-arm, pd-win ] + needs: [ max-mac, max-win, pd-mac, pd-linux-intel, pd-win ] steps: - name: Checkout main repo uses: actions/checkout@v3 From c13c2e98e2b9f9be2c81e925b473bea4e56dab9b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 21:12:34 +0000 Subject: [PATCH 196/222] Correct move of externals --- .github/workflows/distribution.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 662a6126d..e12710ff4 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -168,11 +168,12 @@ jobs: path: ../build/ - name: Move max externals into place run: | + mkdir Packaging/Max/FrameLib/externals mv ../build/build-mac/* Packaging/Max/FrameLib/externals mv ../build/build-win/* Packaging/Max/FrameLib/externals rm -d ../build/build-mac/ rm -d ../build/build-win/ - - name: Sign and notarize max extnerals + - name: Sign and notarize max externals uses: ./.github/actions/mac-notarization with: glob: '-e mxo' From 182f72671594efc25fe27c7415ff2d523f9e987d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 21:12:56 +0000 Subject: [PATCH 197/222] Delete previous actions --- .github/workflows/max-build.yml | 88 ------------------- .github/workflows/pd-build.yml | 150 -------------------------------- 2 files changed, 238 deletions(-) delete mode 100644 .github/workflows/max-build.yml delete mode 100644 .github/workflows/pd-build.yml diff --git a/.github/workflows/max-build.yml b/.github/workflows/max-build.yml deleted file mode 100644 index 6b24f9725..000000000 --- a/.github/workflows/max-build.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: max-github -on: [ workflow_dispatch ] -jobs: - max-mac: - runs-on: macos-latest - steps: - - name: Checkout main repo - uses: actions/checkout@v3 - with: - path: "framelib" - - name: Checkout max-sdk-base - uses: actions/checkout@v3 - with: - repository: 'Cycling74/max-sdk-base' - path: "max-sdk-base" - - name: Build mac max externals - run: xcodebuild -project 'framelib/framelib.xcodeproj' -scheme 'framelib Max (objects build)' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES - - name: Upload mac build - uses: actions/upload-artifact@v3 - with: - name: build-mac - path: framelib/Packaging/Max/FrameLib/externals - max-win: - runs-on: windows-2019 - steps: - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.1 - - name: Checkout main repo - uses: actions/checkout@v3 - with: - path: "framelib" - - name: Checkout max-sdk-base - uses: actions/checkout@v3 - with: - repository: 'Cycling74/max-sdk-base' - path: "max-sdk-base" - - name: Build win max externals - run: msbuild "framelib/framelib.sln" /p:configuration="Release" /p:platform=x64 /t:framelib_objects_max /v:q /clp:ErrorsOnly /nologo /m - - name: Upload win build - uses: actions/upload-artifact@v3 - with: - name: build-win - path: framelib/Packaging/Max/FrameLib/externals - deploy-max: - runs-on: macos-latest - needs: [ max-mac, max-win ] - steps: - - name: Get current date / make build folder - id: date - run: | - echo "::set-output name=date::$(date +'%Y-%m-%d')" - mkdir ../build - - name: Checkout main repo - uses: actions/checkout@v3 - - name: Build max documentation - run: xcodebuild -project 'framelib.xcodeproj' -scheme 'framelib Max Documentation' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES - - name: Download mac builds - uses: actions/download-artifact@v3 - with: - name: build-mac - path: Packaging/Max/FrameLib/externals - - name: Download win builds - uses: actions/download-artifact@v3 - with: - name: build-win - path: Packaging/Max/FrameLib/externals - - name: Sign and notarize - uses: ./.github/actions/mac-notarization - with: - glob: '-e mxo' - folder: Packaging/Max/FrameLib/externals - team_id: ${{ secrets.TEAM_ID }} - apple_id: ${{ secrets.APPLE_ID }} - app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} - cert_pwd: ${{ secrets.CERT_PWD }} - cert_base64: ${{ secrets.CERT_BASE64}} - - name: Zip package - run: /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/FrameLib.zip - - name: Make release - uses: "softprops/action-gh-release@v1" - with: - prerelease: true - fail_on_unmatched_files: true - files: ../build/FrameLib.zip - target_commitish: ${{ github.sha }} - tag_name: max-latest-${{ steps.date.outputs.date }} - body: This is an automated build of FrameLib for Max. - generate_release_notes: true diff --git a/.github/workflows/pd-build.yml b/.github/workflows/pd-build.yml deleted file mode 100644 index 32ca39ae3..000000000 --- a/.github/workflows/pd-build.yml +++ /dev/null @@ -1,150 +0,0 @@ -name: pd-github -on: [ workflow_dispatch ] -jobs: - pd-mac: - runs-on: macos-latest - steps: - - name: Checkout main repo - uses: actions/checkout@v3 - - name: Build mac pd binary - run: | - cd FrameLib_PD_Objects/ - make - - name: Upload mac build - uses: actions/upload-artifact@v3 - with: - name: build-mac - path: build/*.d_fat - pd-linux-intel: - runs-on: ubuntu-latest - strategy: - matrix: - type: [ i386, x86_64 ] - steps: - - name: Checkout main repo - uses: actions/checkout@v3 - - name: Install multi-libgcc - if: matrix.type != 'x86_64' - run: | - sudo apt-get update -y - sudo apt-get install -y gcc-multilib - sudo apt-get install -y g++-multilib - - name: Build linux intel pd binary - run: | - cd FrameLib_PD_Objects/ - make BUILD_TYPE=${{ matrix.type }} - - name: Upload linux intel build - uses: actions/upload-artifact@v3 - with: - name: ${{ format('build-linux-intel-{0}', matrix.type) }} - path: build/*.pd_linux - pd-linux-arm: - runs-on: ubuntu-latest - strategy: - matrix: - type: [ armv6, armv7, aarch64 ] - include: - - type: armv6 - cpu: arm1176 - base_image: raspios_lite:2022-01-28 - - type: armv7 - cpu: cortex-a7 - base_image: raspios_lite:2022-01-28 - - type: aarch64 - cpu: cortex-a8 - base_image: raspios_lite_arm64:2022-01-28 - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: ARM runner - uses: pguyot/arm-runner-action@v2 - with: - base_image: ${{ matrix.base_image }} - cpu: ${{ matrix.cpu }} - bind_mount_repository: true - image_additional_mb: 500 - commands: | - cd FrameLib_PD_Objects/ - make NAME_SUFFIX=${{ matrix.type }} - - name: Upload linux arm build - uses: actions/upload-artifact@v3 - with: - name: ${{ format('build-win-{0}', matrix.type) }} - path: build/*.pd_linux - pd-win: - runs-on: windows-2019 - strategy: - matrix: - type: [ i386 , x86_64 ] - steps: - - name: Set up MinGW - if: matrix.type == 'x86_64' - uses: egor-tensin/setup-mingw@v2 - with: - platform: x64 - - name: Set up MinGW 32bit - if: matrix.type == 'i386' - uses: egor-tensin/setup-mingw@v2 - with: - platform: x86 - - name: Checkout main repo - uses: actions/checkout@v3 - - name: Build win pd binary - shell: bash - run: | - if [[ ${{ matrix.type }} == i386 ]]; then - PD_PACKAGE=https://msp.puredata.info/Software/pd-0.52-2-i386.msw.zip - MAKE_CMD=mingw32-make.exe - else - PD_PACKAGE=https://msp.puredata.info/Software/pd-0.52-2.msw.zip - MAKE_CMD=make - fi - cd FrameLib_PD_Objects/ - curl $PD_PACKAGE --output pdzipped.zip - unzip pdzipped.zip -d ../../ - $MAKE_CMD BUILD_TYPE=${{ matrix.type }} - - name: Upload win build - uses: actions/upload-artifact@v3 - with: - name: ${{ format('build-win-{0}', matrix.type) }} - path: build/*.dll - deploy-pd: - runs-on: macos-latest - needs: [ pd-mac, pd-linux-intel, pd-linux-arm, pd-win ] - steps: - - name: Prepare local actions - uses: actions/checkout@v1 - - name: Get current date / make build folder - id: date - run: | - echo "::set-output name=date::$(date +'%Y-%m-%d')" - mkdir ../build - - name: Download builds - uses: actions/download-artifact@v3 - with: - path: ../build/ - - name: Sign and notarize - if: ${{ false }} # disable for now - uses: ./.github/actions/mac-notarization - with: - glob: '-e d_fat' - folder: ../build/ - team_id: ${{ secrets.TEAM_ID }} - apple_id: ${{ secrets.APPLE_ID }} - app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} - cert_pwd: ${{ secrets.CERT_PWD }} - cert_base64: ${{ secrets.CERT_BASE64}} - - name: Zip files - run: | - cd ../build/ - find . -type f -execdir zip '{}.zip' '{}' \; - - name: Make release - uses: "softprops/action-gh-release@v1" - with: - prerelease: true - fail_on_unmatched_files: true - files: ../build/*/*.zip - target_commitish: ${{ github.sha }} - tag_name: pd-latest-${{ steps.date.outputs.date }} - body: This is an automated build of FrameLib for pd. - generate_release_notes: true From 3ee455e8400e37fdb73ee43817db31493e78e011 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 21:15:44 +0000 Subject: [PATCH 198/222] Whitespace --- .github/workflows/distribution.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index e12710ff4..0ba5e79aa 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -167,12 +167,12 @@ jobs: with: path: ../build/ - name: Move max externals into place - run: | + run: | mkdir Packaging/Max/FrameLib/externals mv ../build/build-mac/* Packaging/Max/FrameLib/externals mv ../build/build-win/* Packaging/Max/FrameLib/externals rm -d ../build/build-mac/ - rm -d ../build/build-win/ + rm -d ../build/build-win/ - name: Sign and notarize max externals uses: ./.github/actions/mac-notarization with: From 93857db3c85b7b1f0b00d03a24de6f96e5661703 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 21:48:49 +0000 Subject: [PATCH 199/222] Fix tag name --- .github/workflows/distribution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 0ba5e79aa..491956eba 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -207,6 +207,6 @@ jobs: fail_on_unmatched_files: true files: ../build/*/*.zip target_commitish: ${{ github.sha }} - tag_name: framelib-latest-${{ github.ref_name }}- ${{ steps.date.outputs.date }} + tag_name: framelib-latest-${{ github.ref_name }}-${{ steps.date.outputs.date }} body: This is an automated build of FrameLib for max/pd. generate_release_notes: true From b75beb1f5b7e5a93aeefb84da849e9cdcd291541 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 21:48:58 +0000 Subject: [PATCH 200/222] Whitespace --- .github/workflows/distribution.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 491956eba..328e6ce9b 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -167,12 +167,12 @@ jobs: with: path: ../build/ - name: Move max externals into place - run: | + run: | mkdir Packaging/Max/FrameLib/externals mv ../build/build-mac/* Packaging/Max/FrameLib/externals mv ../build/build-win/* Packaging/Max/FrameLib/externals rm -d ../build/build-mac/ - rm -d ../build/build-win/ + rm -d ../build/build-win/ - name: Sign and notarize max externals uses: ./.github/actions/mac-notarization with: From bb47e30a3d2a918835e15e7d6917345474a477ad Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 2 Nov 2022 21:57:02 +0000 Subject: [PATCH 201/222] Add pd ARM builds back --- .github/workflows/distribution.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 328e6ce9b..5c58da361 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -79,7 +79,6 @@ jobs: name: ${{ format('build-linux-intel-{0}', matrix.type) }} path: build/*.pd_linux pd-linux-arm: - if: ${{ false }} runs-on: ubuntu-latest strategy: matrix: @@ -151,7 +150,7 @@ jobs: path: build/*.dll deploy: runs-on: macos-latest - needs: [ max-mac, max-win, pd-mac, pd-linux-intel, pd-win ] + needs: [ max-mac, max-win, pd-mac, pd-linux-intel, pd-linux-arm, pd-win ] steps: - name: Checkout main repo uses: actions/checkout@v3 From 4460371e7ad4e3432e51e4d8e2e3f60dd25d5e12 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 3 Nov 2022 08:28:53 +0000 Subject: [PATCH 202/222] Change path for max package to ensure upload --- .github/workflows/distribution.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 5c58da361..e83af6fc0 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -194,7 +194,9 @@ jobs: cert_pwd: ${{ secrets.CERT_PWD }} cert_base64: ${{ secrets.CERT_BASE64}} - name: Zip max package - run: /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/FrameLib_Max_Package.zip + run: | + mkdir ../build/Max_Package + /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/Max_Package/FrameLib_Max_Package.zip - name: Zip pd files run: | cd ../build/ From 869b1c530e9ac44705db08fc75f5945d931ca95c Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 3 Nov 2022 09:06:19 +0000 Subject: [PATCH 203/222] Reorder to avoid additional zip --- .github/workflows/distribution.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index e83af6fc0..0e1d0bf27 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -193,14 +193,14 @@ jobs: app_specific_pwd: ${{ secrets.APP_SPECIFIC_PWD }} cert_pwd: ${{ secrets.CERT_PWD }} cert_base64: ${{ secrets.CERT_BASE64}} - - name: Zip max package - run: | - mkdir ../build/Max_Package - /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/Max_Package/FrameLib_Max_Package.zip - name: Zip pd files run: | cd ../build/ find . -type f -execdir zip '{}.zip' '{}' \; + - name: Zip max package + run: | + mkdir ../build/Max_Package + /usr/bin/ditto -c -k --norsrc --keepParent Packaging/Max/FrameLib/ ../build/Max_Package/FrameLib_Max_Package.zip - name: Make release uses: "softprops/action-gh-release@v1" with: From fb70cc17da6ee005838abf355ea3fbc453425ca8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 3 Nov 2022 18:13:52 +0000 Subject: [PATCH 204/222] Use new github outputs approach --- .github/workflows/distribution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 0e1d0bf27..28da0e1ac 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -157,7 +157,7 @@ jobs: - name: Get current date / make build folder id: date run: | - echo "::set-output name=date::$(date +'%Y-%m-%d')" + echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT mkdir ../build - name: Build max documentation run: xcodebuild -project 'framelib.xcodeproj' -scheme 'framelib Max Documentation' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES From d4df6baa6dbfb9cd91de8bfc47259014cb5c5108 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 16 Jan 2023 09:28:10 +0000 Subject: [PATCH 205/222] Add static configuration for the libraries and tests --- .../Visual_Studio/02_Common/framelib.vcxproj | 66 ++ .../02_Common/framelib_objects.vcxproj | 71 +- .../04 Tests/ExportTests/ExportTests.vcxproj | 78 ++ framelib.sln | 678 ++++++++++++++++++ 4 files changed, 892 insertions(+), 1 deletion(-) diff --git a/Projects/Visual_Studio/02_Common/framelib.vcxproj b/Projects/Visual_Studio/02_Common/framelib.vcxproj index 06a249e1b..04ab83341 100644 --- a/Projects/Visual_Studio/02_Common/framelib.vcxproj +++ b/Projects/Visual_Studio/02_Common/framelib.vcxproj @@ -17,6 +17,14 @@ Release x64 + + Static + Win32 + + + Static + x64 + @@ -68,6 +76,12 @@ v142 true + + StaticLibrary + false + v142 + true + StaticLibrary true @@ -79,6 +93,12 @@ v142 true + + StaticLibrary + false + v142 + true + @@ -94,6 +114,11 @@ + + + + + @@ -104,6 +129,11 @@ + + + + + true @@ -114,9 +144,15 @@ false + + false + false + + false + _LIB;%(PreprocessorDefinitions) @@ -152,6 +188,21 @@ true + + + _LIB;%(PreprocessorDefinitions) + + + true + MultiThreaded + + + Windows + true + true + true + + _LIB;%(PreprocessorDefinitions) @@ -165,6 +216,21 @@ true + + + _LIB;%(PreprocessorDefinitions) + + + true + MultiThreaded + + + Windows + true + true + true + + diff --git a/Projects/Visual_Studio/02_Common/framelib_objects.vcxproj b/Projects/Visual_Studio/02_Common/framelib_objects.vcxproj index 4810bb45e..898a0b46b 100644 --- a/Projects/Visual_Studio/02_Common/framelib_objects.vcxproj +++ b/Projects/Visual_Studio/02_Common/framelib_objects.vcxproj @@ -17,6 +17,14 @@ Release x64 + + Static + Win32 + + + Static + x64 + @@ -232,6 +240,13 @@ true Unicode + + StaticLibrary + false + v142 + true + Unicode + StaticLibrary true @@ -243,6 +258,12 @@ v142 true + + StaticLibrary + false + v142 + true + @@ -260,6 +281,12 @@ + + + + + + @@ -272,6 +299,12 @@ + + + + + + true @@ -282,9 +315,15 @@ false + + false + false + + false + _LIB;%(PreprocessorDefinitions) @@ -320,6 +359,21 @@ true + + + _LIB;%(PreprocessorDefinitions) + + + true + MultiThreaded + + + Windows + true + true + true + + _LIB;%(PreprocessorDefinitions) @@ -333,7 +387,22 @@ true + + + _LIB;%(PreprocessorDefinitions) + + + true + MultiThreaded + + + Windows + true + true + true + + - + \ No newline at end of file diff --git a/Projects/Visual_Studio/04 Tests/ExportTests/ExportTests.vcxproj b/Projects/Visual_Studio/04 Tests/ExportTests/ExportTests.vcxproj index 5abf8db71..645a42614 100644 --- a/Projects/Visual_Studio/04 Tests/ExportTests/ExportTests.vcxproj +++ b/Projects/Visual_Studio/04 Tests/ExportTests/ExportTests.vcxproj @@ -17,6 +17,14 @@ Release x64 + + Static + Win32 + + + Static + x64 + @@ -45,6 +53,13 @@ true Unicode + + Application + false + v142 + true + Unicode + Application true @@ -58,6 +73,13 @@ true Unicode + + Application + false + v142 + true + Unicode + @@ -75,6 +97,12 @@ + + + + + + @@ -87,6 +115,12 @@ + + + + + + true @@ -94,12 +128,18 @@ false + + false + true false + + false + Level3 @@ -132,6 +172,25 @@ $(SolutionDir)build\$(configuration)_$(platform);%(AdditionalLibraryDirectories) + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + framelib.lib;framelib_objects.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)build\$(configuration)_$(platform);%(AdditionalLibraryDirectories) + + Level3 @@ -164,6 +223,25 @@ $(SolutionDir)build\$(configuration)_$(platform);%(AdditionalLibraryDirectories) + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + framelib.lib;framelib_objects.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)build\$(configuration)_$(platform);%(AdditionalLibraryDirectories) + + diff --git a/framelib.sln b/framelib.sln index c7a0c8fc7..1fe729f24 100644 --- a/framelib.sln +++ b/framelib.sln @@ -1184,6 +1184,8 @@ Global Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 + Static|x64 = Static|x64 + Static|x86 = Static|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Debug|x64.ActiveCfg = Debug|x64 @@ -1194,6 +1196,10 @@ Global {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Release|x64.Build.0 = Release|x64 {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Release|x86.ActiveCfg = Release|Win32 {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Release|x86.Build.0 = Release|Win32 + {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Static|x64.ActiveCfg = Static|x64 + {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Static|x64.Build.0 = Static|x64 + {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Static|x86.ActiveCfg = Static|Win32 + {15B7B576-7125-46F8-AFF1-976F8E4685A7}.Static|x86.Build.0 = Static|Win32 {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Debug|x64.ActiveCfg = Debug|x64 {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Debug|x64.Build.0 = Debug|x64 {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Debug|x86.ActiveCfg = Debug|Win32 @@ -1202,1002 +1208,1670 @@ Global {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Release|x64.Build.0 = Release|x64 {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Release|x86.ActiveCfg = Release|Win32 {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Release|x86.Build.0 = Release|Win32 + {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Static|x64.ActiveCfg = Static|x64 + {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Static|x64.Build.0 = Static|x64 + {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Static|x86.ActiveCfg = Static|Win32 + {A4E2A0AE-C945-4C8A-BAD6-B40660578BC3}.Static|x86.Build.0 = Static|Win32 {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Debug|x64.ActiveCfg = Debug|x64 {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Debug|x64.Build.0 = Debug|x64 {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Debug|x86.ActiveCfg = Debug|x64 {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Release|x64.ActiveCfg = Release|x64 {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Release|x64.Build.0 = Release|x64 {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Release|x86.ActiveCfg = Release|x64 + {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Static|x64.ActiveCfg = Release|x64 + {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Static|x64.Build.0 = Release|x64 + {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Static|x86.ActiveCfg = Release|x64 + {818BB3B2-7651-4EBD-A476-E0C2E0AEC1DD}.Static|x86.Build.0 = Release|x64 {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Debug|x64.ActiveCfg = Debug|x64 {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Debug|x64.Build.0 = Debug|x64 {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Debug|x86.ActiveCfg = Debug|x64 {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Release|x64.ActiveCfg = Release|x64 {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Release|x64.Build.0 = Release|x64 {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Release|x86.ActiveCfg = Release|x64 + {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Static|x64.ActiveCfg = Release|x64 + {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Static|x64.Build.0 = Release|x64 + {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Static|x86.ActiveCfg = Release|x64 + {77A6F8A3-AECD-4EE3-A85B-489F6B9A64D7}.Static|x86.Build.0 = Release|x64 {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Debug|x64.ActiveCfg = Debug|x64 {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Debug|x64.Build.0 = Debug|x64 {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Debug|x86.ActiveCfg = Debug|x64 {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Release|x64.ActiveCfg = Release|x64 {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Release|x64.Build.0 = Release|x64 {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Release|x86.ActiveCfg = Release|x64 + {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Static|x64.ActiveCfg = Release|x64 + {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Static|x64.Build.0 = Release|x64 + {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Static|x86.ActiveCfg = Release|x64 + {F73714A7-0858-4966-8870-8A7FC17F9ACA}.Static|x86.Build.0 = Release|x64 {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Debug|x64.ActiveCfg = Debug|x64 {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Debug|x64.Build.0 = Debug|x64 {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Debug|x86.ActiveCfg = Debug|x64 {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Release|x64.ActiveCfg = Release|x64 {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Release|x64.Build.0 = Release|x64 {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Release|x86.ActiveCfg = Release|x64 + {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Static|x64.ActiveCfg = Release|x64 + {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Static|x64.Build.0 = Release|x64 + {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Static|x86.ActiveCfg = Release|x64 + {A2D6F379-B98E-4F86-99BF-A5D68C1714AF}.Static|x86.Build.0 = Release|x64 {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Debug|x64.ActiveCfg = Debug|x64 {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Debug|x64.Build.0 = Debug|x64 {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Debug|x86.ActiveCfg = Debug|x64 {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Release|x64.ActiveCfg = Release|x64 {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Release|x64.Build.0 = Release|x64 {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Release|x86.ActiveCfg = Release|x64 + {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Static|x64.ActiveCfg = Release|x64 + {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Static|x64.Build.0 = Release|x64 + {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Static|x86.ActiveCfg = Release|x64 + {27E1A6EC-C1B7-4632-9C0A-B3B510FC19DD}.Static|x86.Build.0 = Release|x64 {4D54C280-963D-4428-ABA8-0F0A70982319}.Debug|x64.ActiveCfg = Debug|x64 {4D54C280-963D-4428-ABA8-0F0A70982319}.Debug|x64.Build.0 = Debug|x64 {4D54C280-963D-4428-ABA8-0F0A70982319}.Debug|x86.ActiveCfg = Debug|x64 {4D54C280-963D-4428-ABA8-0F0A70982319}.Release|x64.ActiveCfg = Release|x64 {4D54C280-963D-4428-ABA8-0F0A70982319}.Release|x64.Build.0 = Release|x64 {4D54C280-963D-4428-ABA8-0F0A70982319}.Release|x86.ActiveCfg = Release|x64 + {4D54C280-963D-4428-ABA8-0F0A70982319}.Static|x64.ActiveCfg = Release|x64 + {4D54C280-963D-4428-ABA8-0F0A70982319}.Static|x64.Build.0 = Release|x64 + {4D54C280-963D-4428-ABA8-0F0A70982319}.Static|x86.ActiveCfg = Release|x64 + {4D54C280-963D-4428-ABA8-0F0A70982319}.Static|x86.Build.0 = Release|x64 {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Debug|x64.ActiveCfg = Debug|x64 {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Debug|x64.Build.0 = Debug|x64 {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Debug|x86.ActiveCfg = Debug|x64 {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Release|x64.ActiveCfg = Release|x64 {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Release|x64.Build.0 = Release|x64 {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Release|x86.ActiveCfg = Release|x64 + {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Static|x64.ActiveCfg = Release|x64 + {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Static|x64.Build.0 = Release|x64 + {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Static|x86.ActiveCfg = Release|x64 + {93AA91B2-5A8F-414D-856D-1AB4C557DC1F}.Static|x86.Build.0 = Release|x64 {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Debug|x64.ActiveCfg = Debug|x64 {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Debug|x64.Build.0 = Debug|x64 {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Debug|x86.ActiveCfg = Debug|x64 {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Release|x64.ActiveCfg = Release|x64 {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Release|x64.Build.0 = Release|x64 {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Release|x86.ActiveCfg = Release|x64 + {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Static|x64.ActiveCfg = Release|x64 + {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Static|x64.Build.0 = Release|x64 + {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Static|x86.ActiveCfg = Release|x64 + {5A89D5F5-66CB-49BD-BF5E-294B8FE81AE4}.Static|x86.Build.0 = Release|x64 {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Debug|x64.ActiveCfg = Debug|x64 {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Debug|x64.Build.0 = Debug|x64 {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Debug|x86.ActiveCfg = Debug|x64 {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Release|x64.ActiveCfg = Release|x64 {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Release|x64.Build.0 = Release|x64 {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Release|x86.ActiveCfg = Release|x64 + {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Static|x64.ActiveCfg = Release|x64 + {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Static|x64.Build.0 = Release|x64 + {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Static|x86.ActiveCfg = Release|x64 + {F252BDBF-E0EA-49D6-9A85-147FBA604FDF}.Static|x86.Build.0 = Release|x64 {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Debug|x64.ActiveCfg = Debug|x64 {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Debug|x64.Build.0 = Debug|x64 {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Debug|x86.ActiveCfg = Debug|x64 {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Release|x64.ActiveCfg = Release|x64 {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Release|x64.Build.0 = Release|x64 {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Release|x86.ActiveCfg = Release|x64 + {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Static|x64.ActiveCfg = Release|x64 + {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Static|x64.Build.0 = Release|x64 + {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Static|x86.ActiveCfg = Release|x64 + {7AF67CC5-DD9F-4258-9F07-D6C838578E8E}.Static|x86.Build.0 = Release|x64 {9725EED1-4827-4801-8B89-1B43DBD8543F}.Debug|x64.ActiveCfg = Debug|x64 {9725EED1-4827-4801-8B89-1B43DBD8543F}.Debug|x64.Build.0 = Debug|x64 {9725EED1-4827-4801-8B89-1B43DBD8543F}.Debug|x86.ActiveCfg = Debug|x64 {9725EED1-4827-4801-8B89-1B43DBD8543F}.Release|x64.ActiveCfg = Release|x64 {9725EED1-4827-4801-8B89-1B43DBD8543F}.Release|x64.Build.0 = Release|x64 {9725EED1-4827-4801-8B89-1B43DBD8543F}.Release|x86.ActiveCfg = Release|x64 + {9725EED1-4827-4801-8B89-1B43DBD8543F}.Static|x64.ActiveCfg = Release|x64 + {9725EED1-4827-4801-8B89-1B43DBD8543F}.Static|x64.Build.0 = Release|x64 + {9725EED1-4827-4801-8B89-1B43DBD8543F}.Static|x86.ActiveCfg = Release|x64 + {9725EED1-4827-4801-8B89-1B43DBD8543F}.Static|x86.Build.0 = Release|x64 {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Debug|x64.ActiveCfg = Debug|x64 {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Debug|x64.Build.0 = Debug|x64 {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Debug|x86.ActiveCfg = Debug|x64 {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Release|x64.ActiveCfg = Release|x64 {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Release|x64.Build.0 = Release|x64 {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Release|x86.ActiveCfg = Release|x64 + {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Static|x64.ActiveCfg = Release|x64 + {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Static|x64.Build.0 = Release|x64 + {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Static|x86.ActiveCfg = Release|x64 + {42C266C6-0950-4669-B04F-FB4C9A864D0D}.Static|x86.Build.0 = Release|x64 {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Debug|x64.ActiveCfg = Debug|x64 {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Debug|x64.Build.0 = Debug|x64 {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Debug|x86.ActiveCfg = Debug|x64 {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Release|x64.ActiveCfg = Release|x64 {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Release|x64.Build.0 = Release|x64 {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Release|x86.ActiveCfg = Release|x64 + {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Static|x64.ActiveCfg = Release|x64 + {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Static|x64.Build.0 = Release|x64 + {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Static|x86.ActiveCfg = Release|x64 + {B6B529AD-26F2-4FC2-BBD6-9BF3BFBD444F}.Static|x86.Build.0 = Release|x64 {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Debug|x64.ActiveCfg = Debug|x64 {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Debug|x64.Build.0 = Debug|x64 {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Debug|x86.ActiveCfg = Debug|x64 {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Release|x64.ActiveCfg = Release|x64 {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Release|x64.Build.0 = Release|x64 {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Release|x86.ActiveCfg = Release|x64 + {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Static|x64.ActiveCfg = Release|x64 + {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Static|x64.Build.0 = Release|x64 + {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Static|x86.ActiveCfg = Release|x64 + {CA3C5EDD-9576-49EC-8456-2774011DB13E}.Static|x86.Build.0 = Release|x64 {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Debug|x64.ActiveCfg = Debug|x64 {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Debug|x64.Build.0 = Debug|x64 {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Debug|x86.ActiveCfg = Debug|x64 {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Release|x64.ActiveCfg = Release|x64 {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Release|x64.Build.0 = Release|x64 {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Release|x86.ActiveCfg = Release|x64 + {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Static|x64.ActiveCfg = Release|x64 + {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Static|x64.Build.0 = Release|x64 + {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Static|x86.ActiveCfg = Release|x64 + {DA37A20D-89ED-4F31-AD01-E75EE04F7282}.Static|x86.Build.0 = Release|x64 {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Debug|x64.ActiveCfg = Debug|x64 {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Debug|x64.Build.0 = Debug|x64 {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Debug|x86.ActiveCfg = Debug|x64 {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Release|x64.ActiveCfg = Release|x64 {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Release|x64.Build.0 = Release|x64 {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Release|x86.ActiveCfg = Release|x64 + {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Static|x64.ActiveCfg = Release|x64 + {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Static|x64.Build.0 = Release|x64 + {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Static|x86.ActiveCfg = Release|x64 + {3A00E1E9-AD6F-4F66-8C47-2EE193F7A575}.Static|x86.Build.0 = Release|x64 {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Debug|x64.ActiveCfg = Debug|x64 {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Debug|x64.Build.0 = Debug|x64 {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Debug|x86.ActiveCfg = Debug|x64 {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Release|x64.ActiveCfg = Release|x64 {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Release|x64.Build.0 = Release|x64 {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Release|x86.ActiveCfg = Release|x64 + {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Static|x64.ActiveCfg = Release|x64 + {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Static|x64.Build.0 = Release|x64 + {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Static|x86.ActiveCfg = Release|x64 + {3A2DFAA8-6E43-437A-A75D-DF6B98A5ED28}.Static|x86.Build.0 = Release|x64 {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Debug|x64.ActiveCfg = Debug|x64 {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Debug|x64.Build.0 = Debug|x64 {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Debug|x86.ActiveCfg = Debug|x64 {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Release|x64.ActiveCfg = Release|x64 {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Release|x64.Build.0 = Release|x64 {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Release|x86.ActiveCfg = Release|x64 + {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Static|x64.ActiveCfg = Release|x64 + {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Static|x64.Build.0 = Release|x64 + {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Static|x86.ActiveCfg = Release|x64 + {C36560AB-268A-4FB0-B6C5-BC0F6DF9E0FD}.Static|x86.Build.0 = Release|x64 {04D59CEE-109D-48FE-9228-E71B95224D0D}.Debug|x64.ActiveCfg = Debug|x64 {04D59CEE-109D-48FE-9228-E71B95224D0D}.Debug|x64.Build.0 = Debug|x64 {04D59CEE-109D-48FE-9228-E71B95224D0D}.Debug|x86.ActiveCfg = Debug|x64 {04D59CEE-109D-48FE-9228-E71B95224D0D}.Release|x64.ActiveCfg = Release|x64 {04D59CEE-109D-48FE-9228-E71B95224D0D}.Release|x64.Build.0 = Release|x64 {04D59CEE-109D-48FE-9228-E71B95224D0D}.Release|x86.ActiveCfg = Release|x64 + {04D59CEE-109D-48FE-9228-E71B95224D0D}.Static|x64.ActiveCfg = Release|x64 + {04D59CEE-109D-48FE-9228-E71B95224D0D}.Static|x64.Build.0 = Release|x64 + {04D59CEE-109D-48FE-9228-E71B95224D0D}.Static|x86.ActiveCfg = Release|x64 + {04D59CEE-109D-48FE-9228-E71B95224D0D}.Static|x86.Build.0 = Release|x64 {6FC6559E-3F04-4919-8004-2E1078E5594F}.Debug|x64.ActiveCfg = Debug|x64 {6FC6559E-3F04-4919-8004-2E1078E5594F}.Debug|x64.Build.0 = Debug|x64 {6FC6559E-3F04-4919-8004-2E1078E5594F}.Debug|x86.ActiveCfg = Debug|x64 {6FC6559E-3F04-4919-8004-2E1078E5594F}.Release|x64.ActiveCfg = Release|x64 {6FC6559E-3F04-4919-8004-2E1078E5594F}.Release|x64.Build.0 = Release|x64 {6FC6559E-3F04-4919-8004-2E1078E5594F}.Release|x86.ActiveCfg = Release|x64 + {6FC6559E-3F04-4919-8004-2E1078E5594F}.Static|x64.ActiveCfg = Release|x64 + {6FC6559E-3F04-4919-8004-2E1078E5594F}.Static|x64.Build.0 = Release|x64 + {6FC6559E-3F04-4919-8004-2E1078E5594F}.Static|x86.ActiveCfg = Release|x64 + {6FC6559E-3F04-4919-8004-2E1078E5594F}.Static|x86.Build.0 = Release|x64 {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Debug|x64.ActiveCfg = Debug|x64 {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Debug|x64.Build.0 = Debug|x64 {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Debug|x86.ActiveCfg = Debug|x64 {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Release|x64.ActiveCfg = Release|x64 {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Release|x64.Build.0 = Release|x64 {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Release|x86.ActiveCfg = Release|x64 + {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Static|x64.ActiveCfg = Release|x64 + {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Static|x64.Build.0 = Release|x64 + {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Static|x86.ActiveCfg = Release|x64 + {9AEC4BB2-4C14-4A95-BF0F-9ED4141FD644}.Static|x86.Build.0 = Release|x64 {F991E402-7708-4F41-83AA-ED5AE1587583}.Debug|x64.ActiveCfg = Debug|x64 {F991E402-7708-4F41-83AA-ED5AE1587583}.Debug|x64.Build.0 = Debug|x64 {F991E402-7708-4F41-83AA-ED5AE1587583}.Debug|x86.ActiveCfg = Debug|x64 {F991E402-7708-4F41-83AA-ED5AE1587583}.Release|x64.ActiveCfg = Release|x64 {F991E402-7708-4F41-83AA-ED5AE1587583}.Release|x64.Build.0 = Release|x64 {F991E402-7708-4F41-83AA-ED5AE1587583}.Release|x86.ActiveCfg = Release|x64 + {F991E402-7708-4F41-83AA-ED5AE1587583}.Static|x64.ActiveCfg = Release|x64 + {F991E402-7708-4F41-83AA-ED5AE1587583}.Static|x64.Build.0 = Release|x64 + {F991E402-7708-4F41-83AA-ED5AE1587583}.Static|x86.ActiveCfg = Release|x64 + {F991E402-7708-4F41-83AA-ED5AE1587583}.Static|x86.Build.0 = Release|x64 {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Debug|x64.ActiveCfg = Debug|x64 {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Debug|x64.Build.0 = Debug|x64 {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Debug|x86.ActiveCfg = Debug|x64 {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Release|x64.ActiveCfg = Release|x64 {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Release|x64.Build.0 = Release|x64 {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Release|x86.ActiveCfg = Release|x64 + {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Static|x64.ActiveCfg = Release|x64 + {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Static|x64.Build.0 = Release|x64 + {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Static|x86.ActiveCfg = Release|x64 + {98EAEC47-C7E9-44AA-8953-473CB9400CD0}.Static|x86.Build.0 = Release|x64 {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Debug|x64.ActiveCfg = Debug|x64 {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Debug|x64.Build.0 = Debug|x64 {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Debug|x86.ActiveCfg = Debug|x64 {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Release|x64.ActiveCfg = Release|x64 {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Release|x64.Build.0 = Release|x64 {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Release|x86.ActiveCfg = Release|x64 + {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Static|x64.ActiveCfg = Release|x64 + {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Static|x64.Build.0 = Release|x64 + {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Static|x86.ActiveCfg = Release|x64 + {26614B4A-F867-497C-BC50-DC7F4DA20ECF}.Static|x86.Build.0 = Release|x64 {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Debug|x64.ActiveCfg = Debug|x64 {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Debug|x64.Build.0 = Debug|x64 {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Debug|x86.ActiveCfg = Debug|x64 {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Release|x64.ActiveCfg = Release|x64 {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Release|x64.Build.0 = Release|x64 {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Release|x86.ActiveCfg = Release|x64 + {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Static|x64.ActiveCfg = Release|x64 + {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Static|x64.Build.0 = Release|x64 + {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Static|x86.ActiveCfg = Release|x64 + {568CA6FB-E548-49B4-88AF-11B6D1825EFE}.Static|x86.Build.0 = Release|x64 {CEF8067C-7D48-44D8-9796-D594F7915915}.Debug|x64.ActiveCfg = Debug|x64 {CEF8067C-7D48-44D8-9796-D594F7915915}.Debug|x64.Build.0 = Debug|x64 {CEF8067C-7D48-44D8-9796-D594F7915915}.Debug|x86.ActiveCfg = Debug|x64 {CEF8067C-7D48-44D8-9796-D594F7915915}.Release|x64.ActiveCfg = Release|x64 {CEF8067C-7D48-44D8-9796-D594F7915915}.Release|x64.Build.0 = Release|x64 {CEF8067C-7D48-44D8-9796-D594F7915915}.Release|x86.ActiveCfg = Release|x64 + {CEF8067C-7D48-44D8-9796-D594F7915915}.Static|x64.ActiveCfg = Release|x64 + {CEF8067C-7D48-44D8-9796-D594F7915915}.Static|x64.Build.0 = Release|x64 + {CEF8067C-7D48-44D8-9796-D594F7915915}.Static|x86.ActiveCfg = Release|x64 + {CEF8067C-7D48-44D8-9796-D594F7915915}.Static|x86.Build.0 = Release|x64 {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Debug|x64.ActiveCfg = Debug|x64 {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Debug|x64.Build.0 = Debug|x64 {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Debug|x86.ActiveCfg = Debug|x64 {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Release|x64.ActiveCfg = Release|x64 {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Release|x64.Build.0 = Release|x64 {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Release|x86.ActiveCfg = Release|x64 + {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Static|x64.ActiveCfg = Release|x64 + {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Static|x64.Build.0 = Release|x64 + {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Static|x86.ActiveCfg = Release|x64 + {8D8CB5B4-2F4E-4F33-8896-6D35232EA756}.Static|x86.Build.0 = Release|x64 {6478C07C-FA53-494A-922F-170687D9933E}.Debug|x64.ActiveCfg = Debug|x64 {6478C07C-FA53-494A-922F-170687D9933E}.Debug|x64.Build.0 = Debug|x64 {6478C07C-FA53-494A-922F-170687D9933E}.Debug|x86.ActiveCfg = Debug|x64 {6478C07C-FA53-494A-922F-170687D9933E}.Release|x64.ActiveCfg = Release|x64 {6478C07C-FA53-494A-922F-170687D9933E}.Release|x64.Build.0 = Release|x64 {6478C07C-FA53-494A-922F-170687D9933E}.Release|x86.ActiveCfg = Release|x64 + {6478C07C-FA53-494A-922F-170687D9933E}.Static|x64.ActiveCfg = Release|x64 + {6478C07C-FA53-494A-922F-170687D9933E}.Static|x64.Build.0 = Release|x64 + {6478C07C-FA53-494A-922F-170687D9933E}.Static|x86.ActiveCfg = Release|x64 + {6478C07C-FA53-494A-922F-170687D9933E}.Static|x86.Build.0 = Release|x64 {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Debug|x64.ActiveCfg = Debug|x64 {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Debug|x64.Build.0 = Debug|x64 {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Debug|x86.ActiveCfg = Debug|x64 {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Release|x64.ActiveCfg = Release|x64 {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Release|x64.Build.0 = Release|x64 {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Release|x86.ActiveCfg = Release|x64 + {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Static|x64.ActiveCfg = Release|x64 + {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Static|x64.Build.0 = Release|x64 + {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Static|x86.ActiveCfg = Release|x64 + {6A876A76-95AF-4DF1-983F-A8FE2B9E68C2}.Static|x86.Build.0 = Release|x64 {73F91272-A472-486A-8B18-3377B4C1EF1F}.Debug|x64.ActiveCfg = Debug|x64 {73F91272-A472-486A-8B18-3377B4C1EF1F}.Debug|x64.Build.0 = Debug|x64 {73F91272-A472-486A-8B18-3377B4C1EF1F}.Debug|x86.ActiveCfg = Debug|x64 {73F91272-A472-486A-8B18-3377B4C1EF1F}.Release|x64.ActiveCfg = Release|x64 {73F91272-A472-486A-8B18-3377B4C1EF1F}.Release|x64.Build.0 = Release|x64 {73F91272-A472-486A-8B18-3377B4C1EF1F}.Release|x86.ActiveCfg = Release|x64 + {73F91272-A472-486A-8B18-3377B4C1EF1F}.Static|x64.ActiveCfg = Release|x64 + {73F91272-A472-486A-8B18-3377B4C1EF1F}.Static|x64.Build.0 = Release|x64 + {73F91272-A472-486A-8B18-3377B4C1EF1F}.Static|x86.ActiveCfg = Release|x64 + {73F91272-A472-486A-8B18-3377B4C1EF1F}.Static|x86.Build.0 = Release|x64 {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Debug|x64.ActiveCfg = Debug|x64 {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Debug|x64.Build.0 = Debug|x64 {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Debug|x86.ActiveCfg = Debug|x64 {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Release|x64.ActiveCfg = Release|x64 {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Release|x64.Build.0 = Release|x64 {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Release|x86.ActiveCfg = Release|x64 + {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Static|x64.ActiveCfg = Release|x64 + {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Static|x64.Build.0 = Release|x64 + {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Static|x86.ActiveCfg = Release|x64 + {8523B581-22D3-4757-A21A-0EFF7BF736EF}.Static|x86.Build.0 = Release|x64 {75350E15-0F40-4286-907E-9F8D62BAE402}.Debug|x64.ActiveCfg = Debug|x64 {75350E15-0F40-4286-907E-9F8D62BAE402}.Debug|x64.Build.0 = Debug|x64 {75350E15-0F40-4286-907E-9F8D62BAE402}.Debug|x86.ActiveCfg = Debug|x64 {75350E15-0F40-4286-907E-9F8D62BAE402}.Release|x64.ActiveCfg = Release|x64 {75350E15-0F40-4286-907E-9F8D62BAE402}.Release|x64.Build.0 = Release|x64 {75350E15-0F40-4286-907E-9F8D62BAE402}.Release|x86.ActiveCfg = Release|x64 + {75350E15-0F40-4286-907E-9F8D62BAE402}.Static|x64.ActiveCfg = Release|x64 + {75350E15-0F40-4286-907E-9F8D62BAE402}.Static|x64.Build.0 = Release|x64 + {75350E15-0F40-4286-907E-9F8D62BAE402}.Static|x86.ActiveCfg = Release|x64 + {75350E15-0F40-4286-907E-9F8D62BAE402}.Static|x86.Build.0 = Release|x64 {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Debug|x64.ActiveCfg = Debug|x64 {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Debug|x64.Build.0 = Debug|x64 {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Debug|x86.ActiveCfg = Debug|x64 {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Release|x64.ActiveCfg = Release|x64 {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Release|x64.Build.0 = Release|x64 {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Release|x86.ActiveCfg = Release|x64 + {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Static|x64.ActiveCfg = Release|x64 + {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Static|x64.Build.0 = Release|x64 + {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Static|x86.ActiveCfg = Release|x64 + {4B5B0C58-494D-4CA5-80AC-E3EBD404E4DC}.Static|x86.Build.0 = Release|x64 {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Debug|x64.ActiveCfg = Debug|x64 {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Debug|x64.Build.0 = Debug|x64 {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Debug|x86.ActiveCfg = Debug|x64 {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Release|x64.ActiveCfg = Release|x64 {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Release|x64.Build.0 = Release|x64 {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Release|x86.ActiveCfg = Release|x64 + {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Static|x64.ActiveCfg = Release|x64 + {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Static|x64.Build.0 = Release|x64 + {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Static|x86.ActiveCfg = Release|x64 + {8598F63A-62E3-49D1-AD9A-4363E5EAB3A7}.Static|x86.Build.0 = Release|x64 {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Debug|x64.ActiveCfg = Debug|x64 {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Debug|x64.Build.0 = Debug|x64 {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Debug|x86.ActiveCfg = Debug|x64 {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Release|x64.ActiveCfg = Release|x64 {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Release|x64.Build.0 = Release|x64 {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Release|x86.ActiveCfg = Release|x64 + {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Static|x64.ActiveCfg = Release|x64 + {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Static|x64.Build.0 = Release|x64 + {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Static|x86.ActiveCfg = Release|x64 + {F7855F1D-23F7-4D6D-9525-C583F38FEE33}.Static|x86.Build.0 = Release|x64 {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Debug|x64.ActiveCfg = Debug|x64 {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Debug|x64.Build.0 = Debug|x64 {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Debug|x86.ActiveCfg = Debug|x64 {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Release|x64.ActiveCfg = Release|x64 {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Release|x64.Build.0 = Release|x64 {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Release|x86.ActiveCfg = Release|x64 + {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Static|x64.ActiveCfg = Release|x64 + {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Static|x64.Build.0 = Release|x64 + {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Static|x86.ActiveCfg = Release|x64 + {BA078FD6-A5E4-4291-97DF-D104E3BABE8F}.Static|x86.Build.0 = Release|x64 {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Debug|x64.ActiveCfg = Debug|x64 {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Debug|x64.Build.0 = Debug|x64 {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Debug|x86.ActiveCfg = Debug|x64 {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Release|x64.ActiveCfg = Release|x64 {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Release|x64.Build.0 = Release|x64 {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Release|x86.ActiveCfg = Release|x64 + {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Static|x64.ActiveCfg = Release|x64 + {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Static|x64.Build.0 = Release|x64 + {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Static|x86.ActiveCfg = Release|x64 + {9092BB58-DD66-41D8-B7AD-5E971A615A75}.Static|x86.Build.0 = Release|x64 {056877DD-DEA5-4001-B64C-26CC13D347D2}.Debug|x64.ActiveCfg = Debug|x64 {056877DD-DEA5-4001-B64C-26CC13D347D2}.Debug|x64.Build.0 = Debug|x64 {056877DD-DEA5-4001-B64C-26CC13D347D2}.Debug|x86.ActiveCfg = Debug|x64 {056877DD-DEA5-4001-B64C-26CC13D347D2}.Release|x64.ActiveCfg = Release|x64 {056877DD-DEA5-4001-B64C-26CC13D347D2}.Release|x64.Build.0 = Release|x64 {056877DD-DEA5-4001-B64C-26CC13D347D2}.Release|x86.ActiveCfg = Release|x64 + {056877DD-DEA5-4001-B64C-26CC13D347D2}.Static|x64.ActiveCfg = Release|x64 + {056877DD-DEA5-4001-B64C-26CC13D347D2}.Static|x64.Build.0 = Release|x64 + {056877DD-DEA5-4001-B64C-26CC13D347D2}.Static|x86.ActiveCfg = Release|x64 + {056877DD-DEA5-4001-B64C-26CC13D347D2}.Static|x86.Build.0 = Release|x64 {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Debug|x64.ActiveCfg = Debug|x64 {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Debug|x64.Build.0 = Debug|x64 {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Debug|x86.ActiveCfg = Debug|x64 {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Release|x64.ActiveCfg = Release|x64 {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Release|x64.Build.0 = Release|x64 {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Release|x86.ActiveCfg = Release|x64 + {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Static|x64.ActiveCfg = Release|x64 + {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Static|x64.Build.0 = Release|x64 + {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Static|x86.ActiveCfg = Release|x64 + {F0901F06-2AC5-4F05-A23A-D4C52672B5B4}.Static|x86.Build.0 = Release|x64 {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Debug|x64.ActiveCfg = Debug|x64 {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Debug|x64.Build.0 = Debug|x64 {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Debug|x86.ActiveCfg = Debug|x64 {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Release|x64.ActiveCfg = Release|x64 {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Release|x64.Build.0 = Release|x64 {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Release|x86.ActiveCfg = Release|x64 + {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Static|x64.ActiveCfg = Release|x64 + {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Static|x64.Build.0 = Release|x64 + {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Static|x86.ActiveCfg = Release|x64 + {4AD15E1D-8D88-48E5-8E5E-D9C9E6F45EDD}.Static|x86.Build.0 = Release|x64 {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Debug|x64.ActiveCfg = Debug|x64 {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Debug|x64.Build.0 = Debug|x64 {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Debug|x86.ActiveCfg = Debug|x64 {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Release|x64.ActiveCfg = Release|x64 {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Release|x64.Build.0 = Release|x64 {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Release|x86.ActiveCfg = Release|x64 + {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Static|x64.ActiveCfg = Release|x64 + {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Static|x64.Build.0 = Release|x64 + {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Static|x86.ActiveCfg = Release|x64 + {4C355ABA-DF72-49C9-B946-F7C7912C1FE0}.Static|x86.Build.0 = Release|x64 {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Debug|x64.ActiveCfg = Debug|x64 {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Debug|x64.Build.0 = Debug|x64 {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Debug|x86.ActiveCfg = Debug|x64 {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Release|x64.ActiveCfg = Release|x64 {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Release|x64.Build.0 = Release|x64 {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Release|x86.ActiveCfg = Release|x64 + {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Static|x64.ActiveCfg = Release|x64 + {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Static|x64.Build.0 = Release|x64 + {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Static|x86.ActiveCfg = Release|x64 + {C1DEF35F-F142-4032-8482-4F9FCC1A7E0B}.Static|x86.Build.0 = Release|x64 {7A38AE51-5C04-402A-8415-611176D05731}.Debug|x64.ActiveCfg = Debug|x64 {7A38AE51-5C04-402A-8415-611176D05731}.Debug|x64.Build.0 = Debug|x64 {7A38AE51-5C04-402A-8415-611176D05731}.Debug|x86.ActiveCfg = Debug|x64 {7A38AE51-5C04-402A-8415-611176D05731}.Release|x64.ActiveCfg = Release|x64 {7A38AE51-5C04-402A-8415-611176D05731}.Release|x64.Build.0 = Release|x64 {7A38AE51-5C04-402A-8415-611176D05731}.Release|x86.ActiveCfg = Release|x64 + {7A38AE51-5C04-402A-8415-611176D05731}.Static|x64.ActiveCfg = Release|x64 + {7A38AE51-5C04-402A-8415-611176D05731}.Static|x64.Build.0 = Release|x64 + {7A38AE51-5C04-402A-8415-611176D05731}.Static|x86.ActiveCfg = Release|x64 + {7A38AE51-5C04-402A-8415-611176D05731}.Static|x86.Build.0 = Release|x64 {204E46C9-E53D-4028-8188-791B01BA862F}.Debug|x64.ActiveCfg = Debug|x64 {204E46C9-E53D-4028-8188-791B01BA862F}.Debug|x64.Build.0 = Debug|x64 {204E46C9-E53D-4028-8188-791B01BA862F}.Debug|x86.ActiveCfg = Debug|x64 {204E46C9-E53D-4028-8188-791B01BA862F}.Release|x64.ActiveCfg = Release|x64 {204E46C9-E53D-4028-8188-791B01BA862F}.Release|x64.Build.0 = Release|x64 {204E46C9-E53D-4028-8188-791B01BA862F}.Release|x86.ActiveCfg = Release|x64 + {204E46C9-E53D-4028-8188-791B01BA862F}.Static|x64.ActiveCfg = Release|x64 + {204E46C9-E53D-4028-8188-791B01BA862F}.Static|x64.Build.0 = Release|x64 + {204E46C9-E53D-4028-8188-791B01BA862F}.Static|x86.ActiveCfg = Release|x64 + {204E46C9-E53D-4028-8188-791B01BA862F}.Static|x86.Build.0 = Release|x64 {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Debug|x64.ActiveCfg = Debug|x64 {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Debug|x64.Build.0 = Debug|x64 {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Debug|x86.ActiveCfg = Debug|x64 {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Release|x64.ActiveCfg = Release|x64 {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Release|x64.Build.0 = Release|x64 {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Release|x86.ActiveCfg = Release|x64 + {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Static|x64.ActiveCfg = Release|x64 + {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Static|x64.Build.0 = Release|x64 + {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Static|x86.ActiveCfg = Release|x64 + {8B885C32-2253-4B9B-9FDA-70A012CBE62E}.Static|x86.Build.0 = Release|x64 {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Debug|x64.ActiveCfg = Debug|x64 {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Debug|x64.Build.0 = Debug|x64 {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Debug|x86.ActiveCfg = Debug|x64 {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Release|x64.ActiveCfg = Release|x64 {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Release|x64.Build.0 = Release|x64 {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Release|x86.ActiveCfg = Release|x64 + {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Static|x64.ActiveCfg = Release|x64 + {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Static|x64.Build.0 = Release|x64 + {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Static|x86.ActiveCfg = Release|x64 + {60EE72AF-E131-40D7-AB58-E33361FA67AE}.Static|x86.Build.0 = Release|x64 {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Debug|x64.ActiveCfg = Debug|x64 {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Debug|x64.Build.0 = Debug|x64 {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Debug|x86.ActiveCfg = Debug|x64 {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Release|x64.ActiveCfg = Release|x64 {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Release|x64.Build.0 = Release|x64 {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Release|x86.ActiveCfg = Release|x64 + {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Static|x64.ActiveCfg = Release|x64 + {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Static|x64.Build.0 = Release|x64 + {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Static|x86.ActiveCfg = Release|x64 + {E0DF2E82-8E09-4CDC-B133-CFF712198F0D}.Static|x86.Build.0 = Release|x64 {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Debug|x64.ActiveCfg = Debug|x64 {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Debug|x64.Build.0 = Debug|x64 {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Debug|x86.ActiveCfg = Debug|x64 {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Release|x64.ActiveCfg = Release|x64 {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Release|x64.Build.0 = Release|x64 {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Release|x86.ActiveCfg = Release|x64 + {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Static|x64.ActiveCfg = Release|x64 + {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Static|x64.Build.0 = Release|x64 + {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Static|x86.ActiveCfg = Release|x64 + {17940BEA-08D0-4ADF-A193-07D71E0BFD1F}.Static|x86.Build.0 = Release|x64 {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Debug|x64.ActiveCfg = Debug|x64 {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Debug|x64.Build.0 = Debug|x64 {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Debug|x86.ActiveCfg = Debug|x64 {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Release|x64.ActiveCfg = Release|x64 {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Release|x64.Build.0 = Release|x64 {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Release|x86.ActiveCfg = Release|x64 + {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Static|x64.ActiveCfg = Release|x64 + {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Static|x64.Build.0 = Release|x64 + {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Static|x86.ActiveCfg = Release|x64 + {ECFB830E-DE05-49DF-AF71-15420D50E3BA}.Static|x86.Build.0 = Release|x64 {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Debug|x64.ActiveCfg = Debug|x64 {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Debug|x64.Build.0 = Debug|x64 {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Debug|x86.ActiveCfg = Debug|x64 {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Release|x64.ActiveCfg = Release|x64 {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Release|x64.Build.0 = Release|x64 {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Release|x86.ActiveCfg = Release|x64 + {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Static|x64.ActiveCfg = Release|x64 + {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Static|x64.Build.0 = Release|x64 + {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Static|x86.ActiveCfg = Release|x64 + {90374C7D-B9AD-459C-8D11-DE52AB3211B6}.Static|x86.Build.0 = Release|x64 {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Debug|x64.ActiveCfg = Debug|x64 {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Debug|x64.Build.0 = Debug|x64 {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Debug|x86.ActiveCfg = Debug|x64 {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Release|x64.ActiveCfg = Release|x64 {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Release|x64.Build.0 = Release|x64 {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Release|x86.ActiveCfg = Release|x64 + {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Static|x64.ActiveCfg = Release|x64 + {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Static|x64.Build.0 = Release|x64 + {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Static|x86.ActiveCfg = Release|x64 + {D7ABF609-24B2-4EBA-8700-ACED2D74B298}.Static|x86.Build.0 = Release|x64 {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Debug|x64.ActiveCfg = Debug|x64 {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Debug|x64.Build.0 = Debug|x64 {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Debug|x86.ActiveCfg = Debug|x64 {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Release|x64.ActiveCfg = Release|x64 {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Release|x64.Build.0 = Release|x64 {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Release|x86.ActiveCfg = Release|x64 + {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Static|x64.ActiveCfg = Release|x64 + {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Static|x64.Build.0 = Release|x64 + {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Static|x86.ActiveCfg = Release|x64 + {52ADE31F-157B-48C7-95A1-4078F3779D0E}.Static|x86.Build.0 = Release|x64 {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Debug|x64.ActiveCfg = Debug|x64 {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Debug|x64.Build.0 = Debug|x64 {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Debug|x86.ActiveCfg = Debug|x64 {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Release|x64.ActiveCfg = Release|x64 {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Release|x64.Build.0 = Release|x64 {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Release|x86.ActiveCfg = Release|x64 + {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Static|x64.ActiveCfg = Release|x64 + {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Static|x64.Build.0 = Release|x64 + {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Static|x86.ActiveCfg = Release|x64 + {694B2EC0-50D6-4094-A8C5-2817B4911ACC}.Static|x86.Build.0 = Release|x64 {A1CAFA42-F48D-426B-89C4-535872D025D7}.Debug|x64.ActiveCfg = Debug|x64 {A1CAFA42-F48D-426B-89C4-535872D025D7}.Debug|x64.Build.0 = Debug|x64 {A1CAFA42-F48D-426B-89C4-535872D025D7}.Debug|x86.ActiveCfg = Debug|x64 {A1CAFA42-F48D-426B-89C4-535872D025D7}.Release|x64.ActiveCfg = Release|x64 {A1CAFA42-F48D-426B-89C4-535872D025D7}.Release|x64.Build.0 = Release|x64 {A1CAFA42-F48D-426B-89C4-535872D025D7}.Release|x86.ActiveCfg = Release|x64 + {A1CAFA42-F48D-426B-89C4-535872D025D7}.Static|x64.ActiveCfg = Release|x64 + {A1CAFA42-F48D-426B-89C4-535872D025D7}.Static|x64.Build.0 = Release|x64 + {A1CAFA42-F48D-426B-89C4-535872D025D7}.Static|x86.ActiveCfg = Release|x64 + {A1CAFA42-F48D-426B-89C4-535872D025D7}.Static|x86.Build.0 = Release|x64 {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Debug|x64.ActiveCfg = Debug|x64 {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Debug|x64.Build.0 = Debug|x64 {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Debug|x86.ActiveCfg = Debug|x64 {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Release|x64.ActiveCfg = Release|x64 {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Release|x64.Build.0 = Release|x64 {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Release|x86.ActiveCfg = Release|x64 + {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Static|x64.ActiveCfg = Release|x64 + {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Static|x64.Build.0 = Release|x64 + {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Static|x86.ActiveCfg = Release|x64 + {A1F660E4-5FCA-4A6A-8A24-66928AEDE9B5}.Static|x86.Build.0 = Release|x64 {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Debug|x64.ActiveCfg = Debug|x64 {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Debug|x64.Build.0 = Debug|x64 {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Debug|x86.ActiveCfg = Debug|x64 {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Release|x64.ActiveCfg = Release|x64 {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Release|x64.Build.0 = Release|x64 {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Release|x86.ActiveCfg = Release|x64 + {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Static|x64.ActiveCfg = Release|x64 + {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Static|x64.Build.0 = Release|x64 + {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Static|x86.ActiveCfg = Release|x64 + {40B1D1F8-26A7-42B1-A850-FC400E263A5F}.Static|x86.Build.0 = Release|x64 {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Debug|x64.ActiveCfg = Debug|x64 {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Debug|x64.Build.0 = Debug|x64 {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Debug|x86.ActiveCfg = Debug|x64 {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Release|x64.ActiveCfg = Release|x64 {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Release|x64.Build.0 = Release|x64 {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Release|x86.ActiveCfg = Release|x64 + {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Static|x64.ActiveCfg = Release|x64 + {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Static|x64.Build.0 = Release|x64 + {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Static|x86.ActiveCfg = Release|x64 + {A8490DB8-1EAA-4066-AC25-6F168414AD3D}.Static|x86.Build.0 = Release|x64 {EEB4FA1D-34A6-4586-B9DA-685776918905}.Debug|x64.ActiveCfg = Debug|x64 {EEB4FA1D-34A6-4586-B9DA-685776918905}.Debug|x64.Build.0 = Debug|x64 {EEB4FA1D-34A6-4586-B9DA-685776918905}.Debug|x86.ActiveCfg = Debug|x64 {EEB4FA1D-34A6-4586-B9DA-685776918905}.Release|x64.ActiveCfg = Release|x64 {EEB4FA1D-34A6-4586-B9DA-685776918905}.Release|x64.Build.0 = Release|x64 {EEB4FA1D-34A6-4586-B9DA-685776918905}.Release|x86.ActiveCfg = Release|x64 + {EEB4FA1D-34A6-4586-B9DA-685776918905}.Static|x64.ActiveCfg = Release|x64 + {EEB4FA1D-34A6-4586-B9DA-685776918905}.Static|x64.Build.0 = Release|x64 + {EEB4FA1D-34A6-4586-B9DA-685776918905}.Static|x86.ActiveCfg = Release|x64 + {EEB4FA1D-34A6-4586-B9DA-685776918905}.Static|x86.Build.0 = Release|x64 {6F50BBB6-9309-45B2-88A5-431069456B0A}.Debug|x64.ActiveCfg = Debug|x64 {6F50BBB6-9309-45B2-88A5-431069456B0A}.Debug|x64.Build.0 = Debug|x64 {6F50BBB6-9309-45B2-88A5-431069456B0A}.Debug|x86.ActiveCfg = Debug|x64 {6F50BBB6-9309-45B2-88A5-431069456B0A}.Release|x64.ActiveCfg = Release|x64 {6F50BBB6-9309-45B2-88A5-431069456B0A}.Release|x64.Build.0 = Release|x64 {6F50BBB6-9309-45B2-88A5-431069456B0A}.Release|x86.ActiveCfg = Release|x64 + {6F50BBB6-9309-45B2-88A5-431069456B0A}.Static|x64.ActiveCfg = Release|x64 + {6F50BBB6-9309-45B2-88A5-431069456B0A}.Static|x64.Build.0 = Release|x64 + {6F50BBB6-9309-45B2-88A5-431069456B0A}.Static|x86.ActiveCfg = Release|x64 + {6F50BBB6-9309-45B2-88A5-431069456B0A}.Static|x86.Build.0 = Release|x64 {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Debug|x64.ActiveCfg = Debug|x64 {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Debug|x64.Build.0 = Debug|x64 {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Debug|x86.ActiveCfg = Debug|x64 {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Release|x64.ActiveCfg = Release|x64 {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Release|x64.Build.0 = Release|x64 {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Release|x86.ActiveCfg = Release|x64 + {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Static|x64.ActiveCfg = Release|x64 + {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Static|x64.Build.0 = Release|x64 + {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Static|x86.ActiveCfg = Release|x64 + {A6DCD2FE-34F0-4C21-BB89-F4969D151ED0}.Static|x86.Build.0 = Release|x64 {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Debug|x64.ActiveCfg = Debug|x64 {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Debug|x64.Build.0 = Debug|x64 {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Debug|x86.ActiveCfg = Debug|x64 {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Release|x64.ActiveCfg = Release|x64 {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Release|x64.Build.0 = Release|x64 {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Release|x86.ActiveCfg = Release|x64 + {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Static|x64.ActiveCfg = Release|x64 + {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Static|x64.Build.0 = Release|x64 + {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Static|x86.ActiveCfg = Release|x64 + {5813E7E9-A449-4FC4-94D3-BF7566AD6A37}.Static|x86.Build.0 = Release|x64 {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Debug|x64.ActiveCfg = Debug|x64 {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Debug|x64.Build.0 = Debug|x64 {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Debug|x86.ActiveCfg = Debug|x64 {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Release|x64.ActiveCfg = Release|x64 {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Release|x64.Build.0 = Release|x64 {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Release|x86.ActiveCfg = Release|x64 + {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Static|x64.ActiveCfg = Release|x64 + {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Static|x64.Build.0 = Release|x64 + {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Static|x86.ActiveCfg = Release|x64 + {9E2EA72E-D1D2-4CDD-A435-69E6847197C0}.Static|x86.Build.0 = Release|x64 {E430ED01-3F62-43C0-882F-3854835B1F4E}.Debug|x64.ActiveCfg = Debug|x64 {E430ED01-3F62-43C0-882F-3854835B1F4E}.Debug|x64.Build.0 = Debug|x64 {E430ED01-3F62-43C0-882F-3854835B1F4E}.Debug|x86.ActiveCfg = Debug|x64 {E430ED01-3F62-43C0-882F-3854835B1F4E}.Release|x64.ActiveCfg = Release|x64 {E430ED01-3F62-43C0-882F-3854835B1F4E}.Release|x64.Build.0 = Release|x64 {E430ED01-3F62-43C0-882F-3854835B1F4E}.Release|x86.ActiveCfg = Release|x64 + {E430ED01-3F62-43C0-882F-3854835B1F4E}.Static|x64.ActiveCfg = Release|x64 + {E430ED01-3F62-43C0-882F-3854835B1F4E}.Static|x64.Build.0 = Release|x64 + {E430ED01-3F62-43C0-882F-3854835B1F4E}.Static|x86.ActiveCfg = Release|x64 + {E430ED01-3F62-43C0-882F-3854835B1F4E}.Static|x86.Build.0 = Release|x64 {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Debug|x64.ActiveCfg = Debug|x64 {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Debug|x64.Build.0 = Debug|x64 {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Debug|x86.ActiveCfg = Debug|x64 {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Release|x64.ActiveCfg = Release|x64 {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Release|x64.Build.0 = Release|x64 {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Release|x86.ActiveCfg = Release|x64 + {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Static|x64.ActiveCfg = Release|x64 + {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Static|x64.Build.0 = Release|x64 + {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Static|x86.ActiveCfg = Release|x64 + {497CA7CB-F577-4A4B-8041-3BA64E6F7643}.Static|x86.Build.0 = Release|x64 {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Debug|x64.ActiveCfg = Debug|x64 {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Debug|x64.Build.0 = Debug|x64 {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Debug|x86.ActiveCfg = Debug|x64 {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Release|x64.ActiveCfg = Release|x64 {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Release|x64.Build.0 = Release|x64 {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Release|x86.ActiveCfg = Release|x64 + {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Static|x64.ActiveCfg = Release|x64 + {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Static|x64.Build.0 = Release|x64 + {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Static|x86.ActiveCfg = Release|x64 + {4B7A1CEB-DC3E-4B64-8E2B-C3B2C7ACAF6E}.Static|x86.Build.0 = Release|x64 {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Debug|x64.ActiveCfg = Debug|x64 {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Debug|x64.Build.0 = Debug|x64 {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Debug|x86.ActiveCfg = Debug|x64 {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Release|x64.ActiveCfg = Release|x64 {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Release|x64.Build.0 = Release|x64 {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Release|x86.ActiveCfg = Release|x64 + {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Static|x64.ActiveCfg = Release|x64 + {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Static|x64.Build.0 = Release|x64 + {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Static|x86.ActiveCfg = Release|x64 + {3B3D1028-AEE2-49E0-8874-ED487D8E3ACC}.Static|x86.Build.0 = Release|x64 {CB85257A-943D-4546-B737-F4C4D3E8A140}.Debug|x64.ActiveCfg = Debug|x64 {CB85257A-943D-4546-B737-F4C4D3E8A140}.Debug|x64.Build.0 = Debug|x64 {CB85257A-943D-4546-B737-F4C4D3E8A140}.Debug|x86.ActiveCfg = Debug|x64 {CB85257A-943D-4546-B737-F4C4D3E8A140}.Release|x64.ActiveCfg = Release|x64 {CB85257A-943D-4546-B737-F4C4D3E8A140}.Release|x64.Build.0 = Release|x64 {CB85257A-943D-4546-B737-F4C4D3E8A140}.Release|x86.ActiveCfg = Release|x64 + {CB85257A-943D-4546-B737-F4C4D3E8A140}.Static|x64.ActiveCfg = Release|x64 + {CB85257A-943D-4546-B737-F4C4D3E8A140}.Static|x64.Build.0 = Release|x64 + {CB85257A-943D-4546-B737-F4C4D3E8A140}.Static|x86.ActiveCfg = Release|x64 + {CB85257A-943D-4546-B737-F4C4D3E8A140}.Static|x86.Build.0 = Release|x64 {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Debug|x64.ActiveCfg = Debug|x64 {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Debug|x64.Build.0 = Debug|x64 {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Debug|x86.ActiveCfg = Debug|x64 {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Release|x64.ActiveCfg = Release|x64 {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Release|x64.Build.0 = Release|x64 {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Release|x86.ActiveCfg = Release|x64 + {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Static|x64.ActiveCfg = Release|x64 + {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Static|x64.Build.0 = Release|x64 + {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Static|x86.ActiveCfg = Release|x64 + {DD07EF89-0819-46BD-95DD-BF8399A92D7A}.Static|x86.Build.0 = Release|x64 {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Debug|x64.ActiveCfg = Debug|x64 {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Debug|x64.Build.0 = Debug|x64 {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Debug|x86.ActiveCfg = Debug|x64 {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Release|x64.ActiveCfg = Release|x64 {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Release|x64.Build.0 = Release|x64 {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Release|x86.ActiveCfg = Release|x64 + {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Static|x64.ActiveCfg = Release|x64 + {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Static|x64.Build.0 = Release|x64 + {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Static|x86.ActiveCfg = Release|x64 + {CDFDCCB0-E445-4D06-A688-B194FCE0DFA1}.Static|x86.Build.0 = Release|x64 {9A271709-1CE1-4B85-8B30-110F5E184D95}.Debug|x64.ActiveCfg = Debug|x64 {9A271709-1CE1-4B85-8B30-110F5E184D95}.Debug|x64.Build.0 = Debug|x64 {9A271709-1CE1-4B85-8B30-110F5E184D95}.Debug|x86.ActiveCfg = Debug|x64 {9A271709-1CE1-4B85-8B30-110F5E184D95}.Release|x64.ActiveCfg = Release|x64 {9A271709-1CE1-4B85-8B30-110F5E184D95}.Release|x64.Build.0 = Release|x64 {9A271709-1CE1-4B85-8B30-110F5E184D95}.Release|x86.ActiveCfg = Release|x64 + {9A271709-1CE1-4B85-8B30-110F5E184D95}.Static|x64.ActiveCfg = Release|x64 + {9A271709-1CE1-4B85-8B30-110F5E184D95}.Static|x64.Build.0 = Release|x64 + {9A271709-1CE1-4B85-8B30-110F5E184D95}.Static|x86.ActiveCfg = Release|x64 + {9A271709-1CE1-4B85-8B30-110F5E184D95}.Static|x86.Build.0 = Release|x64 {727B10D5-CDB1-4EB8-B988-7529702D4606}.Debug|x64.ActiveCfg = Debug|x64 {727B10D5-CDB1-4EB8-B988-7529702D4606}.Debug|x64.Build.0 = Debug|x64 {727B10D5-CDB1-4EB8-B988-7529702D4606}.Debug|x86.ActiveCfg = Debug|x64 {727B10D5-CDB1-4EB8-B988-7529702D4606}.Release|x64.ActiveCfg = Release|x64 {727B10D5-CDB1-4EB8-B988-7529702D4606}.Release|x64.Build.0 = Release|x64 {727B10D5-CDB1-4EB8-B988-7529702D4606}.Release|x86.ActiveCfg = Release|x64 + {727B10D5-CDB1-4EB8-B988-7529702D4606}.Static|x64.ActiveCfg = Release|x64 + {727B10D5-CDB1-4EB8-B988-7529702D4606}.Static|x64.Build.0 = Release|x64 + {727B10D5-CDB1-4EB8-B988-7529702D4606}.Static|x86.ActiveCfg = Release|x64 + {727B10D5-CDB1-4EB8-B988-7529702D4606}.Static|x86.Build.0 = Release|x64 {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Debug|x64.ActiveCfg = Debug|x64 {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Debug|x64.Build.0 = Debug|x64 {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Debug|x86.ActiveCfg = Debug|x64 {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Release|x64.ActiveCfg = Release|x64 {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Release|x64.Build.0 = Release|x64 {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Release|x86.ActiveCfg = Release|x64 + {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Static|x64.ActiveCfg = Release|x64 + {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Static|x64.Build.0 = Release|x64 + {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Static|x86.ActiveCfg = Release|x64 + {8C60E541-7ABC-40ED-8940-AEF1D97AE6CC}.Static|x86.Build.0 = Release|x64 {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Debug|x64.ActiveCfg = Debug|x64 {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Debug|x64.Build.0 = Debug|x64 {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Debug|x86.ActiveCfg = Debug|x64 {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Release|x64.ActiveCfg = Release|x64 {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Release|x64.Build.0 = Release|x64 {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Release|x86.ActiveCfg = Release|x64 + {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Static|x64.ActiveCfg = Release|x64 + {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Static|x64.Build.0 = Release|x64 + {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Static|x86.ActiveCfg = Release|x64 + {971C960B-2E59-4160-8D59-92BFB14AEDF4}.Static|x86.Build.0 = Release|x64 {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Debug|x64.ActiveCfg = Debug|x64 {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Debug|x64.Build.0 = Debug|x64 {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Debug|x86.ActiveCfg = Debug|x64 {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Release|x64.ActiveCfg = Release|x64 {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Release|x64.Build.0 = Release|x64 {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Release|x86.ActiveCfg = Release|x64 + {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Static|x64.ActiveCfg = Release|x64 + {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Static|x64.Build.0 = Release|x64 + {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Static|x86.ActiveCfg = Release|x64 + {312FB92B-3290-4909-BFF8-A6DC5D79488D}.Static|x86.Build.0 = Release|x64 {E05103FA-817B-42AD-88CA-7C429BD77F87}.Debug|x64.ActiveCfg = Debug|x64 {E05103FA-817B-42AD-88CA-7C429BD77F87}.Debug|x64.Build.0 = Debug|x64 {E05103FA-817B-42AD-88CA-7C429BD77F87}.Debug|x86.ActiveCfg = Debug|x64 {E05103FA-817B-42AD-88CA-7C429BD77F87}.Release|x64.ActiveCfg = Release|x64 {E05103FA-817B-42AD-88CA-7C429BD77F87}.Release|x64.Build.0 = Release|x64 {E05103FA-817B-42AD-88CA-7C429BD77F87}.Release|x86.ActiveCfg = Release|x64 + {E05103FA-817B-42AD-88CA-7C429BD77F87}.Static|x64.ActiveCfg = Release|x64 + {E05103FA-817B-42AD-88CA-7C429BD77F87}.Static|x64.Build.0 = Release|x64 + {E05103FA-817B-42AD-88CA-7C429BD77F87}.Static|x86.ActiveCfg = Release|x64 + {E05103FA-817B-42AD-88CA-7C429BD77F87}.Static|x86.Build.0 = Release|x64 {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Debug|x64.ActiveCfg = Debug|x64 {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Debug|x64.Build.0 = Debug|x64 {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Debug|x86.ActiveCfg = Debug|x64 {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Release|x64.ActiveCfg = Release|x64 {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Release|x64.Build.0 = Release|x64 {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Release|x86.ActiveCfg = Release|x64 + {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Static|x64.ActiveCfg = Release|x64 + {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Static|x64.Build.0 = Release|x64 + {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Static|x86.ActiveCfg = Release|x64 + {938650B9-6CFB-4BD9-89F3-632ECFD3FC5C}.Static|x86.Build.0 = Release|x64 {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Debug|x64.ActiveCfg = Debug|x64 {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Debug|x64.Build.0 = Debug|x64 {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Debug|x86.ActiveCfg = Debug|x64 {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Release|x64.ActiveCfg = Release|x64 {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Release|x64.Build.0 = Release|x64 {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Release|x86.ActiveCfg = Release|x64 + {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Static|x64.ActiveCfg = Release|x64 + {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Static|x64.Build.0 = Release|x64 + {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Static|x86.ActiveCfg = Release|x64 + {60E12FC5-F246-497F-A7AB-C1FFDECC8365}.Static|x86.Build.0 = Release|x64 {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Debug|x64.ActiveCfg = Debug|x64 {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Debug|x64.Build.0 = Debug|x64 {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Debug|x86.ActiveCfg = Debug|x64 {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Release|x64.ActiveCfg = Release|x64 {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Release|x64.Build.0 = Release|x64 {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Release|x86.ActiveCfg = Release|x64 + {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Static|x64.ActiveCfg = Release|x64 + {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Static|x64.Build.0 = Release|x64 + {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Static|x86.ActiveCfg = Release|x64 + {351CD9CD-AEB8-4EC1-8DEC-854BC97DAA62}.Static|x86.Build.0 = Release|x64 {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Debug|x64.ActiveCfg = Debug|x64 {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Debug|x64.Build.0 = Debug|x64 {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Debug|x86.ActiveCfg = Debug|x64 {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Release|x64.ActiveCfg = Release|x64 {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Release|x64.Build.0 = Release|x64 {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Release|x86.ActiveCfg = Release|x64 + {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Static|x64.ActiveCfg = Release|x64 + {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Static|x64.Build.0 = Release|x64 + {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Static|x86.ActiveCfg = Release|x64 + {62F096ED-DAAA-4E11-B959-FA17C4DACE6E}.Static|x86.Build.0 = Release|x64 {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Debug|x64.ActiveCfg = Debug|x64 {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Debug|x64.Build.0 = Debug|x64 {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Debug|x86.ActiveCfg = Debug|x64 {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Release|x64.ActiveCfg = Release|x64 {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Release|x64.Build.0 = Release|x64 {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Release|x86.ActiveCfg = Release|x64 + {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Static|x64.ActiveCfg = Release|x64 + {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Static|x64.Build.0 = Release|x64 + {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Static|x86.ActiveCfg = Release|x64 + {95DCC41F-E001-4BA1-BD29-BB0AB3472F5B}.Static|x86.Build.0 = Release|x64 {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Debug|x64.ActiveCfg = Debug|x64 {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Debug|x64.Build.0 = Debug|x64 {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Debug|x86.ActiveCfg = Debug|x64 {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Release|x64.ActiveCfg = Release|x64 {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Release|x64.Build.0 = Release|x64 {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Release|x86.ActiveCfg = Release|x64 + {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Static|x64.ActiveCfg = Release|x64 + {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Static|x64.Build.0 = Release|x64 + {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Static|x86.ActiveCfg = Release|x64 + {4DB513E0-A9C3-4EC9-B9A0-B6A754F85D16}.Static|x86.Build.0 = Release|x64 {E1D7117A-1014-429A-B759-5556B6DDC25B}.Debug|x64.ActiveCfg = Debug|x64 {E1D7117A-1014-429A-B759-5556B6DDC25B}.Debug|x64.Build.0 = Debug|x64 {E1D7117A-1014-429A-B759-5556B6DDC25B}.Debug|x86.ActiveCfg = Debug|x64 {E1D7117A-1014-429A-B759-5556B6DDC25B}.Release|x64.ActiveCfg = Release|x64 {E1D7117A-1014-429A-B759-5556B6DDC25B}.Release|x64.Build.0 = Release|x64 {E1D7117A-1014-429A-B759-5556B6DDC25B}.Release|x86.ActiveCfg = Release|x64 + {E1D7117A-1014-429A-B759-5556B6DDC25B}.Static|x64.ActiveCfg = Release|x64 + {E1D7117A-1014-429A-B759-5556B6DDC25B}.Static|x64.Build.0 = Release|x64 + {E1D7117A-1014-429A-B759-5556B6DDC25B}.Static|x86.ActiveCfg = Release|x64 + {E1D7117A-1014-429A-B759-5556B6DDC25B}.Static|x86.Build.0 = Release|x64 {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Debug|x64.ActiveCfg = Debug|x64 {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Debug|x64.Build.0 = Debug|x64 {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Debug|x86.ActiveCfg = Debug|x64 {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Release|x64.ActiveCfg = Release|x64 {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Release|x64.Build.0 = Release|x64 {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Release|x86.ActiveCfg = Release|x64 + {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Static|x64.ActiveCfg = Release|x64 + {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Static|x64.Build.0 = Release|x64 + {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Static|x86.ActiveCfg = Release|x64 + {2E8C16BA-4E21-46E2-9CE6-7D4FBB8F704B}.Static|x86.Build.0 = Release|x64 {699298AE-7266-4BDC-B314-E77963442B50}.Debug|x64.ActiveCfg = Debug|x64 {699298AE-7266-4BDC-B314-E77963442B50}.Debug|x64.Build.0 = Debug|x64 {699298AE-7266-4BDC-B314-E77963442B50}.Debug|x86.ActiveCfg = Debug|x64 {699298AE-7266-4BDC-B314-E77963442B50}.Release|x64.ActiveCfg = Release|x64 {699298AE-7266-4BDC-B314-E77963442B50}.Release|x64.Build.0 = Release|x64 {699298AE-7266-4BDC-B314-E77963442B50}.Release|x86.ActiveCfg = Release|x64 + {699298AE-7266-4BDC-B314-E77963442B50}.Static|x64.ActiveCfg = Release|x64 + {699298AE-7266-4BDC-B314-E77963442B50}.Static|x64.Build.0 = Release|x64 + {699298AE-7266-4BDC-B314-E77963442B50}.Static|x86.ActiveCfg = Release|x64 + {699298AE-7266-4BDC-B314-E77963442B50}.Static|x86.Build.0 = Release|x64 {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Debug|x64.ActiveCfg = Debug|x64 {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Debug|x64.Build.0 = Debug|x64 {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Debug|x86.ActiveCfg = Debug|x64 {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Release|x64.ActiveCfg = Release|x64 {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Release|x64.Build.0 = Release|x64 {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Release|x86.ActiveCfg = Release|x64 + {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Static|x64.ActiveCfg = Release|x64 + {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Static|x64.Build.0 = Release|x64 + {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Static|x86.ActiveCfg = Release|x64 + {4480BE6E-C119-4DF9-97A7-726F8C6E8463}.Static|x86.Build.0 = Release|x64 {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Debug|x64.ActiveCfg = Debug|x64 {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Debug|x64.Build.0 = Debug|x64 {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Debug|x86.ActiveCfg = Debug|x64 {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Release|x64.ActiveCfg = Release|x64 {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Release|x64.Build.0 = Release|x64 {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Release|x86.ActiveCfg = Release|x64 + {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Static|x64.ActiveCfg = Release|x64 + {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Static|x64.Build.0 = Release|x64 + {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Static|x86.ActiveCfg = Release|x64 + {F9FF78C7-F0F2-46B2-A5F0-3C6D22BCC8E7}.Static|x86.Build.0 = Release|x64 {40EB68C0-30B0-419A-867F-067884E01F98}.Debug|x64.ActiveCfg = Debug|x64 {40EB68C0-30B0-419A-867F-067884E01F98}.Debug|x64.Build.0 = Debug|x64 {40EB68C0-30B0-419A-867F-067884E01F98}.Debug|x86.ActiveCfg = Debug|x64 {40EB68C0-30B0-419A-867F-067884E01F98}.Release|x64.ActiveCfg = Release|x64 {40EB68C0-30B0-419A-867F-067884E01F98}.Release|x64.Build.0 = Release|x64 {40EB68C0-30B0-419A-867F-067884E01F98}.Release|x86.ActiveCfg = Release|x64 + {40EB68C0-30B0-419A-867F-067884E01F98}.Static|x64.ActiveCfg = Release|x64 + {40EB68C0-30B0-419A-867F-067884E01F98}.Static|x64.Build.0 = Release|x64 + {40EB68C0-30B0-419A-867F-067884E01F98}.Static|x86.ActiveCfg = Release|x64 + {40EB68C0-30B0-419A-867F-067884E01F98}.Static|x86.Build.0 = Release|x64 {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Debug|x64.ActiveCfg = Debug|x64 {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Debug|x64.Build.0 = Debug|x64 {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Debug|x86.ActiveCfg = Debug|x64 {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Release|x64.ActiveCfg = Release|x64 {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Release|x64.Build.0 = Release|x64 {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Release|x86.ActiveCfg = Release|x64 + {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Static|x64.ActiveCfg = Release|x64 + {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Static|x64.Build.0 = Release|x64 + {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Static|x86.ActiveCfg = Release|x64 + {16ED96FF-9A70-424B-8713-1E342DACD6D3}.Static|x86.Build.0 = Release|x64 {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Debug|x64.ActiveCfg = Debug|x64 {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Debug|x64.Build.0 = Debug|x64 {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Debug|x86.ActiveCfg = Debug|x64 {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Release|x64.ActiveCfg = Release|x64 {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Release|x64.Build.0 = Release|x64 {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Release|x86.ActiveCfg = Release|x64 + {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Static|x64.ActiveCfg = Release|x64 + {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Static|x64.Build.0 = Release|x64 + {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Static|x86.ActiveCfg = Release|x64 + {403B7B9B-7131-4BBD-BDD2-7D2C20B4FD66}.Static|x86.Build.0 = Release|x64 {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Debug|x64.ActiveCfg = Debug|x64 {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Debug|x64.Build.0 = Debug|x64 {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Debug|x86.ActiveCfg = Debug|x64 {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Release|x64.ActiveCfg = Release|x64 {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Release|x64.Build.0 = Release|x64 {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Release|x86.ActiveCfg = Release|x64 + {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Static|x64.ActiveCfg = Release|x64 + {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Static|x64.Build.0 = Release|x64 + {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Static|x86.ActiveCfg = Release|x64 + {C05A9B82-EAFE-49D3-B333-D867DCF27A19}.Static|x86.Build.0 = Release|x64 {24CAB46F-A794-4316-B139-6D6250E4E697}.Debug|x64.ActiveCfg = Debug|x64 {24CAB46F-A794-4316-B139-6D6250E4E697}.Debug|x64.Build.0 = Debug|x64 {24CAB46F-A794-4316-B139-6D6250E4E697}.Debug|x86.ActiveCfg = Debug|x64 {24CAB46F-A794-4316-B139-6D6250E4E697}.Release|x64.ActiveCfg = Release|x64 {24CAB46F-A794-4316-B139-6D6250E4E697}.Release|x64.Build.0 = Release|x64 {24CAB46F-A794-4316-B139-6D6250E4E697}.Release|x86.ActiveCfg = Release|x64 + {24CAB46F-A794-4316-B139-6D6250E4E697}.Static|x64.ActiveCfg = Release|x64 + {24CAB46F-A794-4316-B139-6D6250E4E697}.Static|x64.Build.0 = Release|x64 + {24CAB46F-A794-4316-B139-6D6250E4E697}.Static|x86.ActiveCfg = Release|x64 + {24CAB46F-A794-4316-B139-6D6250E4E697}.Static|x86.Build.0 = Release|x64 {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Debug|x64.ActiveCfg = Debug|x64 {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Debug|x64.Build.0 = Debug|x64 {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Debug|x86.ActiveCfg = Debug|x64 {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Release|x64.ActiveCfg = Release|x64 {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Release|x64.Build.0 = Release|x64 {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Release|x86.ActiveCfg = Release|x64 + {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Static|x64.ActiveCfg = Release|x64 + {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Static|x64.Build.0 = Release|x64 + {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Static|x86.ActiveCfg = Release|x64 + {3C88E3FC-C471-4972-AF1D-2B53EA324D7B}.Static|x86.Build.0 = Release|x64 {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Debug|x64.ActiveCfg = Debug|x64 {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Debug|x64.Build.0 = Debug|x64 {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Debug|x86.ActiveCfg = Debug|x64 {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Release|x64.ActiveCfg = Release|x64 {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Release|x64.Build.0 = Release|x64 {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Release|x86.ActiveCfg = Release|x64 + {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Static|x64.ActiveCfg = Release|x64 + {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Static|x64.Build.0 = Release|x64 + {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Static|x86.ActiveCfg = Release|x64 + {3987A4A6-38C3-4E71-ACFC-66EA72D34366}.Static|x86.Build.0 = Release|x64 {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Debug|x64.ActiveCfg = Debug|x64 {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Debug|x64.Build.0 = Debug|x64 {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Debug|x86.ActiveCfg = Debug|x64 {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Release|x64.ActiveCfg = Release|x64 {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Release|x64.Build.0 = Release|x64 {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Release|x86.ActiveCfg = Release|x64 + {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Static|x64.ActiveCfg = Release|x64 + {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Static|x64.Build.0 = Release|x64 + {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Static|x86.ActiveCfg = Release|x64 + {0256BC73-AAA2-4ED8-A491-92A98BEE0ED0}.Static|x86.Build.0 = Release|x64 {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Debug|x64.ActiveCfg = Debug|x64 {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Debug|x64.Build.0 = Debug|x64 {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Debug|x86.ActiveCfg = Debug|x64 {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Release|x64.ActiveCfg = Release|x64 {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Release|x64.Build.0 = Release|x64 {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Release|x86.ActiveCfg = Release|x64 + {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Static|x64.ActiveCfg = Release|x64 + {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Static|x64.Build.0 = Release|x64 + {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Static|x86.ActiveCfg = Release|x64 + {49AB364B-D3F5-4035-9367-6D784CCAB33B}.Static|x86.Build.0 = Release|x64 {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Debug|x64.ActiveCfg = Debug|x64 {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Debug|x64.Build.0 = Debug|x64 {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Debug|x86.ActiveCfg = Debug|x64 {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Release|x64.ActiveCfg = Release|x64 {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Release|x64.Build.0 = Release|x64 {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Release|x86.ActiveCfg = Release|x64 + {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Static|x64.ActiveCfg = Release|x64 + {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Static|x64.Build.0 = Release|x64 + {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Static|x86.ActiveCfg = Release|x64 + {887BDE27-1490-487C-8FDA-99766D6F2B5A}.Static|x86.Build.0 = Release|x64 {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Debug|x64.ActiveCfg = Debug|x64 {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Debug|x64.Build.0 = Debug|x64 {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Debug|x86.ActiveCfg = Debug|x64 {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Release|x64.ActiveCfg = Release|x64 {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Release|x64.Build.0 = Release|x64 {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Release|x86.ActiveCfg = Release|x64 + {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Static|x64.ActiveCfg = Release|x64 + {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Static|x64.Build.0 = Release|x64 + {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Static|x86.ActiveCfg = Release|x64 + {995386C7-249F-4E3F-86AF-A2B8C7EB17EE}.Static|x86.Build.0 = Release|x64 {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Debug|x64.ActiveCfg = Debug|x64 {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Debug|x64.Build.0 = Debug|x64 {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Debug|x86.ActiveCfg = Debug|x64 {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Release|x64.ActiveCfg = Release|x64 {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Release|x64.Build.0 = Release|x64 {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Release|x86.ActiveCfg = Release|x64 + {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Static|x64.ActiveCfg = Release|x64 + {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Static|x64.Build.0 = Release|x64 + {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Static|x86.ActiveCfg = Release|x64 + {6231EA81-7C9A-4391-97F0-AA83E6F7D881}.Static|x86.Build.0 = Release|x64 {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Debug|x64.ActiveCfg = Debug|x64 {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Debug|x64.Build.0 = Debug|x64 {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Debug|x86.ActiveCfg = Debug|x64 {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Release|x64.ActiveCfg = Release|x64 {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Release|x64.Build.0 = Release|x64 {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Release|x86.ActiveCfg = Release|x64 + {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Static|x64.ActiveCfg = Release|x64 + {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Static|x64.Build.0 = Release|x64 + {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Static|x86.ActiveCfg = Release|x64 + {C0410DFA-CB11-4C5A-9D3F-0A107E766602}.Static|x86.Build.0 = Release|x64 {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Debug|x64.ActiveCfg = Debug|x64 {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Debug|x64.Build.0 = Debug|x64 {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Debug|x86.ActiveCfg = Debug|x64 {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Release|x64.ActiveCfg = Release|x64 {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Release|x64.Build.0 = Release|x64 {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Release|x86.ActiveCfg = Release|x64 + {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Static|x64.ActiveCfg = Release|x64 + {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Static|x64.Build.0 = Release|x64 + {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Static|x86.ActiveCfg = Release|x64 + {93529A37-49D7-4E6E-AB45-B08BBCB4A367}.Static|x86.Build.0 = Release|x64 {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Debug|x64.ActiveCfg = Debug|x64 {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Debug|x64.Build.0 = Debug|x64 {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Debug|x86.ActiveCfg = Debug|x64 {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Release|x64.ActiveCfg = Release|x64 {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Release|x64.Build.0 = Release|x64 {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Release|x86.ActiveCfg = Release|x64 + {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Static|x64.ActiveCfg = Release|x64 + {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Static|x64.Build.0 = Release|x64 + {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Static|x86.ActiveCfg = Release|x64 + {7C83386E-09DF-4DB2-A491-09B7F20F8C0C}.Static|x86.Build.0 = Release|x64 {577D0485-EFB4-401C-8F88-9FE6990691DF}.Debug|x64.ActiveCfg = Debug|x64 {577D0485-EFB4-401C-8F88-9FE6990691DF}.Debug|x64.Build.0 = Debug|x64 {577D0485-EFB4-401C-8F88-9FE6990691DF}.Debug|x86.ActiveCfg = Debug|x64 {577D0485-EFB4-401C-8F88-9FE6990691DF}.Release|x64.ActiveCfg = Release|x64 {577D0485-EFB4-401C-8F88-9FE6990691DF}.Release|x64.Build.0 = Release|x64 {577D0485-EFB4-401C-8F88-9FE6990691DF}.Release|x86.ActiveCfg = Release|x64 + {577D0485-EFB4-401C-8F88-9FE6990691DF}.Static|x64.ActiveCfg = Release|x64 + {577D0485-EFB4-401C-8F88-9FE6990691DF}.Static|x64.Build.0 = Release|x64 + {577D0485-EFB4-401C-8F88-9FE6990691DF}.Static|x86.ActiveCfg = Release|x64 + {577D0485-EFB4-401C-8F88-9FE6990691DF}.Static|x86.Build.0 = Release|x64 {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Debug|x64.ActiveCfg = Debug|x64 {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Debug|x64.Build.0 = Debug|x64 {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Debug|x86.ActiveCfg = Debug|x64 {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Release|x64.ActiveCfg = Release|x64 {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Release|x64.Build.0 = Release|x64 {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Release|x86.ActiveCfg = Release|x64 + {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Static|x64.ActiveCfg = Release|x64 + {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Static|x64.Build.0 = Release|x64 + {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Static|x86.ActiveCfg = Release|x64 + {B50F1860-F2DB-4345-8A90-542B24AEAA3B}.Static|x86.Build.0 = Release|x64 {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Debug|x64.ActiveCfg = Debug|x64 {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Debug|x64.Build.0 = Debug|x64 {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Debug|x86.ActiveCfg = Debug|x64 {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Release|x64.ActiveCfg = Release|x64 {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Release|x64.Build.0 = Release|x64 {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Release|x86.ActiveCfg = Release|x64 + {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Static|x64.ActiveCfg = Release|x64 + {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Static|x64.Build.0 = Release|x64 + {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Static|x86.ActiveCfg = Release|x64 + {A612D05A-251C-498F-ACC8-9F31BBFAFAD6}.Static|x86.Build.0 = Release|x64 {9552A896-98A6-4160-8DD0-44BAA14D7205}.Debug|x64.ActiveCfg = Debug|x64 {9552A896-98A6-4160-8DD0-44BAA14D7205}.Debug|x64.Build.0 = Debug|x64 {9552A896-98A6-4160-8DD0-44BAA14D7205}.Debug|x86.ActiveCfg = Debug|x64 {9552A896-98A6-4160-8DD0-44BAA14D7205}.Release|x64.ActiveCfg = Release|x64 {9552A896-98A6-4160-8DD0-44BAA14D7205}.Release|x64.Build.0 = Release|x64 {9552A896-98A6-4160-8DD0-44BAA14D7205}.Release|x86.ActiveCfg = Release|x64 + {9552A896-98A6-4160-8DD0-44BAA14D7205}.Static|x64.ActiveCfg = Release|x64 + {9552A896-98A6-4160-8DD0-44BAA14D7205}.Static|x64.Build.0 = Release|x64 + {9552A896-98A6-4160-8DD0-44BAA14D7205}.Static|x86.ActiveCfg = Release|x64 + {9552A896-98A6-4160-8DD0-44BAA14D7205}.Static|x86.Build.0 = Release|x64 {6C5A9683-2480-488B-B5B6-057F8383E444}.Debug|x64.ActiveCfg = Debug|x64 {6C5A9683-2480-488B-B5B6-057F8383E444}.Debug|x64.Build.0 = Debug|x64 {6C5A9683-2480-488B-B5B6-057F8383E444}.Debug|x86.ActiveCfg = Debug|x64 {6C5A9683-2480-488B-B5B6-057F8383E444}.Release|x64.ActiveCfg = Release|x64 {6C5A9683-2480-488B-B5B6-057F8383E444}.Release|x64.Build.0 = Release|x64 {6C5A9683-2480-488B-B5B6-057F8383E444}.Release|x86.ActiveCfg = Release|x64 + {6C5A9683-2480-488B-B5B6-057F8383E444}.Static|x64.ActiveCfg = Release|x64 + {6C5A9683-2480-488B-B5B6-057F8383E444}.Static|x64.Build.0 = Release|x64 + {6C5A9683-2480-488B-B5B6-057F8383E444}.Static|x86.ActiveCfg = Release|x64 + {6C5A9683-2480-488B-B5B6-057F8383E444}.Static|x86.Build.0 = Release|x64 {0D507AC6-8284-4081-8E1F-F62538D670C4}.Debug|x64.ActiveCfg = Debug|x64 {0D507AC6-8284-4081-8E1F-F62538D670C4}.Debug|x64.Build.0 = Debug|x64 {0D507AC6-8284-4081-8E1F-F62538D670C4}.Debug|x86.ActiveCfg = Debug|x64 {0D507AC6-8284-4081-8E1F-F62538D670C4}.Release|x64.ActiveCfg = Release|x64 {0D507AC6-8284-4081-8E1F-F62538D670C4}.Release|x64.Build.0 = Release|x64 {0D507AC6-8284-4081-8E1F-F62538D670C4}.Release|x86.ActiveCfg = Release|x64 + {0D507AC6-8284-4081-8E1F-F62538D670C4}.Static|x64.ActiveCfg = Release|x64 + {0D507AC6-8284-4081-8E1F-F62538D670C4}.Static|x64.Build.0 = Release|x64 + {0D507AC6-8284-4081-8E1F-F62538D670C4}.Static|x86.ActiveCfg = Release|x64 + {0D507AC6-8284-4081-8E1F-F62538D670C4}.Static|x86.Build.0 = Release|x64 {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Debug|x64.ActiveCfg = Debug|x64 {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Debug|x64.Build.0 = Debug|x64 {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Debug|x86.ActiveCfg = Debug|x64 {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Release|x64.ActiveCfg = Release|x64 {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Release|x64.Build.0 = Release|x64 {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Release|x86.ActiveCfg = Release|x64 + {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Static|x64.ActiveCfg = Release|x64 + {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Static|x64.Build.0 = Release|x64 + {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Static|x86.ActiveCfg = Release|x64 + {6D8C8302-85F1-41BC-9FED-85756CFF4722}.Static|x86.Build.0 = Release|x64 {1DE6423B-A00A-4554-A951-D582E5E324F7}.Debug|x64.ActiveCfg = Debug|x64 {1DE6423B-A00A-4554-A951-D582E5E324F7}.Debug|x64.Build.0 = Debug|x64 {1DE6423B-A00A-4554-A951-D582E5E324F7}.Debug|x86.ActiveCfg = Debug|x64 {1DE6423B-A00A-4554-A951-D582E5E324F7}.Release|x64.ActiveCfg = Release|x64 {1DE6423B-A00A-4554-A951-D582E5E324F7}.Release|x64.Build.0 = Release|x64 {1DE6423B-A00A-4554-A951-D582E5E324F7}.Release|x86.ActiveCfg = Release|x64 + {1DE6423B-A00A-4554-A951-D582E5E324F7}.Static|x64.ActiveCfg = Release|x64 + {1DE6423B-A00A-4554-A951-D582E5E324F7}.Static|x64.Build.0 = Release|x64 + {1DE6423B-A00A-4554-A951-D582E5E324F7}.Static|x86.ActiveCfg = Release|x64 + {1DE6423B-A00A-4554-A951-D582E5E324F7}.Static|x86.Build.0 = Release|x64 {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Debug|x64.ActiveCfg = Debug|x64 {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Debug|x64.Build.0 = Debug|x64 {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Debug|x86.ActiveCfg = Debug|x64 {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Release|x64.ActiveCfg = Release|x64 {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Release|x64.Build.0 = Release|x64 {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Release|x86.ActiveCfg = Release|x64 + {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Static|x64.ActiveCfg = Release|x64 + {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Static|x64.Build.0 = Release|x64 + {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Static|x86.ActiveCfg = Release|x64 + {69A5EB03-3814-4F5B-8E74-8B5BF517880A}.Static|x86.Build.0 = Release|x64 {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Debug|x64.ActiveCfg = Debug|x64 {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Debug|x64.Build.0 = Debug|x64 {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Debug|x86.ActiveCfg = Debug|x64 {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Release|x64.ActiveCfg = Release|x64 {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Release|x64.Build.0 = Release|x64 {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Release|x86.ActiveCfg = Release|x64 + {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Static|x64.ActiveCfg = Release|x64 + {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Static|x64.Build.0 = Release|x64 + {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Static|x86.ActiveCfg = Release|x64 + {430DC071-7DA9-4ADB-8DC7-024B23906D8F}.Static|x86.Build.0 = Release|x64 {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Debug|x64.ActiveCfg = Debug|x64 {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Debug|x64.Build.0 = Debug|x64 {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Debug|x86.ActiveCfg = Debug|x64 {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Release|x64.ActiveCfg = Release|x64 {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Release|x64.Build.0 = Release|x64 {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Release|x86.ActiveCfg = Release|x64 + {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Static|x64.ActiveCfg = Release|x64 + {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Static|x64.Build.0 = Release|x64 + {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Static|x86.ActiveCfg = Release|x64 + {F8DE0E35-7CA4-4992-8FCE-A9DCFFEB19CE}.Static|x86.Build.0 = Release|x64 {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Debug|x64.ActiveCfg = Debug|x64 {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Debug|x64.Build.0 = Debug|x64 {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Debug|x86.ActiveCfg = Debug|x64 {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Release|x64.ActiveCfg = Release|x64 {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Release|x64.Build.0 = Release|x64 {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Release|x86.ActiveCfg = Release|x64 + {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Static|x64.ActiveCfg = Release|x64 + {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Static|x64.Build.0 = Release|x64 + {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Static|x86.ActiveCfg = Release|x64 + {629A5E06-BE9B-400C-8C5D-6571D23066AA}.Static|x86.Build.0 = Release|x64 {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Debug|x64.ActiveCfg = Debug|x64 {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Debug|x64.Build.0 = Debug|x64 {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Debug|x86.ActiveCfg = Debug|x64 {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Release|x64.ActiveCfg = Release|x64 {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Release|x64.Build.0 = Release|x64 {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Release|x86.ActiveCfg = Release|x64 + {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Static|x64.ActiveCfg = Release|x64 + {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Static|x64.Build.0 = Release|x64 + {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Static|x86.ActiveCfg = Release|x64 + {D48F4FC8-6D61-4BFA-99D0-610D6B15DCCB}.Static|x86.Build.0 = Release|x64 {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Debug|x64.ActiveCfg = Debug|x64 {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Debug|x64.Build.0 = Debug|x64 {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Debug|x86.ActiveCfg = Debug|x64 {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Release|x64.ActiveCfg = Release|x64 {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Release|x64.Build.0 = Release|x64 {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Release|x86.ActiveCfg = Release|x64 + {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Static|x64.ActiveCfg = Release|x64 + {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Static|x64.Build.0 = Release|x64 + {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Static|x86.ActiveCfg = Release|x64 + {41A84AB1-76A3-4EDA-A6CB-EF1982990C32}.Static|x86.Build.0 = Release|x64 {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Debug|x64.ActiveCfg = Debug|x64 {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Debug|x64.Build.0 = Debug|x64 {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Debug|x86.ActiveCfg = Debug|x64 {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Release|x64.ActiveCfg = Release|x64 {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Release|x64.Build.0 = Release|x64 {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Release|x86.ActiveCfg = Release|x64 + {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Static|x64.ActiveCfg = Release|x64 + {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Static|x64.Build.0 = Release|x64 + {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Static|x86.ActiveCfg = Release|x64 + {4FF91B6D-C8DB-402A-8718-58527DAFCE4E}.Static|x86.Build.0 = Release|x64 {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Debug|x64.ActiveCfg = Debug|x64 {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Debug|x64.Build.0 = Debug|x64 {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Debug|x86.ActiveCfg = Debug|x64 {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Release|x64.ActiveCfg = Release|x64 {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Release|x64.Build.0 = Release|x64 {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Release|x86.ActiveCfg = Release|x64 + {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Static|x64.ActiveCfg = Release|x64 + {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Static|x64.Build.0 = Release|x64 + {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Static|x86.ActiveCfg = Release|x64 + {95BEEA4A-DBA2-48DE-9A09-8244B60E4272}.Static|x86.Build.0 = Release|x64 {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Debug|x64.ActiveCfg = Debug|x64 {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Debug|x64.Build.0 = Debug|x64 {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Debug|x86.ActiveCfg = Debug|x64 {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Release|x64.ActiveCfg = Release|x64 {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Release|x64.Build.0 = Release|x64 {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Release|x86.ActiveCfg = Release|x64 + {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Static|x64.ActiveCfg = Release|x64 + {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Static|x64.Build.0 = Release|x64 + {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Static|x86.ActiveCfg = Release|x64 + {1B9A426D-98EA-4097-AA54-6338EC71E3A0}.Static|x86.Build.0 = Release|x64 {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Debug|x64.ActiveCfg = Debug|x64 {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Debug|x64.Build.0 = Debug|x64 {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Debug|x86.ActiveCfg = Debug|x64 {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Release|x64.ActiveCfg = Release|x64 {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Release|x64.Build.0 = Release|x64 {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Release|x86.ActiveCfg = Release|x64 + {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Static|x64.ActiveCfg = Release|x64 + {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Static|x64.Build.0 = Release|x64 + {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Static|x86.ActiveCfg = Release|x64 + {DF137DF5-28F8-459D-8D24-C6903838A9E6}.Static|x86.Build.0 = Release|x64 {32025899-2AF2-45F6-B603-5FB42F79A234}.Debug|x64.ActiveCfg = Debug|x64 {32025899-2AF2-45F6-B603-5FB42F79A234}.Debug|x64.Build.0 = Debug|x64 {32025899-2AF2-45F6-B603-5FB42F79A234}.Debug|x86.ActiveCfg = Debug|x64 {32025899-2AF2-45F6-B603-5FB42F79A234}.Release|x64.ActiveCfg = Release|x64 {32025899-2AF2-45F6-B603-5FB42F79A234}.Release|x64.Build.0 = Release|x64 {32025899-2AF2-45F6-B603-5FB42F79A234}.Release|x86.ActiveCfg = Release|x64 + {32025899-2AF2-45F6-B603-5FB42F79A234}.Static|x64.ActiveCfg = Release|x64 + {32025899-2AF2-45F6-B603-5FB42F79A234}.Static|x64.Build.0 = Release|x64 + {32025899-2AF2-45F6-B603-5FB42F79A234}.Static|x86.ActiveCfg = Release|x64 + {32025899-2AF2-45F6-B603-5FB42F79A234}.Static|x86.Build.0 = Release|x64 {02332986-DC1D-4090-BFC8-F9494D3FE297}.Debug|x64.ActiveCfg = Debug|x64 {02332986-DC1D-4090-BFC8-F9494D3FE297}.Debug|x64.Build.0 = Debug|x64 {02332986-DC1D-4090-BFC8-F9494D3FE297}.Debug|x86.ActiveCfg = Debug|x64 {02332986-DC1D-4090-BFC8-F9494D3FE297}.Release|x64.ActiveCfg = Release|x64 {02332986-DC1D-4090-BFC8-F9494D3FE297}.Release|x64.Build.0 = Release|x64 {02332986-DC1D-4090-BFC8-F9494D3FE297}.Release|x86.ActiveCfg = Release|x64 + {02332986-DC1D-4090-BFC8-F9494D3FE297}.Static|x64.ActiveCfg = Release|x64 + {02332986-DC1D-4090-BFC8-F9494D3FE297}.Static|x64.Build.0 = Release|x64 + {02332986-DC1D-4090-BFC8-F9494D3FE297}.Static|x86.ActiveCfg = Release|x64 + {02332986-DC1D-4090-BFC8-F9494D3FE297}.Static|x86.Build.0 = Release|x64 {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Debug|x64.ActiveCfg = Debug|x64 {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Debug|x64.Build.0 = Debug|x64 {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Debug|x86.ActiveCfg = Debug|x64 {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Release|x64.ActiveCfg = Release|x64 {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Release|x64.Build.0 = Release|x64 {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Release|x86.ActiveCfg = Release|x64 + {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Static|x64.ActiveCfg = Release|x64 + {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Static|x64.Build.0 = Release|x64 + {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Static|x86.ActiveCfg = Release|x64 + {27B8F081-ECE6-485F-A2B1-FB092B5CCD6A}.Static|x86.Build.0 = Release|x64 {A65B0838-1244-4002-885B-09073B7DDDBA}.Debug|x64.ActiveCfg = Debug|x64 {A65B0838-1244-4002-885B-09073B7DDDBA}.Debug|x64.Build.0 = Debug|x64 {A65B0838-1244-4002-885B-09073B7DDDBA}.Debug|x86.ActiveCfg = Debug|x64 {A65B0838-1244-4002-885B-09073B7DDDBA}.Release|x64.ActiveCfg = Release|x64 {A65B0838-1244-4002-885B-09073B7DDDBA}.Release|x64.Build.0 = Release|x64 {A65B0838-1244-4002-885B-09073B7DDDBA}.Release|x86.ActiveCfg = Release|x64 + {A65B0838-1244-4002-885B-09073B7DDDBA}.Static|x64.ActiveCfg = Release|x64 + {A65B0838-1244-4002-885B-09073B7DDDBA}.Static|x64.Build.0 = Release|x64 + {A65B0838-1244-4002-885B-09073B7DDDBA}.Static|x86.ActiveCfg = Release|x64 + {A65B0838-1244-4002-885B-09073B7DDDBA}.Static|x86.Build.0 = Release|x64 {0499586B-F18F-482C-8055-06ED2FC13A36}.Debug|x64.ActiveCfg = Debug|x64 {0499586B-F18F-482C-8055-06ED2FC13A36}.Debug|x64.Build.0 = Debug|x64 {0499586B-F18F-482C-8055-06ED2FC13A36}.Debug|x86.ActiveCfg = Debug|x64 {0499586B-F18F-482C-8055-06ED2FC13A36}.Release|x64.ActiveCfg = Release|x64 {0499586B-F18F-482C-8055-06ED2FC13A36}.Release|x64.Build.0 = Release|x64 {0499586B-F18F-482C-8055-06ED2FC13A36}.Release|x86.ActiveCfg = Release|x64 + {0499586B-F18F-482C-8055-06ED2FC13A36}.Static|x64.ActiveCfg = Release|x64 + {0499586B-F18F-482C-8055-06ED2FC13A36}.Static|x64.Build.0 = Release|x64 + {0499586B-F18F-482C-8055-06ED2FC13A36}.Static|x86.ActiveCfg = Release|x64 + {0499586B-F18F-482C-8055-06ED2FC13A36}.Static|x86.Build.0 = Release|x64 {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Debug|x64.ActiveCfg = Debug|x64 {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Debug|x64.Build.0 = Debug|x64 {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Debug|x86.ActiveCfg = Debug|x64 {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Release|x64.ActiveCfg = Release|x64 {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Release|x64.Build.0 = Release|x64 {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Release|x86.ActiveCfg = Release|x64 + {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Static|x64.ActiveCfg = Release|x64 + {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Static|x64.Build.0 = Release|x64 + {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Static|x86.ActiveCfg = Release|x64 + {F4163CBA-1A05-492B-A0BB-04AB0291359A}.Static|x86.Build.0 = Release|x64 {AF3F1CE7-411D-496B-B53F-31A53667F055}.Debug|x64.ActiveCfg = Debug|x64 {AF3F1CE7-411D-496B-B53F-31A53667F055}.Debug|x64.Build.0 = Debug|x64 {AF3F1CE7-411D-496B-B53F-31A53667F055}.Debug|x86.ActiveCfg = Debug|x64 {AF3F1CE7-411D-496B-B53F-31A53667F055}.Release|x64.ActiveCfg = Release|x64 {AF3F1CE7-411D-496B-B53F-31A53667F055}.Release|x64.Build.0 = Release|x64 {AF3F1CE7-411D-496B-B53F-31A53667F055}.Release|x86.ActiveCfg = Release|x64 + {AF3F1CE7-411D-496B-B53F-31A53667F055}.Static|x64.ActiveCfg = Release|x64 + {AF3F1CE7-411D-496B-B53F-31A53667F055}.Static|x64.Build.0 = Release|x64 + {AF3F1CE7-411D-496B-B53F-31A53667F055}.Static|x86.ActiveCfg = Release|x64 + {AF3F1CE7-411D-496B-B53F-31A53667F055}.Static|x86.Build.0 = Release|x64 {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Debug|x64.ActiveCfg = Debug|x64 {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Debug|x64.Build.0 = Debug|x64 {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Debug|x86.ActiveCfg = Debug|x64 {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Release|x64.ActiveCfg = Release|x64 {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Release|x64.Build.0 = Release|x64 {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Release|x86.ActiveCfg = Release|x64 + {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Static|x64.ActiveCfg = Release|x64 + {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Static|x64.Build.0 = Release|x64 + {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Static|x86.ActiveCfg = Release|x64 + {6AE5707C-B774-4CFE-A33C-89DA0FFFFFD7}.Static|x86.Build.0 = Release|x64 {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Debug|x64.ActiveCfg = Debug|x64 {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Debug|x64.Build.0 = Debug|x64 {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Debug|x86.ActiveCfg = Debug|x64 {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Release|x64.ActiveCfg = Release|x64 {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Release|x64.Build.0 = Release|x64 {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Release|x86.ActiveCfg = Release|x64 + {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Static|x64.ActiveCfg = Release|x64 + {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Static|x64.Build.0 = Release|x64 + {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Static|x86.ActiveCfg = Release|x64 + {F2830064-BDDB-4EC3-AF34-F0342288C5D4}.Static|x86.Build.0 = Release|x64 {0E84773D-D688-49AD-814C-45F0AABD385D}.Debug|x64.ActiveCfg = Debug|x64 {0E84773D-D688-49AD-814C-45F0AABD385D}.Debug|x64.Build.0 = Debug|x64 {0E84773D-D688-49AD-814C-45F0AABD385D}.Debug|x86.ActiveCfg = Debug|x64 {0E84773D-D688-49AD-814C-45F0AABD385D}.Release|x64.ActiveCfg = Release|x64 {0E84773D-D688-49AD-814C-45F0AABD385D}.Release|x64.Build.0 = Release|x64 {0E84773D-D688-49AD-814C-45F0AABD385D}.Release|x86.ActiveCfg = Release|x64 + {0E84773D-D688-49AD-814C-45F0AABD385D}.Static|x64.ActiveCfg = Release|x64 + {0E84773D-D688-49AD-814C-45F0AABD385D}.Static|x64.Build.0 = Release|x64 + {0E84773D-D688-49AD-814C-45F0AABD385D}.Static|x86.ActiveCfg = Release|x64 + {0E84773D-D688-49AD-814C-45F0AABD385D}.Static|x86.Build.0 = Release|x64 {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Debug|x64.ActiveCfg = Debug|x64 {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Debug|x64.Build.0 = Debug|x64 {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Debug|x86.ActiveCfg = Debug|x64 {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Release|x64.ActiveCfg = Release|x64 {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Release|x64.Build.0 = Release|x64 {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Release|x86.ActiveCfg = Release|x64 + {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Static|x64.ActiveCfg = Release|x64 + {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Static|x64.Build.0 = Release|x64 + {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Static|x86.ActiveCfg = Release|x64 + {DDC8B41F-2859-4736-B37B-D5A6A8A086AF}.Static|x86.Build.0 = Release|x64 {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Debug|x64.ActiveCfg = Debug|x64 {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Debug|x64.Build.0 = Debug|x64 {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Debug|x86.ActiveCfg = Debug|x64 {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Release|x64.ActiveCfg = Release|x64 {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Release|x64.Build.0 = Release|x64 {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Release|x86.ActiveCfg = Release|x64 + {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Static|x64.ActiveCfg = Release|x64 + {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Static|x64.Build.0 = Release|x64 + {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Static|x86.ActiveCfg = Release|x64 + {F59E62B5-AA5A-4216-A1CD-8E0897AC28B8}.Static|x86.Build.0 = Release|x64 {B4D83262-6ED7-410C-A90C-10C3109FB664}.Debug|x64.ActiveCfg = Debug|x64 {B4D83262-6ED7-410C-A90C-10C3109FB664}.Debug|x64.Build.0 = Debug|x64 {B4D83262-6ED7-410C-A90C-10C3109FB664}.Debug|x86.ActiveCfg = Debug|x64 {B4D83262-6ED7-410C-A90C-10C3109FB664}.Release|x64.ActiveCfg = Release|x64 {B4D83262-6ED7-410C-A90C-10C3109FB664}.Release|x64.Build.0 = Release|x64 {B4D83262-6ED7-410C-A90C-10C3109FB664}.Release|x86.ActiveCfg = Release|Win32 + {B4D83262-6ED7-410C-A90C-10C3109FB664}.Static|x64.ActiveCfg = Release|x64 + {B4D83262-6ED7-410C-A90C-10C3109FB664}.Static|x64.Build.0 = Release|x64 + {B4D83262-6ED7-410C-A90C-10C3109FB664}.Static|x86.ActiveCfg = Release|Win32 + {B4D83262-6ED7-410C-A90C-10C3109FB664}.Static|x86.Build.0 = Release|Win32 {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Debug|x64.ActiveCfg = Debug|x64 {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Debug|x64.Build.0 = Debug|x64 {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Debug|x86.ActiveCfg = Debug|x64 {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Release|x64.ActiveCfg = Release|x64 {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Release|x64.Build.0 = Release|x64 {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Release|x86.ActiveCfg = Release|Win32 + {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Static|x64.ActiveCfg = Release|x64 + {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Static|x64.Build.0 = Release|x64 + {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Static|x86.ActiveCfg = Release|Win32 + {932082C7-D8B8-44D8-99D1-2E138EFA5172}.Static|x86.Build.0 = Release|Win32 {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Debug|x64.ActiveCfg = Debug|x64 {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Debug|x64.Build.0 = Debug|x64 {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Debug|x86.ActiveCfg = Debug|x64 {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Release|x64.ActiveCfg = Release|x64 {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Release|x64.Build.0 = Release|x64 {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Release|x86.ActiveCfg = Release|Win32 + {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Static|x64.ActiveCfg = Release|x64 + {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Static|x64.Build.0 = Release|x64 + {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Static|x86.ActiveCfg = Release|Win32 + {20C3A5B2-DC60-4F31-9DFC-1BDF671A80F1}.Static|x86.Build.0 = Release|Win32 {E7D46902-602E-497E-8C80-3AE3026092C3}.Debug|x64.ActiveCfg = Debug|x64 {E7D46902-602E-497E-8C80-3AE3026092C3}.Debug|x64.Build.0 = Debug|x64 {E7D46902-602E-497E-8C80-3AE3026092C3}.Debug|x86.ActiveCfg = Debug|x64 {E7D46902-602E-497E-8C80-3AE3026092C3}.Release|x64.ActiveCfg = Release|x64 {E7D46902-602E-497E-8C80-3AE3026092C3}.Release|x64.Build.0 = Release|x64 {E7D46902-602E-497E-8C80-3AE3026092C3}.Release|x86.ActiveCfg = Release|x64 + {E7D46902-602E-497E-8C80-3AE3026092C3}.Static|x64.ActiveCfg = Release|x64 + {E7D46902-602E-497E-8C80-3AE3026092C3}.Static|x64.Build.0 = Release|x64 + {E7D46902-602E-497E-8C80-3AE3026092C3}.Static|x86.ActiveCfg = Release|x64 + {E7D46902-602E-497E-8C80-3AE3026092C3}.Static|x86.Build.0 = Release|x64 {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Debug|x64.ActiveCfg = Debug|x64 {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Debug|x64.Build.0 = Debug|x64 {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Debug|x86.ActiveCfg = Debug|x64 {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Release|x64.ActiveCfg = Release|x64 {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Release|x64.Build.0 = Release|x64 {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Release|x86.ActiveCfg = Release|Win32 + {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Static|x64.ActiveCfg = Release|x64 + {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Static|x64.Build.0 = Release|x64 + {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Static|x86.ActiveCfg = Release|Win32 + {6C4C4C79-6722-4A60-BB55-386FB2EE1E46}.Static|x86.Build.0 = Release|Win32 {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Debug|x64.ActiveCfg = Debug|x64 {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Debug|x64.Build.0 = Debug|x64 {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Debug|x86.ActiveCfg = Debug|x64 {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Release|x64.ActiveCfg = Release|x64 {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Release|x64.Build.0 = Release|x64 {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Release|x86.ActiveCfg = Release|Win32 + {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Static|x64.ActiveCfg = Release|x64 + {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Static|x64.Build.0 = Release|x64 + {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Static|x86.ActiveCfg = Release|Win32 + {EAC8D4B2-27BB-44CE-AD2E-DC78B5D8EFE3}.Static|x86.Build.0 = Release|Win32 {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Debug|x64.ActiveCfg = Debug|x64 {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Debug|x64.Build.0 = Debug|x64 {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Debug|x86.ActiveCfg = Debug|x64 {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Release|x64.ActiveCfg = Release|x64 {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Release|x64.Build.0 = Release|x64 {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Release|x86.ActiveCfg = Release|x64 + {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Static|x64.ActiveCfg = Release|x64 + {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Static|x64.Build.0 = Release|x64 + {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Static|x86.ActiveCfg = Release|x64 + {FCAB7716-5FE0-445F-95E9-A9153C63503B}.Static|x86.Build.0 = Release|x64 {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Debug|x64.ActiveCfg = Debug|x64 {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Debug|x64.Build.0 = Debug|x64 {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Debug|x86.ActiveCfg = Debug|x64 {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Release|x64.ActiveCfg = Release|x64 {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Release|x64.Build.0 = Release|x64 {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Release|x86.ActiveCfg = Release|x64 + {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Static|x64.ActiveCfg = Release|x64 + {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Static|x64.Build.0 = Release|x64 + {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Static|x86.ActiveCfg = Release|x64 + {2667D5DB-A960-4244-9BED-0D1CD1EB4F1D}.Static|x86.Build.0 = Release|x64 {A5029F58-9D3A-4129-90E1-15748428F383}.Debug|x64.ActiveCfg = Debug|x64 {A5029F58-9D3A-4129-90E1-15748428F383}.Debug|x64.Build.0 = Debug|x64 {A5029F58-9D3A-4129-90E1-15748428F383}.Debug|x86.ActiveCfg = Debug|x64 {A5029F58-9D3A-4129-90E1-15748428F383}.Release|x64.ActiveCfg = Release|x64 {A5029F58-9D3A-4129-90E1-15748428F383}.Release|x64.Build.0 = Release|x64 {A5029F58-9D3A-4129-90E1-15748428F383}.Release|x86.ActiveCfg = Release|x64 + {A5029F58-9D3A-4129-90E1-15748428F383}.Static|x64.ActiveCfg = Release|x64 + {A5029F58-9D3A-4129-90E1-15748428F383}.Static|x64.Build.0 = Release|x64 + {A5029F58-9D3A-4129-90E1-15748428F383}.Static|x86.ActiveCfg = Release|x64 + {A5029F58-9D3A-4129-90E1-15748428F383}.Static|x86.Build.0 = Release|x64 {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Debug|x64.ActiveCfg = Debug|x64 {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Debug|x64.Build.0 = Debug|x64 {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Debug|x86.ActiveCfg = Debug|x64 {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Release|x64.ActiveCfg = Release|x64 {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Release|x64.Build.0 = Release|x64 {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Release|x86.ActiveCfg = Release|x64 + {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Static|x64.ActiveCfg = Release|x64 + {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Static|x64.Build.0 = Release|x64 + {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Static|x86.ActiveCfg = Release|x64 + {EF908F11-8BC1-4EFA-AD86-9723E7CFDEEB}.Static|x86.Build.0 = Release|x64 {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Debug|x64.ActiveCfg = Debug|x64 {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Debug|x64.Build.0 = Debug|x64 {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Debug|x86.ActiveCfg = Debug|x64 {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Release|x64.ActiveCfg = Release|x64 {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Release|x64.Build.0 = Release|x64 {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Release|x86.ActiveCfg = Release|x64 + {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Static|x64.ActiveCfg = Release|x64 + {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Static|x64.Build.0 = Release|x64 + {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Static|x86.ActiveCfg = Release|x64 + {A082A871-BC27-476D-A99E-F9F3EC7C460E}.Static|x86.Build.0 = Release|x64 {189B353F-6776-4C56-97F3-A7935FE01D62}.Debug|x64.ActiveCfg = Debug|x64 {189B353F-6776-4C56-97F3-A7935FE01D62}.Debug|x64.Build.0 = Debug|x64 {189B353F-6776-4C56-97F3-A7935FE01D62}.Debug|x86.ActiveCfg = Debug|x64 {189B353F-6776-4C56-97F3-A7935FE01D62}.Release|x64.ActiveCfg = Release|x64 {189B353F-6776-4C56-97F3-A7935FE01D62}.Release|x64.Build.0 = Release|x64 {189B353F-6776-4C56-97F3-A7935FE01D62}.Release|x86.ActiveCfg = Release|x64 + {189B353F-6776-4C56-97F3-A7935FE01D62}.Static|x64.ActiveCfg = Release|x64 + {189B353F-6776-4C56-97F3-A7935FE01D62}.Static|x64.Build.0 = Release|x64 + {189B353F-6776-4C56-97F3-A7935FE01D62}.Static|x86.ActiveCfg = Release|x64 + {189B353F-6776-4C56-97F3-A7935FE01D62}.Static|x86.Build.0 = Release|x64 {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Debug|x64.ActiveCfg = Debug|x64 {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Debug|x64.Build.0 = Debug|x64 {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Debug|x86.ActiveCfg = Debug|x64 {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Release|x64.ActiveCfg = Release|x64 {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Release|x64.Build.0 = Release|x64 {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Release|x86.ActiveCfg = Release|x64 + {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Static|x64.ActiveCfg = Release|x64 + {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Static|x64.Build.0 = Release|x64 + {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Static|x86.ActiveCfg = Release|x64 + {19CC1127-02BE-4CA3-A4D5-D3D5039078AA}.Static|x86.Build.0 = Release|x64 {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Debug|x64.ActiveCfg = Debug|x64 {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Debug|x64.Build.0 = Debug|x64 {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Debug|x86.ActiveCfg = Debug|x64 {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Release|x64.ActiveCfg = Release|x64 {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Release|x64.Build.0 = Release|x64 {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Release|x86.ActiveCfg = Release|x64 + {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Static|x64.ActiveCfg = Release|x64 + {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Static|x64.Build.0 = Release|x64 + {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Static|x86.ActiveCfg = Release|x64 + {759D9206-D15D-43CA-A4E2-CCBB8F6D90A9}.Static|x86.Build.0 = Release|x64 {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Debug|x64.ActiveCfg = Debug|x64 {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Debug|x64.Build.0 = Debug|x64 {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Debug|x86.ActiveCfg = Debug|x64 {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Release|x64.ActiveCfg = Release|x64 {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Release|x64.Build.0 = Release|x64 {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Release|x86.ActiveCfg = Release|x64 + {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Static|x64.ActiveCfg = Release|x64 + {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Static|x64.Build.0 = Release|x64 + {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Static|x86.ActiveCfg = Release|x64 + {47F2DA82-C96F-4214-B97F-ABC3C3AE5C0F}.Static|x86.Build.0 = Release|x64 {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Debug|x64.ActiveCfg = Debug|x64 {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Debug|x64.Build.0 = Debug|x64 {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Debug|x86.ActiveCfg = Debug|x64 {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Release|x64.ActiveCfg = Release|x64 {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Release|x64.Build.0 = Release|x64 {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Release|x86.ActiveCfg = Release|x64 + {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Static|x64.ActiveCfg = Release|x64 + {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Static|x64.Build.0 = Release|x64 + {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Static|x86.ActiveCfg = Release|x64 + {F2A78969-5252-44ED-9B7C-2CB6CD74F8AC}.Static|x86.Build.0 = Release|x64 {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Debug|x64.ActiveCfg = Debug|x64 {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Debug|x64.Build.0 = Debug|x64 {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Debug|x86.ActiveCfg = Debug|x64 {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Release|x64.ActiveCfg = Release|x64 {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Release|x64.Build.0 = Release|x64 {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Release|x86.ActiveCfg = Release|x64 + {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Static|x64.ActiveCfg = Release|x64 + {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Static|x64.Build.0 = Release|x64 + {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Static|x86.ActiveCfg = Release|x64 + {61B83BD8-143D-4DCD-A7D6-F335CE8EB80E}.Static|x86.Build.0 = Release|x64 {34A962FC-8489-469D-A440-CB450CC259D1}.Debug|x64.ActiveCfg = Debug|x64 {34A962FC-8489-469D-A440-CB450CC259D1}.Debug|x64.Build.0 = Debug|x64 {34A962FC-8489-469D-A440-CB450CC259D1}.Debug|x86.ActiveCfg = Debug|x64 {34A962FC-8489-469D-A440-CB450CC259D1}.Release|x64.ActiveCfg = Release|x64 {34A962FC-8489-469D-A440-CB450CC259D1}.Release|x64.Build.0 = Release|x64 {34A962FC-8489-469D-A440-CB450CC259D1}.Release|x86.ActiveCfg = Release|x64 + {34A962FC-8489-469D-A440-CB450CC259D1}.Static|x64.ActiveCfg = Release|x64 + {34A962FC-8489-469D-A440-CB450CC259D1}.Static|x64.Build.0 = Release|x64 + {34A962FC-8489-469D-A440-CB450CC259D1}.Static|x86.ActiveCfg = Release|x64 + {34A962FC-8489-469D-A440-CB450CC259D1}.Static|x86.Build.0 = Release|x64 {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Debug|x64.ActiveCfg = Debug|x64 {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Debug|x64.Build.0 = Debug|x64 {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Debug|x86.ActiveCfg = Debug|x64 {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Release|x64.ActiveCfg = Release|x64 {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Release|x64.Build.0 = Release|x64 {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Release|x86.ActiveCfg = Release|x64 + {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Static|x64.ActiveCfg = Release|x64 + {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Static|x64.Build.0 = Release|x64 + {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Static|x86.ActiveCfg = Release|x64 + {95CCFFBB-1D88-4F57-9ABD-3C5658D40CBC}.Static|x86.Build.0 = Release|x64 {015E247D-C084-4879-AADE-5CDDC8A6F693}.Debug|x64.ActiveCfg = Debug|x64 {015E247D-C084-4879-AADE-5CDDC8A6F693}.Debug|x64.Build.0 = Debug|x64 {015E247D-C084-4879-AADE-5CDDC8A6F693}.Debug|x86.ActiveCfg = Debug|x64 {015E247D-C084-4879-AADE-5CDDC8A6F693}.Release|x64.ActiveCfg = Release|x64 {015E247D-C084-4879-AADE-5CDDC8A6F693}.Release|x64.Build.0 = Release|x64 {015E247D-C084-4879-AADE-5CDDC8A6F693}.Release|x86.ActiveCfg = Release|x64 + {015E247D-C084-4879-AADE-5CDDC8A6F693}.Static|x64.ActiveCfg = Release|x64 + {015E247D-C084-4879-AADE-5CDDC8A6F693}.Static|x64.Build.0 = Release|x64 + {015E247D-C084-4879-AADE-5CDDC8A6F693}.Static|x86.ActiveCfg = Release|x64 + {015E247D-C084-4879-AADE-5CDDC8A6F693}.Static|x86.Build.0 = Release|x64 {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Debug|x64.ActiveCfg = Debug|x64 {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Debug|x64.Build.0 = Debug|x64 {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Debug|x86.ActiveCfg = Debug|x64 {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Release|x64.ActiveCfg = Release|x64 {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Release|x64.Build.0 = Release|x64 {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Release|x86.ActiveCfg = Release|x64 + {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Static|x64.ActiveCfg = Release|x64 + {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Static|x64.Build.0 = Release|x64 + {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Static|x86.ActiveCfg = Release|x64 + {174E3B2A-FEDE-42C3-A8B9-EEC8D783AEB9}.Static|x86.Build.0 = Release|x64 {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Debug|x64.ActiveCfg = Debug|x64 {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Debug|x64.Build.0 = Debug|x64 {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Debug|x86.ActiveCfg = Debug|x64 {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Release|x64.ActiveCfg = Release|x64 {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Release|x64.Build.0 = Release|x64 {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Release|x86.ActiveCfg = Release|x64 + {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Static|x64.ActiveCfg = Release|x64 + {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Static|x64.Build.0 = Release|x64 + {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Static|x86.ActiveCfg = Release|x64 + {55BD5E63-14DC-4E67-A2EF-262710ACFBAA}.Static|x86.Build.0 = Release|x64 {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Debug|x64.ActiveCfg = Debug|x64 {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Debug|x64.Build.0 = Debug|x64 {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Debug|x86.ActiveCfg = Debug|x64 {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Release|x64.ActiveCfg = Release|x64 {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Release|x64.Build.0 = Release|x64 {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Release|x86.ActiveCfg = Release|x64 + {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Static|x64.ActiveCfg = Release|x64 + {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Static|x64.Build.0 = Release|x64 + {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Static|x86.ActiveCfg = Release|x64 + {7D58F786-7A66-4544-8E44-563A2AE0E0B3}.Static|x86.Build.0 = Release|x64 {E8560318-BBFD-489A-82E9-0F608033241F}.Debug|x64.ActiveCfg = Debug|x64 {E8560318-BBFD-489A-82E9-0F608033241F}.Debug|x64.Build.0 = Debug|x64 {E8560318-BBFD-489A-82E9-0F608033241F}.Debug|x86.ActiveCfg = Debug|x64 {E8560318-BBFD-489A-82E9-0F608033241F}.Release|x64.ActiveCfg = Release|x64 {E8560318-BBFD-489A-82E9-0F608033241F}.Release|x64.Build.0 = Release|x64 {E8560318-BBFD-489A-82E9-0F608033241F}.Release|x86.ActiveCfg = Release|x64 + {E8560318-BBFD-489A-82E9-0F608033241F}.Static|x64.ActiveCfg = Release|x64 + {E8560318-BBFD-489A-82E9-0F608033241F}.Static|x64.Build.0 = Release|x64 + {E8560318-BBFD-489A-82E9-0F608033241F}.Static|x86.ActiveCfg = Release|x64 + {E8560318-BBFD-489A-82E9-0F608033241F}.Static|x86.Build.0 = Release|x64 {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Debug|x64.ActiveCfg = Debug|x64 {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Debug|x64.Build.0 = Debug|x64 {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Debug|x86.ActiveCfg = Debug|x64 {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Release|x64.ActiveCfg = Release|x64 {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Release|x64.Build.0 = Release|x64 {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Release|x86.ActiveCfg = Release|x64 + {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Static|x64.ActiveCfg = Release|x64 + {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Static|x64.Build.0 = Release|x64 + {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Static|x86.ActiveCfg = Release|x64 + {FA719C6C-DBF5-4D88-A591-0AB6224B8C64}.Static|x86.Build.0 = Release|x64 {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Debug|x64.ActiveCfg = Debug|x64 {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Debug|x64.Build.0 = Debug|x64 {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Debug|x86.ActiveCfg = Debug|x64 {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Release|x64.ActiveCfg = Release|x64 {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Release|x64.Build.0 = Release|x64 {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Release|x86.ActiveCfg = Release|x64 + {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Static|x64.ActiveCfg = Release|x64 + {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Static|x64.Build.0 = Release|x64 + {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Static|x86.ActiveCfg = Release|x64 + {8300D5C7-CF36-4DF4-B3A0-5E311FC6996F}.Static|x86.Build.0 = Release|x64 {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Debug|x64.ActiveCfg = Debug|x64 {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Debug|x64.Build.0 = Debug|x64 {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Debug|x86.ActiveCfg = Debug|x64 {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Release|x64.ActiveCfg = Release|x64 {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Release|x64.Build.0 = Release|x64 {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Release|x86.ActiveCfg = Release|x64 + {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Static|x64.ActiveCfg = Release|x64 + {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Static|x64.Build.0 = Release|x64 + {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Static|x86.ActiveCfg = Release|x64 + {6D8331B8-448F-495C-AB44-A71FC0C07B1C}.Static|x86.Build.0 = Release|x64 {18C09E20-296A-4E88-9970-0465EDD818FB}.Debug|x64.ActiveCfg = Debug|x64 {18C09E20-296A-4E88-9970-0465EDD818FB}.Debug|x64.Build.0 = Debug|x64 {18C09E20-296A-4E88-9970-0465EDD818FB}.Debug|x86.ActiveCfg = Debug|x64 {18C09E20-296A-4E88-9970-0465EDD818FB}.Release|x64.ActiveCfg = Release|x64 {18C09E20-296A-4E88-9970-0465EDD818FB}.Release|x64.Build.0 = Release|x64 {18C09E20-296A-4E88-9970-0465EDD818FB}.Release|x86.ActiveCfg = Release|x64 + {18C09E20-296A-4E88-9970-0465EDD818FB}.Static|x64.ActiveCfg = Release|x64 + {18C09E20-296A-4E88-9970-0465EDD818FB}.Static|x64.Build.0 = Release|x64 + {18C09E20-296A-4E88-9970-0465EDD818FB}.Static|x86.ActiveCfg = Release|x64 + {18C09E20-296A-4E88-9970-0465EDD818FB}.Static|x86.Build.0 = Release|x64 {A63683B8-097D-43D9-9E41-743F57318851}.Debug|x64.ActiveCfg = Debug|x64 {A63683B8-097D-43D9-9E41-743F57318851}.Debug|x64.Build.0 = Debug|x64 {A63683B8-097D-43D9-9E41-743F57318851}.Debug|x86.ActiveCfg = Debug|x64 {A63683B8-097D-43D9-9E41-743F57318851}.Release|x64.ActiveCfg = Release|x64 {A63683B8-097D-43D9-9E41-743F57318851}.Release|x64.Build.0 = Release|x64 {A63683B8-097D-43D9-9E41-743F57318851}.Release|x86.ActiveCfg = Release|x64 + {A63683B8-097D-43D9-9E41-743F57318851}.Static|x64.ActiveCfg = Release|x64 + {A63683B8-097D-43D9-9E41-743F57318851}.Static|x64.Build.0 = Release|x64 + {A63683B8-097D-43D9-9E41-743F57318851}.Static|x86.ActiveCfg = Release|x64 + {A63683B8-097D-43D9-9E41-743F57318851}.Static|x86.Build.0 = Release|x64 {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Debug|x64.ActiveCfg = Debug|x64 {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Debug|x64.Build.0 = Debug|x64 {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Debug|x86.ActiveCfg = Debug|x64 {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Release|x64.ActiveCfg = Release|x64 {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Release|x64.Build.0 = Release|x64 {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Release|x86.ActiveCfg = Release|x64 + {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Static|x64.ActiveCfg = Release|x64 + {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Static|x64.Build.0 = Release|x64 + {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Static|x86.ActiveCfg = Release|x64 + {328FBD05-9CCC-4096-8ABE-0CBAB5E2D6AD}.Static|x86.Build.0 = Release|x64 {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Debug|x64.ActiveCfg = Debug|x64 {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Debug|x64.Build.0 = Debug|x64 {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Debug|x86.ActiveCfg = Debug|x64 {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Release|x64.ActiveCfg = Release|x64 {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Release|x64.Build.0 = Release|x64 {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Release|x86.ActiveCfg = Release|x64 + {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Static|x64.ActiveCfg = Release|x64 + {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Static|x64.Build.0 = Release|x64 + {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Static|x86.ActiveCfg = Release|x64 + {388E9131-0CAB-4C42-869A-D19F6EB2B757}.Static|x86.Build.0 = Release|x64 {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Debug|x64.ActiveCfg = Debug|x64 {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Debug|x64.Build.0 = Debug|x64 {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Debug|x86.ActiveCfg = Debug|x64 {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Release|x64.ActiveCfg = Release|x64 {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Release|x64.Build.0 = Release|x64 {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Release|x86.ActiveCfg = Release|x64 + {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Static|x64.ActiveCfg = Release|x64 + {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Static|x64.Build.0 = Release|x64 + {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Static|x86.ActiveCfg = Release|x64 + {C09C31DC-01C2-4ED9-8AF4-93AFFB0ACDC7}.Static|x86.Build.0 = Release|x64 {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Debug|x64.ActiveCfg = Debug|x64 {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Debug|x64.Build.0 = Debug|x64 {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Debug|x86.ActiveCfg = Debug|x64 {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Release|x64.ActiveCfg = Release|x64 {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Release|x64.Build.0 = Release|x64 {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Release|x86.ActiveCfg = Release|x64 + {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Static|x64.ActiveCfg = Release|x64 + {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Static|x64.Build.0 = Release|x64 + {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Static|x86.ActiveCfg = Release|x64 + {E3879CAF-AAC0-4E34-9753-544C26F20D6A}.Static|x86.Build.0 = Release|x64 {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Debug|x64.ActiveCfg = Debug|x64 {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Debug|x64.Build.0 = Debug|x64 {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Debug|x86.ActiveCfg = Debug|x64 {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Release|x64.ActiveCfg = Release|x64 {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Release|x64.Build.0 = Release|x64 {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Release|x86.ActiveCfg = Release|x64 + {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Static|x64.ActiveCfg = Release|x64 + {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Static|x64.Build.0 = Release|x64 + {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Static|x86.ActiveCfg = Release|x64 + {86415C93-49E4-4F97-AA5D-7DC68E56D9C1}.Static|x86.Build.0 = Release|x64 {A2499166-21D9-441E-BC13-E3E0607E1A15}.Debug|x64.ActiveCfg = Debug|x64 {A2499166-21D9-441E-BC13-E3E0607E1A15}.Debug|x64.Build.0 = Debug|x64 {A2499166-21D9-441E-BC13-E3E0607E1A15}.Debug|x86.ActiveCfg = Debug|x64 {A2499166-21D9-441E-BC13-E3E0607E1A15}.Release|x64.ActiveCfg = Release|x64 {A2499166-21D9-441E-BC13-E3E0607E1A15}.Release|x64.Build.0 = Release|x64 {A2499166-21D9-441E-BC13-E3E0607E1A15}.Release|x86.ActiveCfg = Release|x64 + {A2499166-21D9-441E-BC13-E3E0607E1A15}.Static|x64.ActiveCfg = Release|x64 + {A2499166-21D9-441E-BC13-E3E0607E1A15}.Static|x64.Build.0 = Release|x64 + {A2499166-21D9-441E-BC13-E3E0607E1A15}.Static|x86.ActiveCfg = Release|x64 + {A2499166-21D9-441E-BC13-E3E0607E1A15}.Static|x86.Build.0 = Release|x64 {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Debug|x64.ActiveCfg = Debug|x64 {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Debug|x64.Build.0 = Debug|x64 {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Debug|x86.ActiveCfg = Debug|Win32 @@ -2206,6 +2880,10 @@ Global {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Release|x64.Build.0 = Release|x64 {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Release|x86.ActiveCfg = Release|Win32 {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Release|x86.Build.0 = Release|Win32 + {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Static|x64.ActiveCfg = Static|x64 + {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Static|x64.Build.0 = Static|x64 + {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Static|x86.ActiveCfg = Static|Win32 + {AF915A40-0A9E-4AD1-995C-E0D94DB353A4}.Static|x86.Build.0 = Static|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From c70a2767205db5159759739c77a4be9e9e0b6639 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 16 Jan 2023 13:49:50 +0000 Subject: [PATCH 206/222] Fix license typo --- Packaging/Max/FrameLib/license.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packaging/Max/FrameLib/license.md b/Packaging/Max/FrameLib/license.md index 1d962ad2e..1fc69d8c9 100644 --- a/Packaging/Max/FrameLib/license.md +++ b/Packaging/Max/FrameLib/license.md @@ -1,4 +1,4 @@ -FrameLib Ñ License +FrameLib License ======== Copyright (c) 2017-2022 Alex Harker From 359f6f0713d7755395b54f923a465b6b7d47cf07 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 16 Jan 2023 13:50:27 +0000 Subject: [PATCH 207/222] Fix pd build of fl.register~ --- FrameLib_PD_Objects/framelib_pd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_PD_Objects/framelib_pd.cpp b/FrameLib_PD_Objects/framelib_pd.cpp index c7075dfae..98e595d78 100644 --- a/FrameLib_PD_Objects/framelib_pd.cpp +++ b/FrameLib_PD_Objects/framelib_pd.cpp @@ -652,7 +652,7 @@ PD_API void framelib_pd_setup(void) // Storage FrameLib_PDClass_Expand::makeClass("fl.recall~"); - FrameLib_PDClass_Expand::makeClass("fl.register~"); + FrameLib_PDClass_Expand::makeClass("fl.register~"); FrameLib_PDClass_Expand::makeClass("fl.store~"); // Streaming From f2ff291e3fbe9a751af1a1955c45e7f8450851be Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Mon, 16 Jan 2023 13:53:19 +0000 Subject: [PATCH 208/222] Build the libraries locally for export when building optimised --- framelib.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/framelib.xcodeproj/project.pbxproj b/framelib.xcodeproj/project.pbxproj index 3e38f7e82..ef63c684b 100644 --- a/framelib.xcodeproj/project.pbxproj +++ b/framelib.xcodeproj/project.pbxproj @@ -23038,6 +23038,7 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + DSTROOT = build/; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; EXECUTABLE_PREFIX = lib; @@ -23049,6 +23050,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = lib/; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -23077,6 +23079,8 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_LOCATION = YES; + DSTROOT = build/; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -23087,6 +23091,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = lib/; LLVM_LTO = YES; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -23116,6 +23121,8 @@ CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_LOCATION = YES; + DSTROOT = build/; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -23126,6 +23133,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = lib/; LLVM_LTO = YES; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -25129,6 +25137,7 @@ CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + DSTROOT = build/; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; EXECUTABLE_PREFIX = lib; @@ -25141,6 +25150,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = lib/; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -25178,6 +25188,8 @@ CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_LOCATION = YES; + DSTROOT = build/; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -25189,6 +25201,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = lib/; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -25226,6 +25239,8 @@ CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_LOCATION = YES; + DSTROOT = build/; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; @@ -25237,6 +25252,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + INSTALL_PATH = lib/; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; From ecbcbe942936525856ee736e74f3d3d6344c7c8e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 11 Feb 2023 13:30:00 +0000 Subject: [PATCH 209/222] Update ibuffer access --- FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp | 4 ++-- FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp index 8b99b35f3..39f2d71ea 100755 --- a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp +++ b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp @@ -191,12 +191,12 @@ void ibuffer_read_edges(const ibuffer_data& buffer, double *out, const double *p ibuffer_read_format_edges(buffer, out, positions, n_samps, chan, mul, interp, edges, bound); } -void ibuffer_read_edges(const ibuffer_data& buffer, float *out, const double *positions, intptr_t n_samps, long chan, float mul, InterpType interp, EdgeMode edges, bool bound, float pad_lo, float pad_hi) +void ibuffer_read_edges(const ibuffer_data& buffer, float *out, const double *positions, intptr_t n_samps, long chan, float mul, InterpType interp, EdgeMode edges, bool bound) { ibuffer_read_format_edges(buffer, out, positions, n_samps, chan, mul, interp, edges, bound); } -void ibuffer_read_edges(const ibuffer_data& buffer, float *out, const float *positions, intptr_t n_samps, long chan, float mul, InterpType interp, EdgeMode edges, bool bound, float pad_lo, float pad_hi) +void ibuffer_read_edges(const ibuffer_data& buffer, float *out, const float *positions, intptr_t n_samps, long chan, float mul, InterpType interp, EdgeMode edges, bool bound) { ibuffer_read_format_edges(buffer, out, positions, n_samps, chan, mul, interp, edges, bound); } diff --git a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp index 5455ae65e..0ce3bc9e7 100755 --- a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp +++ b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp @@ -152,7 +152,7 @@ static inline double ibuffer_get_samp(const ibuffer_data& buffer, intptr_t offse // Interpolation Attributes template -t_max_err ibuf_interp_attribute_set(T *x, t_attr *a, long argc, t_atom *argv) +t_max_err ibuf_interp_attribute_set(T *x, t_attr * /* attr */, long argc, t_atom *argv) { if (!argc) { @@ -188,7 +188,7 @@ t_max_err ibuf_interp_attribute_set(T *x, t_attr *a, long argc, t_atom *argv) } template -t_max_err ibuf_interp_attribute_get(T *x, t_object *attr, long *argc, t_atom **argv) +t_max_err ibuf_interp_attribute_get(T *x, t_object */* attr */, long *argc, t_atom **argv) { if (argc && argv) { From 4ed7080ab23f8f701de097210fe5344f0ac18bf1 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 11 Feb 2023 14:24:08 +0000 Subject: [PATCH 210/222] Updates from HISSTools_Library --- .../HISSTools_FFT/HISSTools_FFT_Core.h | 2 +- FrameLib_Dependencies/RandomGenerator.hpp | 3 +- FrameLib_Dependencies/SIMDSupport.hpp | 41 ++++++++++--------- FrameLib_Dependencies/TableReader.hpp | 4 +- FrameLib_Dependencies/WindowFunctions.hpp | 6 ++- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h index 7e7d90eff..2a06e2139 100755 --- a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h +++ b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h @@ -376,7 +376,7 @@ namespace hisstools_fft_impl{ struct static_for { template - void operator()(Vector4x &result, const Vector4x &, const Vector4x &, Fn const&) const {} + void operator()(Vector4x & /* result */, const Vector4x & /* a */, const Vector4x & /* b */ , Fn const& /* fn */) const {} }; template diff --git a/FrameLib_Dependencies/RandomGenerator.hpp b/FrameLib_Dependencies/RandomGenerator.hpp index 7d4e001a0..acba063e1 100755 --- a/FrameLib_Dependencies/RandomGenerator.hpp +++ b/FrameLib_Dependencies/RandomGenerator.hpp @@ -12,7 +12,8 @@ namespace random_generators // Basic CMWC Generator // A complementary modulo with carry algorithm (proposed by George Marsaglia) - // Details can be found in Marsaglia, G. (2003). "Random number generators". Journal of Modern Applied Statistical Methods 2 + // Details can be found in: + // Marsaglia, G. (2003). "Random number generators". Journal of Modern Applied Statistical Methods 2 // See - http://digitalcommons.wayne.edu/cgi/viewcontent.cgi?article=1725&context=jmasm // The memory requirement is 34 unsigned 32 bit integers (can be altered using cmwc_lag_size) diff --git a/FrameLib_Dependencies/SIMDSupport.hpp b/FrameLib_Dependencies/SIMDSupport.hpp index 1ae92dc68..00383c351 100755 --- a/FrameLib_Dependencies/SIMDSupport.hpp +++ b/FrameLib_Dependencies/SIMDSupport.hpp @@ -125,8 +125,11 @@ void deallocate_aligned(T *ptr) template T *allocate_aligned(size_t size) { - void *mem; - posix_memalign(&mem, SIMDLimits::byte_width, size * sizeof(T)); + void *mem = nullptr; + + if (posix_memalign(&mem, SIMDLimits::byte_width, size * sizeof(T))) + return nullptr; + return static_cast(mem); } @@ -363,29 +366,29 @@ struct SizedVector static_iterate()(result, a, b, fn); } - void load(SV &vector, const T *array) + void load(SV &v, const T *array) { - vector.mData[First] = VecType(array + First * vec_size); - static_iterate().load(vector, array); + v.mData[First] = VecType(array + First * vec_size); + static_iterate().load(v, array); } - void store(T *array, const SV& vector) + void store(T *array, const SV& v) { - vector.mData[First].store(array + First * vec_size); - static_iterate().store(array, vector); + v.mData[First].store(array + First * vec_size); + static_iterate().store(array, v); } - void set(SV &vector, const T& a) + void set(SV &v, const T& a) { - vector.mData[First] = a; - static_iterate().set(vector, a); + v.mData[First] = a; + static_iterate().set(v, a); } template - void set(SV &vector, const SizedVector& a) + void set(SV &v, const SizedVector& a) { - vector.mData[First] = a.mData[First]; - static_iterate().set(vector, a); + v.mData[First] = a.mData[First]; + static_iterate().set(v, a); } }; @@ -395,14 +398,14 @@ struct SizedVector struct static_iterate { template - void operator()(SV &result, const SV& a, const SV& b, Fn const& fn) const {} + void operator()(SV & /*result*/, const SV& /* a */, const SV& /* b */, Fn const& /* fn */) const {} - void load(SV &vector, const T *array) {} - void store(T *array, const SV& vector) {} - void set(SV &vector, const T& a) {} + void load(SV & /* v */, const T * /* array */) {} + void store(T * /* array */, const SV& /* v */) {} + void set(SV & /* v */, const T& /* a */) {} template - void set(SV &vector, const SizedVector& a) {} + void set(SV & /* v */, const SizedVector& /* a */) {} }; // Op template diff --git a/FrameLib_Dependencies/TableReader.hpp b/FrameLib_Dependencies/TableReader.hpp index c318e5637..ca9df6d37 100644 --- a/FrameLib_Dependencies/TableReader.hpp +++ b/FrameLib_Dependencies/TableReader.hpp @@ -27,7 +27,7 @@ struct table_fetcher table_fetcher(intptr_t length, double scale_val) : size(length), scale(scale_val) {} template - void split(U position, intptr_t& idx, V& fract, int N) + void split(U position, intptr_t& idx, V& fract, int /* N */) { idx = static_cast(std::floor(position)); fract = static_cast(position - static_cast(idx)); @@ -35,7 +35,7 @@ struct table_fetcher intptr_t limit() { return size - 1; } - void prepare(InterpType interpolation) {} + void prepare(InterpType /* interpolation */) {} const intptr_t size; const double scale; diff --git a/FrameLib_Dependencies/WindowFunctions.hpp b/FrameLib_Dependencies/WindowFunctions.hpp index e98cb7b7b..64b60fee6 100755 --- a/FrameLib_Dependencies/WindowFunctions.hpp +++ b/FrameLib_Dependencies/WindowFunctions.hpp @@ -25,7 +25,7 @@ namespace window_functions struct params { - constexpr params(double A0 = 0.0, double A1 = 0.0, double A2 = 0.0, double A3 = 0.0, double A4 = 0.0, double exp = 1.0) + constexpr params(double A0 = 0, double A1 = 0, double A2 = 0, double A3 = 0, double A4 = 0, double exp = 1) : a0(A0), a1(A1), a2(A2), a3(A3), a4(A4), exponent(exp) {} constexpr params(const double *param_array, int N, double exp) @@ -350,6 +350,8 @@ namespace window_functions template void inline generate(T *window, uint32_t N, uint32_t begin, uint32_t end, const params& p) { + constexpr int max_int = std::numeric_limits().max(); + auto sq = [&](double x) { return x * x; }; auto cb = [&](double x) { return x * x * x; }; auto qb = [&](double x) { return sq(sq(x)); }; @@ -414,7 +416,7 @@ namespace window_functions for (uint32_t i = begin; i < end; i++) *window++ = toType(qb(Func(i, N, p))); } - else if (p.exponent > 0 && p.exponent <= std::numeric_limits().max() && p.exponent == std::floor(p.exponent)) + else if (p.exponent > 0 && p.exponent <= max_int && p.exponent == std::floor(p.exponent)) { int exponent = static_cast(p.exponent); From 213d09fd17ba380eeaf5f0ddc24d2f140730b90b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 11 Feb 2023 14:24:27 +0000 Subject: [PATCH 211/222] Don't need execute permissions on source files --- FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp | 0 FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.h | 0 FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h | 0 FrameLib_Dependencies/RandomGenerator.hpp | 0 FrameLib_Dependencies/SIMDSupport.hpp | 0 FrameLib_Dependencies/WindowFunctions.hpp | 0 FrameLib_Dependencies/convhull_3d/README.md | 0 FrameLib_Dependencies/tlsf/README.md | 0 FrameLib_Dependencies/tlsf/tlsf.c | 0 FrameLib_Dependencies/tlsf/tlsf.h | 0 10 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp mode change 100755 => 100644 FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.h mode change 100755 => 100644 FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h mode change 100755 => 100644 FrameLib_Dependencies/RandomGenerator.hpp mode change 100755 => 100644 FrameLib_Dependencies/SIMDSupport.hpp mode change 100755 => 100644 FrameLib_Dependencies/WindowFunctions.hpp mode change 100755 => 100644 FrameLib_Dependencies/convhull_3d/README.md mode change 100755 => 100644 FrameLib_Dependencies/tlsf/README.md mode change 100755 => 100644 FrameLib_Dependencies/tlsf/tlsf.c mode change 100755 => 100644 FrameLib_Dependencies/tlsf/tlsf.h diff --git a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.cpp old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.h b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT.h old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h b/FrameLib_Dependencies/HISSTools_FFT/HISSTools_FFT_Core.h old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/RandomGenerator.hpp b/FrameLib_Dependencies/RandomGenerator.hpp old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/SIMDSupport.hpp b/FrameLib_Dependencies/SIMDSupport.hpp old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/WindowFunctions.hpp b/FrameLib_Dependencies/WindowFunctions.hpp old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/convhull_3d/README.md b/FrameLib_Dependencies/convhull_3d/README.md old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/tlsf/README.md b/FrameLib_Dependencies/tlsf/README.md old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/tlsf/tlsf.c b/FrameLib_Dependencies/tlsf/tlsf.c old mode 100755 new mode 100644 diff --git a/FrameLib_Dependencies/tlsf/tlsf.h b/FrameLib_Dependencies/tlsf/tlsf.h old mode 100755 new mode 100644 From c8a2514e22aaeee2ab533a18101af063e171f63e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 11 Feb 2023 14:26:08 +0000 Subject: [PATCH 212/222] Execute permissions are not needed for source files --- FrameLib_Max_Objects/Buffer/ibuffer/ibuffer.hpp | 0 FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp | 0 FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 FrameLib_Max_Objects/Buffer/ibuffer/ibuffer.hpp mode change 100755 => 100644 FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp mode change 100755 => 100644 FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp diff --git a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer.hpp b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer.hpp old mode 100755 new mode 100644 diff --git a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.cpp old mode 100755 new mode 100644 diff --git a/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp b/FrameLib_Max_Objects/Buffer/ibuffer/ibuffer_access.hpp old mode 100755 new mode 100644 From 322ff697c30a052185aebe7537f6553c2b36ebe6 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 15 Feb 2023 23:15:15 +0000 Subject: [PATCH 213/222] Correct typo --- FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h b/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h index b0fcd5fd7..abecf4c82 100644 --- a/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h +++ b/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h @@ -3,7 +3,7 @@ #define FRAMELIB_PADDEDVECTOR_H // A class to temporarily wrap a vector and access with end padding (extending the last value) -// A detault value will be used if the input vector is empty +// A default value will be used if the input vector is empty // The class does not own the memory of the vector class PaddedVector From b0ad3bb636bace7ce4572b9a6c50521e118a1968 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Wed, 15 Feb 2023 23:46:37 +0000 Subject: [PATCH 214/222] Complete comment --- FrameLib_Objects/Common_Utilities/FrameLib_RingBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Objects/Common_Utilities/FrameLib_RingBuffer.h b/FrameLib_Objects/Common_Utilities/FrameLib_RingBuffer.h index 066273b92..85cac0b01 100644 --- a/FrameLib_Objects/Common_Utilities/FrameLib_RingBuffer.h +++ b/FrameLib_Objects/Common_Utilities/FrameLib_RingBuffer.h @@ -17,7 +17,7 @@ class FrameLib_RingBuffer : private FrameLib_VectorSet {} // N.B. Valid frames are those written since the last resize or reset - // This allows for code to avoid needing to clear on resize, thus + // This allows for code to avoid needing to clear on resize, thus saving CPU // Getters From de48e47a3b62832869a04215136c4ed9c73110a2 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 18 Feb 2023 00:16:16 +0000 Subject: [PATCH 215/222] PaddedVector tests should be consistent (and based on size, rather than the pointer) --- FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h b/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h index abecf4c82..ae8bd5871 100644 --- a/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h +++ b/FrameLib_Objects/Common_Utilities/FrameLib_PaddedVector.h @@ -12,7 +12,7 @@ class PaddedVector public: PaddedVector(const double *input, unsigned long size, double defaultValue) - : mVector(input ? input : &mDefault), mLimit(size ? size - 1 : 0), mDefault(defaultValue) + : mVector(size ? input : &mDefault), mLimit(size ? size - 1 : 0), mDefault(defaultValue) {} double operator[](unsigned long pos) const From 1343ab8ff15b41eff98d4963396936b43091b97b Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Sat, 18 Feb 2023 00:16:29 +0000 Subject: [PATCH 216/222] Ensure fixed inputs are nullptr if the size is zero --- FrameLib_Framework/FrameLib_DSP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FrameLib_Framework/FrameLib_DSP.cpp b/FrameLib_Framework/FrameLib_DSP.cpp index 422ee8e57..b2ebaead6 100644 --- a/FrameLib_Framework/FrameLib_DSP.cpp +++ b/FrameLib_Framework/FrameLib_DSP.cpp @@ -50,7 +50,7 @@ void FrameLib_DSP::setFixedInput(unsigned long idx, const double *input, unsigne if (mInputs[idx].mFixedInput) delete[] mInputs[idx].mFixedInput; - mInputs[idx].mFixedInput = new double[size]; + mInputs[idx].mFixedInput = size ? new double[size] : nullptr; if (mInputs[idx].mFixedInput) { From 88cc7fecdff37207c51b2d667131f2fe3a3690d8 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Thu, 20 Apr 2023 12:24:38 +0100 Subject: [PATCH 217/222] Set file permissions to remove execute --- FrameLib_Max_Objects/Common/Config_FrameLib_Max.xcconfig | 0 FrameLib_Max_Objects/Vector/fl.reverse~.cpp | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 FrameLib_Max_Objects/Common/Config_FrameLib_Max.xcconfig mode change 100755 => 100644 FrameLib_Max_Objects/Vector/fl.reverse~.cpp diff --git a/FrameLib_Max_Objects/Common/Config_FrameLib_Max.xcconfig b/FrameLib_Max_Objects/Common/Config_FrameLib_Max.xcconfig old mode 100755 new mode 100644 diff --git a/FrameLib_Max_Objects/Vector/fl.reverse~.cpp b/FrameLib_Max_Objects/Vector/fl.reverse~.cpp old mode 100755 new mode 100644 From 0aca2ecdf5248186a6a65b92b06e4a3be685df7e Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 23 Jun 2023 07:08:52 +0100 Subject: [PATCH 218/222] Type fix to allow (correct) negative indexing into padding --- FrameLib_Objects/Vector/FrameLib_Peaks.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp index 9c3b8bf4b..4585a2f1f 100644 --- a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp +++ b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp @@ -114,7 +114,7 @@ void createEdges(double *output, T data, unsigned long size, int edgeSize) // Peak Finding -template +template unsigned long findPeaks(unsigned long *peaks, const double *data, unsigned long size, double threshold) { unsigned long nPeaks = 0; @@ -127,13 +127,13 @@ unsigned long findPeaks(unsigned long *peaks, const double *data, unsigned long } template -bool checkPeak(const double *data, double threshold, unsigned long i) +bool checkPeak(const double *data, double threshold, long i) { return checkPeak(data, threshold, i) && data[i] > data[i-N] && data[i] > data[i+N]; } template <> -bool checkPeak<1>(const double *data, double threshold, unsigned long i) +bool checkPeak<1>(const double *data, double threshold, long i) { return data[i] > threshold && data[i] > data[i-1] && data[i] > data[i+1]; } From f63390590c9df0c340d5047b318543ab4eac5691 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 23 Jun 2023 08:22:13 +0100 Subject: [PATCH 219/222] Correct argument numbering (and documentation) --- FrameLib_Objects/Vector/FrameLib_Peaks.cpp | 4 ++-- .../docs/refpages/framelib-ref/fl.peaks~.maxref.xml | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp index 4585a2f1f..5299126fb 100644 --- a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp +++ b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp @@ -35,11 +35,11 @@ FrameLib_Peaks::FrameLib_Peaks(FrameLib_Context context, const FrameLib_Paramete mParameters.addEnumItem(kParabolic, "parabolic", true); mParameters.addEnumItem(kParabolicLog, "parabolic_log"); - mParameters.addEnum(kBoundaries, "boundaries", 4); + mParameters.addEnum(kBoundaries, "boundaries", 5); mParameters.addEnumItem(kMinimum, "minimum"); mParameters.addEnumItem(kMidpoint, "midpoint"); - mParameters.addBool(kAlwaysDetect, "always_detect", true, 5); + mParameters.addBool(kAlwaysDetect, "always_detect", true, 6); mParameters.set(serialisedParameters); diff --git a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.peaks~.maxref.xml b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.peaks~.maxref.xml index d36241dbe..1f79f2eb9 100644 --- a/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.peaks~.maxref.xml +++ b/Packaging/Max/FrameLib/docs/refpages/framelib-ref/fl.peaks~.maxref.xml @@ -90,6 +90,14 @@ This argument sets the edges parameter:

Sets the edge behaviour for peak detection:

[0] - pad - values beyond the edges of the input are read as the padding value.[1] - extend - the edge values are extended infinitely in either direction.[2] - wrap - values are read as wrapped or cyclical.[3] - fold - values are folded at edges without repetition of the edge values.[4] - mirror - values are mirrored at edges with the edge values repeated.

(default: pad) + + + Sets the method for refining peak values + + + This argument sets the refine parameter:

Sets the method for refining peak values:

[0] - off - return the peak value without refinement.[1] - parabolic - apply parabolic interpolation to the three values around the peak.[2] - parabolic_log - apply parabolic interpolation to the log of the three values around the peak.

Note that parabolic_log is suitable for interpolating linear amplitudes.

(default: parabolic) + + Sets the method for selecting the boundaries between peaks From dbabad3a9316d3167052acb0aedf2c3d43bffc77 Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 30 Jun 2023 17:57:23 +0100 Subject: [PATCH 220/222] Further type fixes for issues with negative indexing --- FrameLib_Objects/Vector/FrameLib_Peaks.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp index 5299126fb..787fe9bab 100644 --- a/FrameLib_Objects/Vector/FrameLib_Peaks.cpp +++ b/FrameLib_Objects/Vector/FrameLib_Peaks.cpp @@ -140,11 +140,11 @@ bool checkPeak<1>(const double *data, double threshold, long i) // Refinement -template +template void refinePeaks(double *positions, double *values, const double *data, unsigned long *peaks, unsigned long nPeaks) { for (unsigned long i = 0; i < nPeaks; i++) - Func(positions, values, data, i, peaks[i]); + Func(positions, values, data, i, static_cast(peaks[i])); } void parabolicInterp(double& position, double& value, double idx, double vm1, double v_0, double vp1) @@ -156,18 +156,18 @@ void parabolicInterp(double& position, double& value, double idx, double vm1, do value = v_0 - (0.25 * (vm1 - vp1) * correction); } -void refineNone(double *positions, double *values, const double *data, unsigned long peak, unsigned long idx) +void refineNone(double *positions, double *values, const double *data, unsigned long peak, long idx) { positions[peak] = idx; values[peak] = data[idx]; } -void refineParabolic(double *positions, double *values, const double *data, unsigned long peak, unsigned long idx) +void refineParabolic(double *positions, double *values, const double *data, unsigned long peak, long idx) { parabolicInterp(positions[peak], values[peak], idx, data[idx-1], data[idx], data[idx+1]); } -void refineParabolicLog(double *positions, double *values, const double *data, unsigned long peak, unsigned long idx) +void refineParabolicLog(double *positions, double *values, const double *data, unsigned long peak, long idx) { // Take log values (avoiding values that are too low) - doesn't work for negative values // N.B. we assume a max of -80dB difference between samples to prevent extreme overshoot From f534de5061948a996f6ee106618160f925011f79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:15:45 +0000 Subject: [PATCH 221/222] Bump actions/download-artifact from 3 to 4.1.7 in /.github/workflows Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/distribution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index 28da0e1ac..aea75306e 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -162,7 +162,7 @@ jobs: - name: Build max documentation run: xcodebuild -project 'framelib.xcodeproj' -scheme 'framelib Max Documentation' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES - name: Download builds - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4.1.7 with: path: ../build/ - name: Move max externals into place From 9baedd00767ac287eddad7b0676e51bf9827561d Mon Sep 17 00:00:00 2001 From: Alex Harker Date: Fri, 6 Sep 2024 12:38:03 +0100 Subject: [PATCH 222/222] Update to compatible version of upload-artifact --- .github/workflows/distribution.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/distribution.yml b/.github/workflows/distribution.yml index aea75306e..bf66d2b62 100644 --- a/.github/workflows/distribution.yml +++ b/.github/workflows/distribution.yml @@ -16,7 +16,7 @@ jobs: - name: Build mac max externals run: xcodebuild -project 'framelib/framelib.xcodeproj' -scheme 'framelib Max (objects build)' -destination 'platform=OS X,arch=x86_64' -configuration Deployment -quiet build CODE_SIGNING_ALLOWED=YES - name: Upload mac build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: build-mac path: framelib/Packaging/Max/FrameLib/externals @@ -37,7 +37,7 @@ jobs: - name: Build win max externals run: msbuild "framelib/framelib.sln" /p:configuration="Release" /p:platform=x64 /t:framelib_objects_max /v:q /clp:ErrorsOnly /nologo /m - name: Upload win build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: build-win path: framelib/Packaging/Max/FrameLib/externals @@ -51,7 +51,7 @@ jobs: cd FrameLib_PD_Objects/ make - name: Upload mac build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: build-mac path: build/*.d_fat @@ -74,7 +74,7 @@ jobs: cd FrameLib_PD_Objects/ make BUILD_TYPE=${{ matrix.type }} - name: Upload linux intel build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: ${{ format('build-linux-intel-{0}', matrix.type) }} path: build/*.pd_linux @@ -107,7 +107,7 @@ jobs: cd FrameLib_PD_Objects/ make NAME_SUFFIX=${{ matrix.type }} - name: Upload linux arm build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: ${{ format('build-win-{0}', matrix.type) }} path: build/*.pd_linux @@ -144,7 +144,7 @@ jobs: unzip pdzipped.zip -d ../../ $MAKE_CMD BUILD_TYPE=${{ matrix.type }} - name: Upload win build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.4.0 with: name: ${{ format('build-win-{0}', matrix.type) }} path: build/*.dll