Max inside SuperCollider?

Hi, I just see this in the cycling74 site !
Maybe a lots of new thinks porting some of Max’s world into SC!

All the best,

José

Huh. It makes sound for me, though I can’t adjust the frequency and it sounds like trash. I guess it is a proof of concept, and the concept is impressive. Honestly, I am a bit annoyed at how slick it is.

Sam

Same here… I can’t adjust the frequency and the resulting sound is different than on Max… Needs to be improved but looks very promising! An export directly to SC like faust2supercollider is also needed :slight_smile:

I wish there could be a C++ blueprint for exporting arbitrary RNBO code to SC.
Currently the buffer size / block size is hardcoded with 512 samples (see line 35). rnbo.example.supercollider/src/RnboSaw.cpp at main · Cycling74/rnbo.example.supercollider · GitHub
Would you know how the samplerate and buffersize could be calculated according to the user settings in SC?
The changing of params would also have to be implemented, the freq is fixed at its initial value of 200 hz from the RNBO patch.

1 Like

+1 - I also have a bunch of ~gen patches that I’d really like to export to supercollider via RNBO.

Also needed is how to assign buffers from SC to the RNBO Ugen (for sample based patches etc.).

1 Like

Ive raised two issues on github. Yesterday there was another fix.
You can now initialise the exported RNBOSaw with a specific frequency, but cannot change it dynamically.
It still remains a proof of concept.

The samplerate and blocksize seem also to work properly (no jitter).

(
{
	var freq = MouseX.kr(20, 4000);
	//var sig = RnboSaw.ar(freq.poll); // freq cant be changed after beeing initialised
	var sig = RnboSaw.ar(220); // is correctly initialised with freq of 220 hz
	sig!2 * 0.1;
}.play;
)

I guess we would need a group of people which works on more details of the C++ template. Unfortunately im not a C++ programmer, but would support the project with some money if needed. What do you think?

3 Likes

Agree, I would support this hypothetical project too. I guess a bit of a niche one to do correctly because it requires decent knowledge of sc+rnbo+cpp.

I reckon it’d be possible to work out by cobbling together some of the Ugen c++ tutorials combined with this template, but I don’t have the time at the moment try it out.

2 Likes

Which tutorials do you mean ? I could have a first look.

maybe this?

1 Like

thanks alot :slight_smile: currently reading :slight_smile:

1 Like

I have read through the example tutorial, thanks for sharing.

What would you suggest from now?
Should we compare the rnbosaw template implementation with the tutorial example? Do you have other resources to look at?

I think the following functionality is missing in the rnbosaw example template (list incomplete):

  • ensure initialisation for params
  • ensure control rate control for params
  • ensure audio rate control for rnbo inlets
  • ensure demand rate control for rnbo inlets
  • make buffers from rnbo available
  • ensure single channel out (Ugen)
  • ensure multichannel outs (MultiOutUGen)

how would lists from max are handled which should be loaded into buffers to be available in gen~?

Those sound like good ideas. I think if this becomes a project it could be a fork of the repo with minimum viable Ugens for:

  • Basic oscillator (like rnbo saw)
  • Basic sample player
  • Some sort of effect demonstrating audio passthrough
  • maybeeee a ‘midi’ or event Ugen - No idea how this would work

I can’t promise I’m the best person to help with this but we could try at some point.

Also, idk if you noticed but at your issue on the github here Can’t change frequency of rnbo saw · Issue #3 · Cycling74/rnbo.example.supercollider · GitHub

they linked to their implementation of RNBO in unreal/metasounds as a template GitHub - Cycling74/RNBOMetasound: RNBO adapter that implements metasound nodes

I guess we would at least need one person who is an experienced c++ programmer. The SC and RNBO side could probably be covered.

1 Like

is it necessary to declare a buffer, i guess for every control block, like its done in the rnbosaw example?

i cant find such a decleration in the rampugen from the SC server plugins example.

It looks like you need the buffer for RNBO to return the nSamples that are its output.

The buffer is declared in the constructor and freed in the destructor, as it should be.

Sam

Most SC UGens write directly, incrementally, to the output wire buffer, e.g. (Ramp) – LOOP(nsmps, ZXP(out) = level; level += slope;); – where ZXP(out) = ... is the output stage.

I guess the buffer is a bridge between the RNBO way and the SC way, “necessary” for RNBO’s structure but not strictly needed. (I.e. the RNBO auto-generated code isn’t maximally efficient.)

hjh

hey, thanks for your replies. So for every output audio channel of the RNBO object I would need to declare a buffer with the length of one control block? So for single channel outs (Ugen) you would need one buffer and for multichannel outs (multiOutUGen) you would need n buffers?
Should the hardcoded value of 512 in the example therefore be changed to bufferSize() ?

Would somebody know if the scope operator does access the number of samples or the duration of one sample of the RNBO object with sizeof(RNBO::SampleValue *) or something else?

Currently looking at this helpfile How to Include RNBO in Your C++ Project | Cycling '74 and the C++ API reference RNBO C++ API Reference | Cycling '74

This depends on how rnbo handles multichannel in and out. Is there a good example of that to look at?

Sam

Here is some information about the ins and outs, not really helpful though.

The initial patch from the rnbo example “RNBOSaw” does actually have two outputs:
grafik

doesnt this code actually create n buffers?

    buf = (RNBO::SampleValue **)RTAlloc(mWorld, sizeof(RNBO::SampleValue *) * rnboObj.getNumOutputChannels());
    for (int i = 0; i < rnboObj.getNumOutputChannels(); i++) {
        buf[i] = (RNBO::SampleValue *)RTAlloc(mWorld, sizeof(RNBO::SampleValue *) * 512);
    }

I guess the .sc class from the example should then inherit from MultiOutUgen instead of Ugen to make the second output available. Currently its:

RnboSaw : UGen {
	*ar { arg freq = 440.0;
		^this.multiNew('audio', freq);
	}
}

But thats not really answering the question.

It creates a multidimensional array of [numChannels][numSamples].

So that is pretty straightforward. I wasn’t sure if it was interleaved or something.

Sam