mc. wrapper > 1024 channels PLEASE

TobyAM's icon

using mc.cycle and just discovered that the channel limit seems to be 1024, and shockingly I need upwards of 3000. Can Cycling set this limit higher please? Show me how to hack it? Workarounds for dynamically creating multiple instances if channel count exceeds.... no that sounds like a mess. Increasing the channel count is the way to go I think.

Max Gardener's icon

One question to post at this point has to do with whether or not your system is going to be happy with 3000 channels of audio....

TobyAM's icon

With a mc.cycle with 1024 channels my Max CPU use is 8%, so I certainly see no issue pushing it. I'm pushing this audio straight to a jit.matrix, so it's a pretty efficient (and silent) patch in that regard.

Max Gardener's icon

If it seemed odd that I was in "measure twice/cut once" mode there, you might be surprised that there are some folks out there who decide that they need N of something before making the effort to figure out whether their gear supports it. A corollary to this involves doing that initial survey by hooking up N of something with none of the processing they expect to be doing on the fly and then expressing consternation when the N of something winds up grinding their CPU to a halt.... :-)

TobyAM's icon

I can't imagine what it must be like to develop software like this, let alone have it be stable and work for everyone; it's amazing stuff that I appreciate in-spite of my ignorance. I've just been hacking away at this patch for years.

Maybe I'm a weirdo/ outlier. I find mc.cycle to be the most perfect, zen solution to my 'problem' of simulating stars in Jitter that all pulse uniquely. This single object is simulating all the stars' pulsations wonderfully.

I didn't mean to sound demanding! Just excited.

in this case my N is currently 3586

Roman Thilenius's icon


if it is really only used for generating a bunch of modulation data (and not part of a big, complicated audio DSP patch) you could just use 3 instances of it.

TobyAM's icon

Yes, I guess I can use 4 sets of [mc.cycle] ---> [th.mcToMatrix~] and glue the 4 resultant matrices back together, then feed to [jit.gl.multiple]. Another opportunity to learn how to do something. Or an excuse to limit the scope? hmmm

Roman Thilenius's icon


have you evaluated yet how the same patch would look using data at scheduler rate? (line -> cos -> starlight express)

TobyAM's icon

A way to have thousands of specific, unique line objects, doesn't leap to my mind, other than dynamic object creation with javascript, and I just gained efficiency by moving away from that elsewhere in my patch.

Roman Thilenius's icon


poly~ ? :)

TobyAM's icon

Hm, mc.poly~ could? Thanks Roman, this will be interesting to try. Sort of a race between Max and MSP for who approximates best galaxy of sines.

On topic of mc.cycle, I was also really excited about the possibility of thousands of unique wavetables, so I may still go that route.

Even with poly~ it seems I have to divide and conquer anyway if there are instance/voice/channel limits of 1024.

Roman Thilenius's icon


it wil be a few more objects but objects can be encapsulated or made invisible on lock.

i would just trigger the required cosine values from cos() from the video frame count.

using 300 different waveforms will be easier with cycle~, that is not so much fun using expr and gate.

and yes, poly~ has a voice limit, too, i am afraid.

TobyAM's icon

Roman, I'm unable to visualize the solution you're describing - perhaps I just don't remember the math involved well. Just to be clear - each pulse needs to have a specific, unique real-time period. Are you suggesting that coefficients can be fed into a single cos function to generate the various sine waves?

Roman Thilenius's icon


you mostly only need a cos() function (but 3000 of them not only one) and a velocity constant and then you could trigger these generators from the video frames. of course if some heavy frame jitter exists that will also be reflected in the realtime modulation messages you derived from it. though i am not so sure if you not already have the same problem with your signals anyway. because if the video frame comes late, what is the perfect calculation of the modulation value worth?

however, you would be timetagging your frames using [counter] only once.

coming from 1, 2, 3, 4, to a bunch of parallel LFOs with different speeds should be easy.

and if you get in trouble with the scheduler queue you could just add a random delay of up to 1 frame to each of the LFOs, i.e. always produce the LFO value for the next frame, not for the current.

or what about reducing the resolution to 100? should be enough for luminance levels? then you could even use a table or coll (not sure if that would be more effectice that cos)

i take note of you saying that your signal version only need 8% of the CPUatm. but i still think it might be worth comparing the attempts.

Roman Thilenius's icon


roughly

if you need a list later, use burst output from poly~ and collect values outside.

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#N vpatcher 25 70 625 470;
#P inlet 185 85 15 0;
#P outlet 98 199 15 0;
#P inlet 98 84 15 0;
#P pop;
#P newobj 470 375 74 9109513 p video;
#N vpatcher 25 70 625 470;
#P inlet 185 85 15 0;
#P outlet 98 199 15 0;
#P inlet 98 84 15 0;
#P pop;
#P newobj 388 375 74 9109513 p video;
#P user multiSlider 212 412 67 173 -1. 1. 1 2681 15 0 0 2 0 0 0;
#M frgb 0 0 0;
#M brgb 255 255 255;
#M rgb2 127 127 127;
#M rgb3 0 0 0;
#M rgb4 37 52 91;
#M rgb5 74 105 182;
#M rgb6 112 158 18;
#M rgb7 149 211 110;
#M rgb8 187 9 201;
#M rgb9 224 62 37;
#M rgb10 7 114 128;
#P newex 212 291 50 9109513 * 0.02;
#P newex 212 327 65 9109513 cos;
#P newex 127 293 50 9109513 * 0.33;
#P user multiSlider 127 412 67 173 -1. 1. 1 2681 15 0 0 2 0 0 0;
#M frgb 0 0 0;
#M brgb 255 255 255;
#M rgb2 127 127 127;
#M rgb3 0 0 0;
#M rgb4 37 52 91;
#M rgb5 74 105 182;
#M rgb6 112 158 18;
#M rgb7 149 211 110;
#M rgb8 187 9 201;
#M rgb9 224 62 37;
#M rgb10 7 114 128;
#P newex 127 329 65 9109513 cos;
#P newex 37 294 50 9109513 * 0.1;
#P user multiSlider 37 412 67 173 -1. 1. 1 2681 15 0 0 2 0 0 0;
#M frgb 0 0 0;
#M brgb 255 255 255;
#M rgb2 127 127 127;
#M rgb3 0 0 0;
#M rgb4 37 52 91;
#M rgb5 74 105 182;
#M rgb6 112 158 18;
#M rgb7 149 211 110;
#M rgb8 187 9 201;
#M rgb9 224 62 37;
#M rgb10 7 114 128;
#P newex 37 330 65 9109513 cos;
#N vpatcher 25 70 625 470;
#P inlet 185 85 15 0;
#P outlet 98 199 15 0;
#P inlet 98 84 15 0;
#P pop;
#P newobj 306 375 74 9109513 p video;
#P newex 245 84 50 9109513 t b b;
#P message 106 193 50 9109513 1;
#P button 245 35 41 0;
#N counter 0 1 1000;
#X flags 0 0;
#P newobj 41 219 122 9109513 counter 0 1 1000;
#P connect 3 0 4 0;
#P connect 3 0 14 0;
#P connect 3 0 15 0;
#P connect 11 0 13 0;
#P connect 11 0 15 1;
#P connect 8 0 9 0;
#P connect 8 0 14 1;
#P connect 5 0 6 0;
#P connect 5 0 4 1;
#P connect 0 0 7 0;
#P connect 0 0 10 0;
#P connect 0 0 12 0;
#P connect 12 0 11 0;
#P connect 10 0 8 0;
#P connect 7 0 5 0;
#P connect 3 1 0 0;
#P connect 1 0 3 0;
#P connect 2 0 0 2;
#P window clipboard copycount 16;

TobyAM's icon

I made a few optimizations and the 1024 channel mc.cycle patch is using 7% now, super stable, although with the cycle stuff deleted entirely the patch still runs at 4.5% (expected, it's big and messy). So extra 2.5% CPU for some SMOOTH pulses is a tasty option. I think I'm going to just see what mileage I can get from this for now.

TobyAM's icon

Wow, thanks for the example! Yes, I see how simple it really is after all, just multiply by the rate first. And by getting the instance number of the poly I could poke that into the appropriate matrix index. This is a great option to have!

Roman Thilenius's icon


or use vexpr, then you actually only need one. :)

TobyAM's icon

Well sir, you win. You made it so simple I couldn't not try it.
CPU use for ~ 3500 unique cycles = 0.01%
I guess I'm done. Moving on!

TobyAM's icon

scaling the speed of the pulses to a reasonable range, while keeping the native FPS, is proving difficult for me to make look good. Gonna have to circle back to this later.

Roman Thilenius's icon


u mean chaning all the times while the video plays? yeah a full initialisation of 3500 values might hit the scheduler limit, especially when your video is faster than 25 fps. if phase doesnt matter maybe you could loosen the generation of data up somehow.

TobyAM's icon

As it is driven by the jit.world bangs at 60fps everything looks smooth and great, but the flashing is all wayy too fast. I want to slow down all the cycles animation, but also restrict the upper and lower limits in a comprehensible way. I do this with a series of ease and scale objects primarily with the mc.cycle way, which works great. I just don't have the math right to scale the vexpr cos() way.

I'm moving along with mc.cycle, as I've loaded unique wavetables to all 1024 instances and it's perfect and just takes a ton of memory, no biggy for the sampler crowd (hah). I'm very excited by the results. I just have to order the polybuffer correctly.

danieleghisi's icon

Hi guys, is there an official Cycling '74 answer on why the mc limit for the number of channels is 1024, and whether there are plans to increase this limit?
Buffers can have up to 2^16 channel, which to me is AWESOME and life-saving in many non-standard applications. I just wish this was true also for the mc stuff!