MSVC only: Error C3203: unspecialized class template ... (works fine on MAC)
-
Can anyone help me fix an apparently simple C++ problem? I know too little about C++ to solve it.
My autogenerated DspNetworks.h compiles fine on MAC, on PC however the compiler issues a lot of errors like such: DspNetwork.h(20,66): error C3203: "Disintegrate": unspecialized class template...
Here is the snippet producing the errors
namespace DspNetwork_impl { // ==============================| Node & Parameter type declarations |============================== template <int NV> using smoothed_parameter_t = wrap::mod<parameter::plain<project::Disintegrate, 0>, control::smoothed_parameter<NV, smoothers::linear_ramp<NV>>>; template <int NV> using smoothed_parameter1_t = wrap::mod<parameter::plain<project::Disintegrate, 2>, control::smoothed_parameter<NV, smoothers::linear_ramp<NV>>>; template <int NV> using smoothed_parameter2_t = wrap::mod<parameter::plain<project::Disintegrate, 3>, control::smoothed_parameter<NV, smoothers::linear_ramp<NV>>>; template <int NV> using split_t = container::split<parameter::empty, wrap::fix<2, smoothed_parameter_t<NV>>, smoothed_parameter1_t<NV>, smoothed_parameter2_t<NV>>;
This file is autogenerated though, so changing it wont do anything as it is overwritten upon compiling the network.
Here is the template thingy that apparently leads to the generation of a faulty DspNetwork.h, so the problem must be in there, everything works if I remove it (apart from not having the wanted third party nodes then, ofc)
#pragma once #include <JuceHeader.h> #include <math.h> #include <set> #include <string> #define __audioeffect__ #define VstInt32 int32_t #define AudioEffect ::airwindows::AirWindowsBase #define AudioEffectX ::airwindows::AirWindowsBase #define audioMasterCallback ::airwindows::SampleRateCallback* #define VstPlugCategory int #define kPlugCategEffect 1 #define kVstMaxProgNameLen 64 #define kVstMaxParamStrLen 64 #define kVstMaxProductStrLen 64 #define kVstMaxVendorStrLen 64 #define vst_strncpy strncpy namespace airwindows { inline auto float2string(float f, char* text, int len) -> void { int decimals = 0; if (std::fabs(f) >= 10.0) { decimals = 1; } else if (std::fabs(f) > 1.0) { decimals = 2; } else { decimals = 3; } juce::String str(f, decimals); str.copyToUTF8(text, (size_t)len); } inline auto int2string(float i, char* text, int len) -> void { juce::String str(i); str.copyToUTF8(text, (size_t)len); } inline auto dB2string(float value, char* text, int maxLen) -> void { if (value <= 0) { vst_strncpy(text, "-oo", (size_t)maxLen); } else { float2string((float)(20. * log10(value)), text, maxLen); } } struct SampleRateCallback { SampleRateCallback() = default; auto getSampleRate() const noexcept -> double { return sampleRate; } double sampleRate{0.0}; }; class AirWindowsBase { public: AirWindowsBase(SampleRateCallback* c, int prog, int param) : numPrograms(prog), numParams(param), callback(c) {} int getNumInputs() { return numInputs; } int getNumOutputs() { return numOutputs; } int getNumParameters() { return numParams; } virtual bool getEffectName(char* name) = 0; virtual VstPlugCategory getPlugCategory() = 0; virtual bool getProductString(char* text) = 0; virtual bool getVendorString(char* text) = 0; virtual VstInt32 getVendorVersion() = 0; virtual void processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames) = 0; virtual void processDoubleReplacing(double** inputs, double** outputs, VstInt32 sampleFrames) = 0; virtual void getProgramName(char* name) = 0; virtual void setProgramName(char* name) = 0; virtual VstInt32 getChunk(void** data, bool isPreset) { juce::ignoreUnused(data, isPreset); return 0; }; virtual VstInt32 setChunk(void* data, VstInt32 byteSize, bool isPreset) { juce::ignoreUnused(data, byteSize, isPreset); return 0; }; virtual float getParameter(VstInt32 index) { juce::ignoreUnused(index); return 0; } virtual void setParameter(VstInt32 index, float value) { juce::ignoreUnused(index, value); } virtual void getParameterLabel(VstInt32 index, char* text) { juce::ignoreUnused(index, text); } virtual void getParameterName(VstInt32 index, char* text) { juce::ignoreUnused(index, text); } virtual void getParameterDisplay(VstInt32 index, char* text) { juce::ignoreUnused(index, text); } virtual VstInt32 canDo(char* text) = 0; protected: void setNumInputs(int numIn) { numInputs = numIn; } void setNumOutputs(int numOut) { numOutputs = numOut; } void setUniqueID(int) {} void canProcessReplacing() {} void canDoubleReplacing() {} void programsAreChunks(bool) {} int numInputs = 0, numOutputs = 0, numPrograms = 0, numParams = 0; SampleRateCallback* callback; double getSampleRate() { return callback->getSampleRate(); } }; } // namespace airwindows #define DECLARE_AIRWINDOWS_NODE(ClassName, Namespace) template <int NV> struct ClassName final : public data::base { SNEX_NODE(ClassName); struct MetadataClass { SN_NODE_ID(#ClassName); }; static constexpr bool isModNode() { return false; }; static constexpr bool isPolyphonic() { return NV > 1; }; static constexpr bool hasTail() { return false; }; static constexpr bool isSuspendedOnSilence() { return false; }; static constexpr int getFixChannelAmount() { return 2; }; static constexpr int NumTables = 0; static constexpr int NumSliderPacks = 0; static constexpr int NumAudioFiles = 0; static constexpr int NumFilters = 0; static constexpr int NumDisplayBuffers = 0; void prepare(PrepareSpecs specs) { _sampleRateSource.sampleRate = specs.sampleRate; _tmp.setSize(specs.numChannels, specs.blockSize); } void reset() {} void handleHiseEvent(HiseEvent& e) {} template <typename T> void process(T& data) { auto buffer = juce::AudioBuffer<float>(data.getRawChannelPointers(), data.getNumChannels(), data.getNumSamples()); processInternal(buffer); } template <typename T> void processFrame(T& data) { auto** ptr = (float**)alloca(data.size() * sizeof(float*)); for (int i = 0; i < data.size(); i++) { ptr[i] = data.begin() + i; } auto buffer = juce::AudioBuffer<float>(ptr, data.size(), 1); processInternal(buffer); } auto processInternal(juce::AudioBuffer<float>& buffer) -> void { _tmp.makeCopyOf(buffer); _engine.processReplacing(_tmp.getArrayOfWritePointers(), buffer.getArrayOfWritePointers(), buffer.getNumSamples()); } int handleModulation(double& value) { return 0; } void setExternalData(ExternalData const& data, int index) {} template <int P> void setParameter(double v) { _engine.setParameter(P, static_cast<float>(v)); } void createParameters(ParameterDataList& data) { for (auto i{0}; i < airwindows::Namespace::kNumParameters; ++i) { char name[kVstMaxParamStrLen]{}; _engine.getParameterName(i, name); auto parameter = parameter::data(name, {0.0, 1.0}); registerCallback(parameter, i); parameter.setDefaultValue(_engine.getParameter(i)); data.add(std::move(parameter)); } } private : template <typename Param> auto registerCallback(Param& parameter, int i) -> void { switch (i) { case 0: registerCallback<0>(parameter); break; case 1: registerCallback<1>(parameter); break; case 2: registerCallback<2>(parameter); break; case 3: registerCallback<3>(parameter); break; case 4: registerCallback<4>(parameter); break; case 5: registerCallback<5>(parameter); break; case 6: registerCallback<6>(parameter); break; case 7: registerCallback<7>(parameter); break; case 8: registerCallback<8>(parameter); break; case 9: registerCallback<9>(parameter); break; case 10: registerCallback<10>(parameter); break; case 11: registerCallback<11>(parameter); break; case 12: registerCallback<12>(parameter); break; case 13: registerCallback<13>(parameter); break; case 14: registerCallback<14>(parameter); break; case 15: registerCallback<15>(parameter); break; case 16: registerCallback<16>(parameter); break; case 17: registerCallback<17>(parameter); break; case 18: registerCallback<18>(parameter); break; case 19: registerCallback<19>(parameter); break; case 20: registerCallback<20>(parameter); break; case 21: registerCallback<21>(parameter); break; case 22: registerCallback<22>(parameter); break; case 23: registerCallback<23>(parameter); break; case 24: registerCallback<24>(parameter); break; default: break; } jassert(false); } airwindows::SampleRateCallback _sampleRateSource{}; airwindows::Namespace::ClassName _engine{&_sampleRateSource}; juce::AudioBuffer<float> _tmp; }
-
@Morphoice said in MSVC only: Error C3203: unspecialized class template ... (works fine on MAC):
so the problem must be in there,
I don't see the word "Disintegrate" in that code so the problem isn't in there. Find where the Disintegrate class is being declared.
Edit: Oh I see, that's the name of your network? So the problem is perhaps unrelated to air windows.
Send me your project, I'm curious.
-
@Morphoice said in MSVC only: Error C3203: unspecialized class template ... (works fine on MAC):
#pragma once #include <JuceHeader.h> #include <math.h> #include <set> #include <string> #define __audioeffect__ #define VstInt32 int32_t #define AudioEffect ::airwindows::AirWindowsBase #define AudioEffectX ::airwindows::AirWindowsBase #define audioMasterCallback ::airwindows::SampleRateCallback* #define VstPlugCategory int #define kPlugCategEffect 1 #define kVstMaxProgNameLen 64 #define kVstMaxParamStrLen 64 #define kVstMaxProductStrLen 64 #define kVstMaxVendorStrLen 64 #define vst_strncpy strncpy namespace airwindows { inline auto float2string(float f, char* text, int len) -> void { int decimals = 0; if (std::fabs(f) >= 10.0) { decimals = 1; } else if (std::fabs(f) > 1.0) { decimals = 2; } else { decimals = 3; } juce::String str(f, decimals); str.copyToUTF8(text, (size_t)len); } inline auto int2string(float i, char* text, int len) -> void { juce::String str(i); str.copyToUTF8(text, (size_t)len); } inline auto dB2string(float value, char* text, int maxLen) -> void { if (value <= 0) { vst_strncpy(text, "-oo", (size_t)maxLen); } else { float2string((float)(20. * log10(value)), text, maxLen); } } struct SampleRateCallback { SampleRateCallback() = default; auto getSampleRate() const noexcept -> double { return sampleRate; } double sampleRate{0.0}; }; class AirWindowsBase { public: AirWindowsBase(SampleRateCallback* c, int prog, int param) : numPrograms(prog), numParams(param), callback(c) {} int getNumInputs() { return numInputs; } int getNumOutputs() { return numOutputs; } int getNumParameters() { return numParams; } virtual bool getEffectName(char* name) = 0; virtual VstPlugCategory getPlugCategory() = 0; virtual bool getProductString(char* text) = 0; virtual bool getVendorString(char* text) = 0; virtual VstInt32 getVendorVersion() = 0; virtual void processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames) = 0; virtual void processDoubleReplacing(double** inputs, double** outputs, VstInt32 sampleFrames) = 0; virtual void getProgramName(char* name) = 0; virtual void setProgramName(char* name) = 0; virtual VstInt32 getChunk(void** data, bool isPreset) { juce::ignoreUnused(data, isPreset); return 0; }; virtual VstInt32 setChunk(void* data, VstInt32 byteSize, bool isPreset) { juce::ignoreUnused(data, byteSize, isPreset); return 0; }; virtual float getParameter(VstInt32 index) { juce::ignoreUnused(index); return 0; } virtual void setParameter(VstInt32 index, float value) { juce::ignoreUnused(index, value); } virtual void getParameterLabel(VstInt32 index, char* text) { juce::ignoreUnused(index, text); } virtual void getParameterName(VstInt32 index, char* text) { juce::ignoreUnused(index, text); } virtual void getParameterDisplay(VstInt32 index, char* text) { juce::ignoreUnused(index, text); } virtual VstInt32 canDo(char* text) = 0; protected: void setNumInputs(int numIn) { numInputs = numIn; } void setNumOutputs(int numOut) { numOutputs = numOut; } void setUniqueID(int) {} void canProcessReplacing() {} void canDoubleReplacing() {} void programsAreChunks(bool) {} int numInputs = 0, numOutputs = 0, numPrograms = 0, numParams = 0; SampleRateCallback* callback; double getSampleRate() { return callback->getSampleRate(); } }; } // namespace airwindows #define DECLARE_AIRWINDOWS_NODE(ClassName, Namespace) template <int NV> struct ClassName final : public data::base { SNEX_NODE(ClassName); struct MetadataClass { SN_NODE_ID(#ClassName); }; static constexpr bool isModNode() { return false; }; static constexpr bool isPolyphonic() { return NV > 1; }; static constexpr bool hasTail() { return false; }; static constexpr bool isSuspendedOnSilence() { return false; }; static constexpr int getFixChannelAmount() { return 2; }; static constexpr int NumTables = 0; static constexpr int NumSliderPacks = 0; static constexpr int NumAudioFiles = 0; static constexpr int NumFilters = 0; static constexpr int NumDisplayBuffers = 0; void prepare(PrepareSpecs specs) { _sampleRateSource.sampleRate = specs.sampleRate; _tmp.setSize(specs.numChannels, specs.blockSize); } void reset() {} void handleHiseEvent(HiseEvent& e) {} template <typename T> void process(T& data) { auto buffer = juce::AudioBuffer<float>(data.getRawChannelPointers(), data.getNumChannels(), data.getNumSamples()); processInternal(buffer); } template <typename T> void processFrame(T& data) { auto** ptr = (float**)alloca(data.size() * sizeof(float*)); for (int i = 0; i < data.size(); i++) { ptr[i] = data.begin() + i; } auto buffer = juce::AudioBuffer<float>(ptr, data.size(), 1); processInternal(buffer); } auto processInternal(juce::AudioBuffer<float>& buffer) -> void { _tmp.makeCopyOf(buffer); _engine.processReplacing(_tmp.getArrayOfWritePointers(), buffer.getArrayOfWritePointers(), buffer.getNumSamples()); } int handleModulation(double& value) { return 0; } void setExternalData(ExternalData const& data, int index) {} template <int P> void setParameter(double v) { _engine.setParameter(P, static_cast<float>(v)); } void createParameters(ParameterDataList& data) { for (auto i{0}; i < airwindows::Namespace::kNumParameters; ++i) { char name[kVstMaxParamStrLen]{}; _engine.getParameterName(i, name); auto parameter = parameter::data(name, {0.0, 1.0}); registerCallback(parameter, i); parameter.setDefaultValue(_engine.getParameter(i)); data.add(std::move(parameter)); } } private : template <typename Param> auto registerCallback(Param& parameter, int i) -> void { switch (i) { case 0: registerCallback<0>(parameter); break; case 1: registerCallback<1>(parameter); break; case 2: registerCallback<2>(parameter); break; case 3: registerCallback<3>(parameter); break; case 4: registerCallback<4>(parameter); break; case 5: registerCallback<5>(parameter); break; case 6: registerCallback<6>(parameter); break; case 7: registerCallback<7>(parameter); break; case 8: registerCallback<8>(parameter); break; case 9: registerCallback<9>(parameter); break; case 10: registerCallback<10>(parameter); break; case 11: registerCallback<11>(parameter); break; case 12: registerCallback<12>(parameter); break; case 13: registerCallback<13>(parameter); break; case 14: registerCallback<14>(parameter); break; case 15: registerCallback<15>(parameter); break; case 16: registerCallback<16>(parameter); break; case 17: registerCallback<17>(parameter); break; case 18: registerCallback<18>(parameter); break; case 19: registerCallback<19>(parameter); break; case 20: registerCallback<20>(parameter); break; case 21: registerCallback<21>(parameter); break; case 22: registerCallback<22>(parameter); break; case 23: registerCallback<23>(parameter); break; case 24: registerCallback<24>(parameter); break; default: break; } jassert(false); } airwindows::SampleRateCallback _sampleRateSource{}; airwindows::Namespace::ClassName _engine{&_sampleRateSource}; juce::AudioBuffer<float> _tmp; }
This Airwindows.h file is exactly the same as the one I'm using, so its not the problem I think.
-
@Lindon wicked. It does look like it's not a problem of the node but the network. If I disable the AllowCompilation in the Network Node properties the third party nodes do at least compile independent of that. So it might indeed throw a false positive on the polyphonic thing as Christoph suggested and therefor not properly build the DspNetworks.h
-
@Morphoice Yeah you're missing the node_properties.json file so the code generator doesn't know whether your C++ node should be polyphonic (as it should as your DECLARE_AIR_WINDOWS macro creates a class with a voice number template) so it makes an educated guess which appears to be wrong.
Whenever you paste in a ThirdParty code, always create the C++ template through the HISE menubar first, then replace the file content of the autogenerated file with your code. This ensures that it creates the proper flags in the
node_properties.json
file.When you do so you should see something like this in
ThirdParty/node_properties.json
."Disintegrate": [ "IsPolyphonic", "AllowPolyphonic" ]
Oh and yeah, use Git, then remove all the build files from the source control system, Dropbox is the complete wrong tool for the job.
-
@Christoph-Hart I will check that out. Thanks
-
@Christoph-Hart is there a list somewhere which folders/files exatcly to ignore in git?
-
**/Binaries/ PooledResources/ AdditionalSourceCode/ Samples/ AudioFiles/ *.hip *.hxi *.hxp *.hr* *.ch* .DS_Store user_info.xml
-
@d-healey said in MSVC only: Error C3203: unspecialized class template ... (works fine on MAC):
**/Binaries/
PooledResources/
AdditionalSourceCode/
Samples/
AudioFiles/
*.hip
*.hxi
*.hxp
.hr
.ch
.DS_Store
user_info.xmlbueno! let's see how that goes.
atm HISE is complaining the source isnt the same commit hash as the build, although I just built it from the source.... narf -
@Morphoice said in MSVC only: Error C3203: unspecialized class template ... (works fine on MAC):
although I just built it from the source.... narf
How many copies of HISE and the source code do you have?
-
@d-healey one. it'a a freshly installed pc, HISE has just been pulled from github and built
-
@Morphoice Did you build the develop branch?
-
@d-healey yes sir
-
@Morphoice In that case it could be just that Christoph hasn't updated the git hash so don't worry about it.
-
@d-healey well it does produce hundreds of compiler errors though ...
-
@d-healey if I forget to update the git it will not show this message, it just doesnât show the correct git in the about window.
That message means that there is a mismatch between the source code git hash and the compiled version.
-
@Christoph-Hart but how can I resolve this? I just compiled it again from the sourcecode and it still shows the message...
-
@Morphoice where does your HisePath setting point to?
-
@Christoph-Hart C:\HISE which is where github put the source... I'm just doing it again from scratch
-
@Morphoice And when you run HISE you're running it from within that same folder?