this is utterly brilliant, thank you @zebra! making supercollider polyphonic has been a stumbling block for me several times now - i’ve made several scripts that would directly benefit from this.

so many cool tricks i learned just by reading the code! the use of NodeWatcher, the voice-stealing implementation. thanks for all the commenting, supercollider is hard to read but here it was so straightforward!

there’s one little thing i’m stuck with:

would you be so kind as to explain what .perform() refers to and also why the “_” is appended before converting to a symbol? this is a really cool way of folding up those functions.

I was able to rename the classes thebangs.sc and OneshotVoicer.sc and retain functionality … but when I try to rename bangs.sc and the corresponding callback in thebangs.sc on line

	bangs = Bangs.class.methods.collect({|m| m.name});

the script boots, but no longer produces sound. I’ve slept the machine after each incremental change and changing that class name seems to break everything for me.

Maybe that one isn’t a class name that needs to be changed or maybe there is a reference to it I missed somewhere?

EDIT:

WHOOPS! I found another Bangs hiding out in thebangs.sc I needed to change.

All good.

this is a norns engine which aims to extend the classic PolyPerc patch

“classic” lol

PolyPerc was my first attempt at supercollider, i apologize that it has become an unsophisticated yet canonical point of entry

10 Likes

seriously - unsophisticated is exactly what it needs to be.

would you be so kind as to explain what .perform() refers to and also why the “_” is appended before converting to a symbol? this is a really cool way of folding up those functions.

this is probably the hackiest thing in the pile. two parts:

(1) perform is a method of Object (the base class of all things.) it accepts a symbol, and if the receiver has a method with the same name as the symbol, that method is invoked with the remaining arguments passed along. relevant helpfile.

(2) when you set the value of a member variable, you are actually invoking a method with that variable’s name followed by an underscore. a default version of this method is generated automatically when you add > to the variable declaration in the class, but setters can also be customized. (like here.)

[not shown: same applies to getters, which are methods with the variable’s name alone - no underscore - and the declaration shortcut is <.]

relevant helpfile.

so those lines are just an inscrutable way of saying, “for each of these strings, add a command that calls the setter method for a variable with the same name as the string, on this object.” (maybe there is even a better way of doing this, but that is what i came up with.)

[aside: the difference between strings (mutable) and symbols (iummutable) is relevant here. it’s one of many places in SC where the string must be “made immutable” with .asSymbol.]

7 Likes

This is great. It’s awesome to see the work we did in Dronecaster grow into an extended exploration of how to make engines more flexible.

2 Likes

I was wondering if there was any correlation to maggie and sarah’s band. i lived in olympia and knew them when they were first getting started with that band (and going through a lot of drummers).

1 Like

yeah all the dronecaster sc props go to @license!!

really beautiful work on this @zebra.

2 Likes

Just a quick update …

My script pixels is up on the library and this is working beautifully for me. Thank you!

I’m working on adding a way for users to swap engines from inside the app … but I’ve noticed that both exp and lin klang engines are not making any sound. Also, the sinFMLP doesn’t seem to change much when scrolling mod1. I do not currently have a way to scroll mod2 from my app, so there may just need to be some interplay there. Not quite sure.

those sounds work for me when editing the parameters in awake_bangs. lmk if that doesn’t work for you. if it’s only in your script, maybe i can help dbg at a later time. (but ATM i have no time)

Plugging a dummy value (100) in for engine.mod2 makes those engines come alive. It seems as though if the mod2 parameter is not specifically initialized with a value, those klang engines make no sound. Perhaps your version of Awake always sends a value out, whereas other scripts may not, causing a possible issue?

I’m just reporting my findings here, no need for debugging.

Thanks so much for this.

ah i see - you’re right. values of zero for mod2 will be silent on those. (and zero is the default.) any nonzero should be audible. will fix

thanks

I’m still working my way through implementing all of the exposed parameters from your engine into my script “pixels”. I seem to have come across a bug or at least an inconsistent behaviour.

The engines reznoise, klangexo and klanglin do not respond to engine.pan. The other engines seem to respond just fine, but I’m getting some strange stuck results with these. Reznoise seems to respond differently to each left and right field as far as frequency response to mod1, mod2 and hz2 go. I’m actually experiencing some weirdness across the stereo field in the klang engines as well.

I’m looking into it my self and trying to learn supercollider. Just wanted to let you know.

Yep - those produce stereo signals in themselves nd I haven’t made the panning stage smart enough to really handle them

Only had a couple short sessions will the this so far, hence v0.0.x

If you want to try it, my idea would be: a conditional on the number of channels returned by the graph method, in Thebangs wrapper method

We can get away with a lot of silly stuff because arguments are only evaluated once at synthdef creation

If pan were modulated we’d need to be more careful

Eager to try this out. Tonight I installed Pixels (which uses this engine) before installing thebangs itself. After rm -rf of pixels I restarted and now I just get ‘supercollider fail’. Any ideas what went wrong here?

EDIT: I just needed an actual SLEEP rather than a ;restart from Maiden, all is fine now.

The Bangs is bundled into “pixels” itself when it is installed. No need to specifically install the engine itself. Just download “pixels” from the community and sleep the Norns.

Glad you got it rolling.

1 Like

… despite some confusing advice i’ve seen floating around here, this is never recommended except during troubleshooting (to get early output from either the SC or matron component) or development (re-launching a single component to test a specific change.)

if you are trying to get to normal functionality and don’t want to use RESET for some reason, you must issue ;restart twice: first in the “SC” tab, then in the matron tab.

more typically, use SLEEP or SYSTEM > RESET from the norns menu to restart after installing new supercollider classes.

5 Likes

What do I have to do have Thebangs/NewAwake and pixels both installed without getting duplicate engine error? Delete an engine?

delete one, or rename this class and this engine name in pixels

(to something like Engine_Pixelbangs and engine.name = Pixelbangs respectively)

(the Engine_foo pattern is mandatory; the capitalization of foo to Foo is just a convention-so-far)

NB that Thebangs will undergo some breaking changes. support for versioning and dependency spec is a big gap in ecosystem still, so general apologies for that. on the bright side, the manual copy + mangle makes it impossible for my updates to break your script.

2 Likes

Sorry @zebra! I misunderstood your directions a while back when you asked me to rename the class and not the file names. I’ll post an update soon to remedy the issue as described above. I had gone through and renamed the other classes in The Bangs, but not actually The Bangs itself. Uhg!

1 Like

Very interesting! I haven’t looked into it yet, but could this be a way to have multi-timbral synths for norns? I’d been working on an engine a few months ago that would support 6-8 timbres (“voices”) but bumped into what I suspect are hardware limitations as far as number of synth instances and grouping of the “voices” into channels.