TB2-Alpha07 is here

OK this is both major (refactor and few new tools and speed and bug fixes) and minor (not many breaking changes)… and sooooo much work on our side :slight_smile:


I hope you enjoy it. I might post my massive parallel patch tomorrow but now, it is time to celebrate. Mac only for now, sorry…



  • KDTree is much faster
  • AudioTransport is more accurate


  • new UMAP dim redux
  • new RobustScaler

Breaking changes:

  • Max: native support of dictionaries (removing the need for dict.(de)serialise~)
  • Max: behaviour of read and write are like native objects (brings menu if no path provided)
  • SC: a new sync dance. Please see below for details:

Non-breaking changes:

  • SC: no more name to DataSet and LabelSet

Many, many bug fixes, including crashing NMFMorph

SC: new non-realtime framework for improved performance and reliability, as well as fewer surprises. In some cases this means that previous behaviour with respect to server.sync is changed but the public interface remains almost unchanged. In particular
– calls to process (the non-blocking versions) in a Routine no longer block in the language. Where this behaviour is needed, there is a new .wait method that can be called on the object instance returned from process(), i.e.


Produces the equivalent of the old behaviour.

– For the second toolbox objects with realtime querying (KDTree etc), you no longer need to communicate via a bus. Instead, a UGen can be obtained directly from the object instance and used in a Synth, like ~tree.kr(…). See the updated help files for examples.


Thank you! Excited to play with this. I just put it in my extensions and got this error on recompiling the class library:

ERROR: No UGen class found for FluidBufFlattenTrigger

I have a SynthDef that uses FluidBufFlatten.kr that gets written with .writeDefFile when the library re-compiles, so this is likely what is throwing the error, but not sure how to get around it. This error didn’t happen with Alpha 06. Thoughts?

Thank you !


Yaaaaaaaaay!!! Congratulations!
Looking forward to the Windows build. :))


Possibly SC is caching the old binaries (it sometimes likes to, just to keep us on our toes). Did you try rebooting the interpreter / IDE ?


Just as soon as me and MSVC linker come to an agreement :laughing:

I don’t think there’s a particular obstacle to the Max Windows build, actually (famous last words), so if the SC doesn’t start playing nicely next time I look at it, I’ll push Max out anyway.

1 Like

Thanks for a quick reply @weefuzzy ! Yup, rebooted all the things.

In an effort to troubleshoot just now, I replaced the Alpha 07 FluidBufFlatten.sc and FluidBufFlatten.scx with the eponymous files from Alpha 06 and I’m no longer getting that error… and after some (minimal) testing it all seems to be working fine.
shrug emoji

But no issues with other FluidBuf* objects in kr? The alpha 6 and 7 versions are pretty radically different, but I guess (in principle) because it’s standalone, subbing in the earlier version shouldn’t cause widespread weirdness.

Looking at the error message again, I misinterpreted it to mean that scsynth couldn’t find a plugin with the right name, but actually:

is completely a language side thing. i.e. something must be trying to directly invoke a UGen in a SynthDef that resolves to FluidBufFlattenTrigger (which, indeed, isn’t a language-side entity).

So: chances are the binaries are ok. Can you share your SynthDef code and we’ll see if we can work out what I’ve done wrong…

Hmm. Just tested this quickly, and I feel like it should work but when I try to plot the features, I get WARNING: Buffer not allocated, can't plot data. Am I just confused here or is this possibly tied up in it too?

b = Buffer.read(s,"/Volumes/Ted's 10TB My Book (June 2020)/SOUND DESIGNS/shoe squeak/bounces/shoe squeak.wav");
f = Buffer.new(s);




Sorry, it’s just kind of without comment here, but let me know if this is helpful or if you need more!

				arg inBus, analysis_scaler_inBuf,analysis_scaler_inBus, input_buf0, amp_bus, trig_rate = 25;
				var sig = Mix(In.ar(inBus,4)) * 0.25;
				//var sig = PlayBuf.ar(1,test_buf,loop:1);
				var spec = FluidSpectralShape.kr(sig);
				var pitch = FluidPitch.kr(sig);
				var loudness = FluidLoudness.kr(sig);
				var zc = A2K.kr(ZeroCrossing.ar(sig));
				var senseDis = SensoryDissonance.kr(FFT(LocalBuf(2048),sig));
				var trig = Impulse.kr(trig_rate);
				var vector = spec ++ pitch ++ loudness ++ [zc,senseDis];
				var t1;

				vector = Median.kr(31,vector);



				t1 = FluidBufFlatten.kr(input_buf0,analysis_scaler_inBuf,trig:trig);

Uh. Also :grimacing::grimacing:
Line 11 of FluidBufCompose.sc has a bit of a clanger. It should say \FluidBufComposeTrigger not \FluidBufNMFTrigger :sob:

Meanwhile, thanks for the code. Will prod and get back asap


For this one, you just need to call updateInfo or query on f before plotting, because the kr versions of the FluidBuf* things don’t (can’t?) get the language to do this automagically.

1 Like

Looks like magic that happens with writeDefFile isn’t the same as (say) with Function#play or, uh, anything else we tested. I’ll drill into and see if I can figure it out.

(It looks like writeDefFile actually cares if there’s a language side class for a given server-synth name, which nothing else seems to mind about.)


I thought that we tested that - in the helpfile of bufnmf there are synths that are too big and are sent that way, but now that I look at them, they do not include our code, just the resulting buffers…

baboon junking laptop dot gif

Not writeDefFile but SynthDesc#readUGenSpec2. Turns out I was horribly wrong about strict symmetry between SC UGen class names and scsynth Unit names being convention rather than necessary. In order to make a usable Synth from a SynthDef, the latter has to be read by the language as well as the server (so that it can make name-able controls, I guess). The code that does the reading straight up assumes that the symbol in the SynthDef file will map to a class.


I don’t like either of my options for fixing this, so will have to have a small tantrum (quietly), before working out what to do. (The options being either (a) make, by hand*, gazillons of pointlessly identical UGen classes in sclang differentiated only by their name or (b) keep doing what I’m doing language side and implement my own lookup (in addition to scsynth’s) to get the right Unit for a given symbol.

  • Unless there’s actually a way of programatically generating classes that I’ve missed. This would make me happy.

I got this error again, when I was trying to make a synth (just a function.play, not a SynthDef()) that was too big, so SC wanted to write it to a file (I’m guessing same as .writeDefFile).

I think it’s probably the same thing but just thought I’d toss it on here in case that’s useful!


WARNING: SynthDef temp__4 too big for sending. Retrying via synthdef file
ERROR: No UGen class found for FluidMLPRegressor/query which was specified in synth def file:  temp__4.scsyndef

Did you try Alpha08 yet? This shouldn’t be A Thing anymore. (can’t help with the size of the Synth though :stuck_out_tongue_winking_eye:)

Oh thank you! I have not! Where is that?

It is here:

1 Like

wasn’t my post obvious enough? I’ll change its title for @tedmoore :smiley:

Oh I think your post was plenty clear, but if you’re thinking about changing titles just for me, maybe you could change it to something like, “Hey Ted, here’s the thing you’re looking for”. That’s be great. Thanks.


I tried to make this work:


but it doesn’t. Then I remembered something long ago as being bad practice… and then it got cancelled it seems:

1 Like