yes totally
if we’re gonna do a discourse tomorrow/sun maybe that will be a good opportunity
lmk so i can plan my days a bit

I bet ya’ll get together to talk about Norns development and a really cool DnD game breaks out.

3 Likes

Wizard is about to die…

Small point of correction (forgive me if I misunderstand what you’re getting at here!) - there is no performance difference between sclang code compiled in the classlib, and sclang code compiled at runtime. Compilation itself is not free, but is quite cheap - compiling something of the complexity of the engines in dust is on the order of <1ms. Of course if you’re compiling code every time a parameter changes, or building a new synth for each note, it’s a performance problem because of bad design, not because of compilation itself. :slight_smile:

You’re right that a class-based approach is best practice, though - there are clear benefits in terms of having Engine’s be something stable and well defined, so that norns can interact with and manage them.

2 Likes

thanks for the correction. of course you’re totally right, there’s no difference in execution time once a chunk has been compiled. but runtime compilation has its own (marginal) overhead, is what i meant - not just for synthdefs. and its surprisingly common for beginner code (or just sloppy last-minute performance code) to call interpreter in a hot loop or calback at runtime. (i totally overstated the point though.)

anyway that’s a trivial consideration compared to the architectural advantages of using classes. the debate in my mind is whether those advantages are worth forcing a recompilation of the class lib anytime anything changes.

1 Like

i’m able to edit matron code and update it on norns now. here are the steps for other windows users:

after editing, copy updated files to norns (using SFTP here, haven’t tried sshfs):

  • connect to norns over wifi
  • using Far Manager change drive to NetBox
  • create new connection, type SFTP, port 22, norns.local, username we, password sleep, try and connect
  • if you get unexpected SSH2_MSG_UNIMPLEMENTED packet error, edit connection, navigate to “Options controlling key re-exchange” and move Diffie-Hellman group exchange to after Diffie-Hellman group 14 and group 1

should be able to connect now and update files on norns:

  • open bash
  • ssh we@norns.local or IP (i had to use IP address)
  • once you’re in cd norns, then ./waf to compile
  • restart matron by doing ./stop.sh and ./start.sh

i’m able to make changes and update matron by doing ./stop.sh and ./start.sh. however when i run ./crone.sh > /dev/null i get the following error:

we@norns:~/norns $ ws-wrapper: ../ws-wrapper/src/main.c:43: bind_sock: Assertion `( *eid = nn_bind(*sock, url) ) >= 0' failed.
./crone.sh: line 8: 26151 Aborted                 ./build/ws-wrapper/ws-wrapper $SCLANG ws://*:5556
2 Likes

error likely means something already bound to that port. if you did ./start.sh it already ran crone.sh so there’s your trouble. if you wan to run matron alone with terminal I/O, run the executable directly (norns/build/matron/matron)

2 Likes

I’ve been doing some work on a flexible lua class for drawing graphs, WIP video below.

The idea is you can load it up with points and draw them in a variety of styles scaled to axes and screen area (so it can sit next to other UI). Or you can give it a y=f(x) function and it’ll plot that, as shown at the start of the video.

I’m keeping the interaction examples to just using enc2, enc3 and key3 so that these could potentially be integrated into sub-pages of the Parameters screen at some point, keeping the back button free.

Couple of questions:

  • I’d like to align the envelope curves with those defined in SC, does anyone have an understanding of how the curve argument is used by SC in Env? I had a look at the code but… yeah :grimacing:
  • Also if anyone has advice for how to graph filters (Bode plot?), code snippets, etc that’d be much appreciated. Maths is hard :sweat_smile:

Thoughts and feedback very welcome!

41 Likes

Can you pass compile options to waf (with current wscript) or do I need to edit wscript?

( I want to pass some compiler defines as you would in make/ cmake )

do you mean when you give a numerical value for “curvature”? good question, i’m finding it oddly difficult to pin down. @jah has added warping functions to norns/lua/util.lua that parallel SC’s explin, linexp, &c. maybe those are useful. we’ve also added a taper with a bipolar curvature control in norns/lua/params/taper.lua, which is, i’m guessing, neither the exact same curve, nor very different. in lua it’s formula is
y = (math.exp(x * k) - 1) / (math.pow(math.exp(1), k) - 1)
where k is the curvature param, and x is the input (nonnegative.)

i’ll see if i can spot SC’s formula for envelope curvature.

re: bode plots. indeed that’s a bit daunting. the math is not necessarlily too bad depending on how far down the rabbit hole. but the mag response would have to be worked out for each individual filter type. then that could be painful. for some types there may not be an easy analytical solution at all.

  • LPF, HPF, RLPF, RHPF ,Resonz, Ringz, Formlet i think are all standard 2nd order IIRs, should be prettty straightforward. but some use have different weird formulas for their arguments - e.g. Ringz is constant-skirt gain.
  • MoogFF is documented in a paper somewhere. MoogLadder is not documented at all (i think it is ripped from random musicdsp.org code)
  • SVF would just have to look at the code. it could be easy (if it’s straight outta chamberlin) or impossible (if it uses nonlinearities)

i would find this a fun and useful project (tracking down mag response functions for all SC filters) but ATM i have no time for it :frowning:

then pragmatically, youd have to ensure you are using the correct filter type. that’s part of a larger discussion we’ve been having, which is to enforce paran type documentation for engine commands (hm, i’ve lost the GH issue right now :confused: )

general-purpose bode plotters (and say, MATLAB) just cheat and do a brute-force measurement - FFT of the filter’s response to white noise and sweeps. but that’s not really a feasible option here

and i’ve seen more than one commercial software UI that just cheat and use a simple filter to stand in for a complicated / proprietary one, for UI purposes. which is not always the worst choice esp. in a low-rez environment like this.

lovely work by the way. more drawing abstractions extremely useful indeed

youd need to add options to wscript. or use CFLAGS env variable maybe?

1 Like

I believe MoogLadder is Antti H’s moog algo which is great: https://pdfs.semanticscholar.org/c490/4c04a7be1d675e360409178da71a1253f6d8.pdf

1 Like

thanks for the correction! awesome. sorry to be flippant.

so yeah, that looks basically impossible to make a clean mag response function for. they are using nonlinearities, lookups to compensate for phase shift, all kinds of stuff.

until i get more comfortable with supercollider, how hard would it be to expand this example to pass in/out audio from another audio programming language/environment i’m more familar with? (i’d probably opt for csound in this case)

ie: is it way more involved than adding a couple bus channels here and connecting them with jack? i’ve poked around through the norns repo and have an idea of how things work together but i’m not sure exactly how and where this scenario would work.

yes, you could connect another application to SCs inputs with jack.

to add
additional input channels to SC would be a little more involved. i think you could change the .inputBusChannels field in the server options on startup (see Crone.sc)

if you are gonna go down that road you will of course be off in a customized environment different from other norns users, and should be comfortable with figuring some stuff out for yourself (e.g. best way to manage persistent jack client connections without a GUI, managing your other application lifecycle, &c)

oh and of course - if you want, you can just run csound instead of SC and send it to the hardware outputs directly. sounds a little more straightforward to me

thanks for the pointers. it’s a bit of a leap above what i’ve done before, but i’m figuring things out fine so far. eventually it would be nice to figure out how to do it with an engine (in my mind it seems it would allow ease of use and quick switching between apps), but doing it direct to outputs will be my first step.

regarding SC and sclang : is there a way to “tap in” to SC/Crone while it’s running? like i said before, i’m pretty new to SC and it seems that running sclang tries to open another instance of SC in that directory or something. furthermore, i haven’t extensively worked with trying to run csds on norns yet, but quickly trying to run csound direct gives me an error of "*** Cannot open device 'hw:0,0' for audio output: Device or resource busy' so i’m wondering if i should be stopping SC before doing this. just not super sure about how to do so

What I’d did yesterday, was in crone.sc, where it sets server options, add
Server.options.maxLogins=4
Then you can use Scide on a remote computer.

@zebra any reason not to have this?
Is there an overhead to alllowing more logins?

1 Like

yeah you don’t want another instance of sclang on the norns. stop the old one first (killall sclang)

the I/O for the sclang instance is exposed to maiden through websockets. you can see output. input through the REPL is currently busted b/c of some weirdness with sclang’s virtual terminal or something
[ https://github.com/monome/norns/issues/421 ]

sounds like its trying to talk to ALSA directly instead of jack. you’ll have to figure out the right way to setup csound if you want it running in parallel. if you don’t want sclang then don’t launch it, you can send OSC to arbitrary destination from lua.

i can’t think of a reason not to. usefulness seems limited since you won’t be able to inspect/debug the local sclang environment, just the server.

[mod: i’m moving this whole thread to development, it’s way off the critical path for most users]

Thank you for the in-depth reply, super helpful!

Yes exactly. I just implemented the formula used in taper.lua (hadn’t noticed that before) and it looks good, certainly close enough for visuals I’d say. So that’s a quick win :smile:

Yeah I think just getting something representative is the way to go. If we had visuals for a LP/HP & BP/NP in 2 & 4 pole variations, resonant/non-resonant then that’d be plenty for now. The difference between implementations I’m guessing won’t look that different on a tiny screen. Still a little beyond my understanding right now but I’ll tidy up the rest of what I have and keep thinking on it!

13 Likes

thanks! you were right, once telling csound to use jack it worked as expected.

i had a long 6 hour flight from santa cruz back home to boston, so i was even able to begin work on passing the csound output back into an SC engine. for someone who hasnt done much development this is starting to feel within reach :slight_smile:

6 Likes

SC’s curvature formula is most accessible in the implementation to the SimpleNumber:lincurve / SimpleNumber:curvelin. It basically amounts to:

		a = outMax - outMin / (1.0 - grow);
		b = outMin + a;
		scaled = (this - inMin) / (inMax - inMin);

		^b - (a * pow(grow, scaled));

If in and out ranges are 0…1, it’s more like:

		grow = exp(curve);
		a = 1.0 / (1.0 - grow);
		b = a;
		scaled = this;

		^b - (a * pow(grow, scaled));
1 Like