MagnitudeResponseView + FilterKernels

MagnitudeResponseView + FilterKernels

MagnitudeResponseView

MagnitudeResponseViewis a Model View Control (MVC) implementation of a Filter Magnitude Response plotter for SuperCollider 3.

k = SOSKernel.new
v = k.view;

MagnitudeResponseView-02

MagnitudeResponseView performs simultaneusly as both a View and a Control.

As a View, it plots the magnitude of frequency bands a Filter will pass or reject.

As a Control, it responds to user adjusts to a Filter’s Cutoff frequency, Gain and Q.

MagnitudeResponseView intefaces with FilterKernels. It can manage any number of FilterKernels and plot the resulting sum of all Filters magnitude responses

MagnitudeResponseView is highly customizable and can be embedded on almost any kind of parent View/Window.

Controls

MagnitudeResponseView as a control

  • Click on a FilterKernel's cursor* selects a FilterKernel.
  • Click and drag a FilterKernel's cursor* to adjust its Cutoff frequency (Hz) [X axis] and/or Gain (dBs) [Y axis] where applicable.

*In MagnitudeResponseView’s of the shelf configuration, a Filter’s Cursor is the red circle at its Cutoff as shown on the pictures.

  • Mouse Wheel or Two finger vertical swipe on touchpads, adjusts the Filter’s Q value where applicable.

  • Right Mouse Button Click on MagnitudeResponseView and you get a popup menu with all the filters available in your installation for the Selected FilterKernel.

soon - forum wont allow me to
![MagnitudeResponseView+menu|446x328](upload://eelrdGypPhrERTKGxt39VZzLQAk.png)

By default, for an SOSKernel for example, the set of installed filters are all of the BEQSuite Filters + an extra Lowshelf example: LowBoost, supplied by this package.


MagnitudeResponseView keyboard controls

  • n - select next kernel
  • p - select previous kernel
  • -/+ - range zoom gain

    These operate on the selected FilterKernel:
  • b or d - bypass selected FilterKernel
  • Up Down - adjusts Gain / Q depending on key mods [shift]/[ctr].
  • Left Right - adjusts Cutoff freq.
  • m - Popoup filter select menu.
  • z - Zero Gain

MagnitudeResponseView's info line updates in real time to reflect user modifications. The info line displays:

  • Active FilterKernel index number in brackets. ie, [0]
  • Filter name. ie, BPeakEQ
  • Cutoff frequency in Hz
  • Q
  • Gain in dBs

Adusting MagnitudeResponseView triggers the View’s instance user installable action function. Just like it would on any other SuperCollider3 View:

MagnitudeResponseView::action_ { arg viewInstance, filterKernel, triggerAction;
  ...
};

Where arguments viewInstance is the View Instance that triggered the action func, filterKernel is the FilterKernel that was modified and triggerAction is a Symbol that states what type of change did just take place:

  • \coefs - Filter Coefficients changed. User adjusts to Cutoff, Gain and/or Q
  • \filterKey - User did select a new Filter Type
  • \bypass - FilterKernel bypass.

FilterKernels

FilterKernels are helper classes.

FilterKernels main funcionality is to obtain a set of filter coefficients based on the kernel’s current configuration. Name it, a Kernel’s current Filter selection and the Filter’s parameters values.

Just like modifications to a Kernel’s filter parameters, Filter selection itself can be made any time.


FilterKernelBase

FilterKernelBase is an abstract class and supplies all of FilterKernels base behavior. Parents FOSKernel and SOSKernel First and Second Order Sections filters respectively.

soon - forum wont allow me to

![FilterKernel-hierarchy|200x124](upload://bnk3ApBYrmhIWGRmGhGbX4gea0G.png)

Create FilterKernel instances

// SOSKernel::new(freq=100.0, q=0.7, dBGain=0.0, filterKey='BPeakEQ', sampleRate=44100.0);
k = SOSKernel.new();

List a FilterKernel installed filters:

SOSKernel.filters.keys; // installed filters

Installing new filters to a FilterKernel

Extending FilterKernel to support more filters can be done by creating an instance of a KernelFilter that defines the new filter then add that to the FilterKernel’s filters dictionary.

KernelFilter::new(name, className, freqKey='freq', gainKey='db', qKey='rq', isQreciprocal=true);
  • name - Name of the filter. This name will appear on menus.
  • className - The filter Class. The class must respondTo the coefs method. The Coefs method calculates and returns a set of coefficients for the supplied filter parameters. This can also be a Function that calculates coefficients from your filter’s parameters (NB - broken ATM).
  • freqKey - Argument name for the filter’s Cutoff ferquency parameter in the coefs method.
  • gainKey - Argument name for the filter’s Gain parameter in the coefs method. nil if not applicable
  • qKey - Argument name for the filter’s Q parameter in the coefs method. nil if not applicable
  • isQreciprocal - True if the Q argument is supplied to the filer as a reciprocal of Q (ie, rq).

Example:

// Install a filter into a FilterKernel (an SOSKernel here)

f = KernelFilter.new("BLowPass", BLowPass, 'freq', nil, 'rq', true);

SOSKernel.filters.put('BLowPass', f);

// All installed filters

SOSKernel.filters.keys;

Examples

A MagnitudeResponseView that plots both, an SOS and a FOS.

k = SOSKernel.new;
j = FOSKernel.new;
j.setFrequency(1000);
v = k.view;
v.kernels = [k, j];

SOSKernel examples

s.boot;
b = Buffer.read(s, "/path/to/your/audio/file)");

(
[1,2].do({ arg chns;
    SynthDef("soskernel-ctrl-"++chns.asString, { |inbus=2, outbus=0, bufnum, rate=1.0, t_trig=1, startPos=0, loop=1, amp=1.0, bypass=0|
        var coefs, coefsctl,fx,dry,z;
        coefs = 0!5;
        coefsctl = \coefs.kr(coefs);

        dry = PlayBuf.ar(2, bufnum, BufRateScale.kr(bufnum) * rate, t_trig, startPos, loop, Done.freeSelf);
        // dry = In.ar(inbus,chns);
        fx = SOS.ar(dry, *coefsctl);
        Out.ar(outbus, ((dry*bypass)+((1-bypass)*fx)) * amp);
    }).add;
});
)

k=SOSKernel.new;
k.coefs;
a=Synth("soskernel-ctrl-2", [\coefs, k.coefs, \bufnum, b.bufnum]);

a.trace;

a.set(\amp, 0.7);
a.set(\amp, 1);

v=k.view;
v.action={|view,kernel| a.set(\coefs, kernel.coefs, \bypass, 1 - kernel.enabled.binaryValue); };

(
v.action={|view,kernel,changed|
    //changed.postln;
    case
    { changed == \coefs or:{ changed == \filterKey } } {
        a.set(\coefs, kernel.coefs);
    }
    { changed == \bypass } {
        a.set(\bypass, 1 - kernel.enabled.binaryValue);
    };
};
)

s.dumpOSC(1);
s.dumpOSC(0);

k.filterClass_(BLowPass); a.set(\coefs, k.coefs);
k.setFrequency(2300.0); a.set(\coefs, k.coefs);
k.setFrequency(5200.0); a.set(\coefs, k.coefs);
k.setQ(0.7); a.set(\coefs, k.coefs);
k.setQ(2.5); a.set(\coefs, k.coefs);
k.setQ(1.2); a.set(\coefs, k.coefs);

k.selectFilterType(\BPeakEQ);
k.setFrequency(2300.0);
k.setGain(3.0);
a.set(\coefs, k.coefs);
k.setQ(0.7); a.set(\coefs, k.coefs);
k.setFrequency(5200.0); a.set(\coefs, k.coefs);
k.setGain(3.5); a.set(\coefs, k.coefs);
k.filterClass_(BHiShelf); a.set(\coefs, k.coefs);
k.setFrequency(1000.0); a.set(\coefs, k.coefs);
k.setGain(3.5); a.set(\coefs, k.coefs);
k.setQ(2.4); a.set(\coefs, k.coefs);
k.setQ(0.7); a.set(\coefs, k.coefs);

a.set(\bypass, 1);
a.set(\bypass, 0);
k.frequency_(1000.0);
k.q_(0.7);
k.gain_(0.0);
k.paramsChanged;
k.changed(\freq);
a.set(\coefs, k.coefs);
v.refresh

a.free;
b.free;

Instalation

Clone MagnitudeResponseView repository and move its folder inside the Extensions folder in SuperCollider3 User Support directory or place MagnitudeResponseView repository folder anywhere you want in your file system and add its path to your includes folder in sclang config section in SCIDE prefs.

ie, in the IDE:

Click Edit Menu → Preferences and click on interpreter.

Recompile Class Library and you are done.

PD, I should be doing this a quark pretty soon.


Hello, world!

It has certainly been a long while since my last post for the comunity. Certainly my first on this forum. it rocks and looks awesome BTW. I have missed the interaction and feedback with you guys that used to render really amazing things.

This is a 100% functional pre-release.
IMHO FilterKernels are not only super simple to use and extend to support more Filter types but also have the adavantage to ease flipping filter models in R/T - these feature alone truly exploits FOS and SOS potential.

The documentation part is notably (still) missing on this initial release. The examples however, should humbly fill in the gaps on only a few of the things that the package is capable of.

I will be adding to that in the next days along with more examples and of course, looking forward your input regards the package.

Mean time, please feel free to post all of you questions.

blackrain-audio blog

The fine print.

As most of you know I have always been a freelancer. Currently between projects and loooking for a gig; be it developing, designing sound, (co)producing, mixing, you name it so pleaaase drop me a line.

Support to fund this project is welcome. Be it via Paypal or any other methods you may suggest is much apreciated. Any amount you feel right is always apreciated. Long hours have been spent on it and that would certanily aid with the time it still needs.

DM me for any details.

Thank you ver much all for your attention.
Cheers.

Thanks

13 Likes

I clicked “like” but what I really meant was :exploding_head: :astonished: :star_struck: :heart_eyes: :exploding_head: :astonished: :star_struck: :heart_eyes: :exploding_head: :astonished: :star_struck: :heart_eyes:

This is great!

hjh

1 Like

Welcome back, sir. I’ll send you a message!

1 Like

If you don’t have GIT available in your system, you can simply download a snapshot of the MagnitudeResponseView repository as a zip file from the Downloads links at the bottom left on that page.
Unzip that and install the resulting folder as a quark:

Quarks.install("~/path/to/MagnitudeResponseView.quark")

Recompile your Class Library and you are done.

Cheers

Thank you very much James.
Super glad you like the idea.

looking forward to see what all of you guys do with this ))

all the best!
x

This is great! Thank you very much!

1 Like

Fantastic!!! Thanks for this! I’ve recently been struggling with understanding the magnitude responses of supercollider filters, and I think this is a super valuable contribution.

1 Like