SNEX Filters...
-
Attempting to make a filter using the core.SNEX node. Using ChatGPT to help me since I know nothing about code. I assume its out of date but maybe someone could explain if this is even possible or not...
I want to start with a simple Low Pass filter.
-I created a new file within a network within script fx.
Here is my error:
snex_node - Line 83(20): Parsing error: Expected:
TypeActual: $identifierHere is my code that's not working:
template <int NV> struct snex_lowpass_filter { SNEX_NODE(snex_lowpass_filter); // Parameters float cutoffFrequency = 1000.0f; // Initial cutoff frequency // Initialise the processing specs here void prepare(PrepareSpecs ps) { // Any initialization can be done here } // Reset the processing pipeline here void reset() { // Reset any internal state variables here } // Low-pass filter function float lowPassFilter(float input) { // Sampling period const float dt = 1.0f / Engine.getSampleRate(); // Time constant const float RC = 1.0f / (2.0f * PI * cutoffFrequency); // Coefficient const float alpha = dt / (RC + dt); // Compute output float output = alpha * input + (1.0f - alpha) * prevOutput; // Update previous output prevOutput = output; return output; } // Process the signal here template <typename ProcessDataType> void process(ProcessDataType& data) { for (auto& sample : data) { sample = lowPassFilter(sample); } } // Process the signal as frame here template <int C> void processFrame(span<float, C>& data) { // This function is used for processing audio frames (e.g., stereo signal) // You can implement a frame-based processing if needed } // Process the MIDI events here void handleHiseEvent(HiseEvent& e) { // This function is used for handling MIDI events // You can implement MIDI event processing if needed } // Use this function to setup the external data void setExternalData(const ExternalData& d, int index) { // This function can be used to set up any external data needed for processing } // Set the parameters here void setParameter(int parameterIndex, double value) { // You can set parameters dynamically during runtime if (parameterIndex == 0) { cutoffFrequency = value; } } private: // Previous output sample float prevOutput = 0.0f; };
-
@FatMitchell been a hot minute since i've used snex, but something like:
template <int NV> struct snex_lowpass_filter { SNEX_NODE(snex_lowpass_filter); // Variables // Define these so you aren't constantly allocating new memory every buffer float cutoffFrequency = 1000.0f; float prevOutput = 0.0f; float RC = 0.0f; float alpha = 0.0f; void prepare(PrepareSpecs ps) { // i'm not sure if these need to be const // but they should be defined here, since this is where we get the sampleRate const float sr = ps.SampleRate; // sampleRate is inside the ps variable, not Engine const float dt = 1.0f / sr; const float PI = Math.pi(); // not sure if ps.SampleRate is the real syntax, but it's something similar } void reset(){} float lowPassFilter(float input) { // not sure if these need to be consts const float RC = 1.0f / (2.0f * PI * cutoffFrequency); // PI should work now since we defined it above const float alpha = dt / (RC + dt); float output = alpha * input + (1.0f - alpha) * prevOutput; prevOutput = output; // not sure why prevOutput was private return output; } // Process the signal here template <typename ProcessDataType> void process(ProcessDataType& data) { for (auto& sample : data) { sample = lowPassFilter(sample); } } // Unused template <int C> void processFrame(span<float, C>& data){} void handleHiseEvent(HiseEvent& e){} void setExternalData(const ExternalData& d, int index){} // Set the parameters here void setParameter(int parameterIndex, double value) { // You can set parameters dynamically during runtime if (parameterIndex == 0) { cutoffFrequency = value; } } };
if you don't have much coding experience, jumping straight into a SNEX filter might be a bit too much to take on, i recommend searching the forum or the repos for simpler examples like a Gain or Saturation effect before taking on something as math-heavy as a filter
i'm not sure if my code will work, but hopefully it points you a bit closer to a working node
-
@iamlamprey thank you endlessly for this. It didn’t work but it’s probably user error. Trying to read through everything I can find but it’s not much in terms of a finished working example. Do you have any working examples (of any kind) that u could post/sendme so I can study how it works and more importantly how to implement it.
Thanks!
-
@FatMitchell Christoph's already made a bunch of SNEX examples here:
https://github.com/christophhart/HISE/tree/develop/tools/snex_playground/test_files
i recommend checking out the "Node" folder as a lot of the other examples are specifically explaining individual syntax
note: some things have probably changed since he made these, for example I don't think you need data.toFrameData() anymore since there's now a function specifically for processing frames
-
and here's a simple gain example:
template <int NV> struct snex_simple_gain { SNEX_NODE(snex_simple_gain); // Variables float gain = 1.0f; void prepare(PrepareSpecs ps){} void reset(){} // This can be a function, or we can do the raw math below float applyGain(float input) { float output = input * gain; return output; } // chatGPT failed you here I think void process(ProcessData<NumChannels>& data) { for (auto& s : data) { s = applyGain(s); } } // Unused template <int C> void processFrame(span<float, C>& data){} void handleHiseEvent(HiseEvent& e){} void setExternalData(const ExternalData& d, int index){} // Set the parameters here // chatGPT also failed you here :P template <int P> void setParameter(double v) { // this gain parameter is added in the Scriptnode tree, it should be ranged 0-1 (where 1.0 is 100% gain) if (P ==0) // the index of our parameter { gain = v; } } };
i cant test if it works right now but it's a pretty simple example so it should help clarify what's going on
-
@iamlamprey wow epic. Is the SNEX documentation up to date? I have been getting some Frame errors but I didn't see anything in the docs. Seriously thank you so much for your time and effort on this.
-
@FatMitchell said in SNEX Filters...:
Is the SNEX documentation up to date?
no idea, i think it's pretty feature-complete at this point so I don't see christoph making too many changes