Can you explain this a little more? I guess I don't know what a 16 step random number generator is - I assume it's a combination of a sequencer and a random number generator, but I'm not exactly clear on how you want to implement it. Walk me through its features though and we can get something going - I have a feeling like what you want to do is pretty easy :)
This is the same as the Buchla Source of Uncertainty. You have a set of random numbers and you can go through them in a random order without any member of the set recurring until all others have been selected. I'm still working on my version for audulus ;)
Sorry @biminiroad, I can explain. I'm not sure what the Bulchla one is, @RobertSyrett, it sounds correct. I'm thinking having a set of 16 numbers, 1-16 that are randomly triggered and sent to the output with no repeats until all the numbers are triggered exactly once. This module can then be input to a 16 step sequencer to create random non repeating patterns. (I guess not exactly patterns by definition...)
Here's one way to go about it. Just press the midi trigger in the corner to generate a set of random numbers. Also please excuse any labeling inconsistencies. This is a Frankenstein's monster made from pieces of the other patches I'm working on.
Dude, @RobertSyrett you are on another level! I'll dig through this and see if I can wrap my brain around it. Thanks! BTW more to come on the Time Dilator. I just wanted to add a randomizer to it.
@RobertSyrett - Very nice work, it's very good (and fast!) at coming up with random sequences, but they're not quite non-repeating. If I were to recall 16 notes in a random order with this, I think I'd need to put a floor(x) expression on the output, which would sometimes cause some of the notes in a sequence to be the same. Either that, or I took too quick of a look at your patch.
Let me keep fiddling with mine. I'm trying to create a variable probability that removes any number already chosen. So if I have three numbers left, each has a 1/3rd of a chance of getting chosen until one gets picked, then the remaining two have a 50% chance.
Ah, you need integers? Is this for your panning algorithm? Also, I get you on the 16-step repeat, let me think of a way to use the jump-to feature on that sequencer to jumble the order of the 16 steps every 16 steps.
No, not for panning. For recalling grains in a random order so it has a smoother sound rather than the washing machine effect.
Anyway, this is what I've come up with. It needs more fiddling with, since it isn't supposed to ever output a zero, and it seems to sometimes reset before getting to all 8 numbers. And also it uses a ton of CPU and I have no idea why. Maybe it's a bug?
Well I thought about this a lot and I still can't think of a way to give you a perfectly random permutation every 16 clock cycles. BUT I do like the concept of perfectly random permutations, I need to figure out how to calculate in one clock cycle how to evaluate whether a number has been chosen before in the set and to select another random step and make the same evaluation until a new step has been found.
I think the CPU usage is probably coming from the use of the z-1 node. In the documentation it seems like that node is still in beta. I guess that's why it's so rooooound, it's eaten up all the CPU. http://docs.audulus.com/nodes/#unitdelay
It's a shame the unit delay node doesn't work well. It would be really nice to reorder some calculations. It seems like the feedback delay is doing the trick though, along with some other trickery, I figured out why it was outputting a zero sometimes.
It's hard to tell if this is actually doing what I want... I can't tell if it's actually running through each number with no repeats, but I think it is pretty random regardless... Not the final version, but pretty close.
I think I have a diagnostic tool you can use, it was part of a pseudo-randomizer I thought might sound good sweeping across grains of sound. Inside there is a bit you can cut and paste that will light up if 1-16 has been selected and all lights reset right before all lights would be on.
edit: oooh it works! good job! I will have to check out that fisher-yates link.
The z-1 node has been optimized in the latest version - it actually works very efficiently - just haven't updated the docs to reflect that yet. The stuff that you're doing @RobertSyrett with delays is stuff you can do with timers and Time>Xmilliseconds functions (to "flam" the catching of random inputs). Anyway, there's a very CPU efficient way of doing this I just need to ponder it a little more. If I have everyone correct here, you have 16 outputs and you just want to reorder the integers 1-16 in random order without repetition of digits?
@SteveX - your thing is using a lot of CPU because it has a lot of logic functions stacked in it - every == and > adds up. You can also use timers instead of the z-1 to do the work of the z-1.
@biminiroad yes, basically. I'm sure there is a way cheaper way of doing this. I hope so, anyways, I'm just not a CS major. I want this to work basically like a shuffle on a CD player.
It's only one output - to be plugged into a sequencer to chose which step is to be played.
Wouldn't you need logic for every timer? I think someone made a delay based z-1 as a temp a while back, I'd have to look.
@RobertSyrett Awesome! I just realized it plays the last number of the last sequence as the first number of the next sequence, causing a repeat every 16 steps. I'll have to figure that one out...
Ok, for now, I'm happy with it. Until someone can figure out a much lower cost way of doing this, I can use this. I fixed the repeating number issue, and so now it has a 1/16 chance of repeating a number when the sequence is refreshed. I'm ok with that.
I'm close to a very efficient solution but this one is hurting my brain - here's a screenshot. This is just for 1-4 proof of concept - it will get more complicated with 1-16, but the same basic idea will bear out.
Instead of having 4 separate S&H's this allows you to make them go to just one - just looks a little tighter and more organized. eventually you'll have N-to-mono and mono-to-N which will be very helpful for large patches like this
Here ya go! I'll make one with 16 steps later - this is just proof of concept. It's very low CPU - 2% or so on my computer.
What it does is it starts with a random node and uses a kind of staggered sampling to quickly capture 4 random values. It does this by rapidly pulsing the triggers of sample & hold nodes in quick succession - the "flam" that @RobertSyrett referred to in an earlier post. It then takes those 4 numbers and sorts them from low to high and assigns a value of 1 to the low number, 2 to the next, 3 above that, and 4 to the highest value. This is regardless of the actual distance between these values. The sort module you see there is in an array that amounts to a kind of sorting algorithm. I just played around with different combinations until it worked.
It has a button to resample, but can also be clocked - the attached patch shows you one way of creatively using this to relatively quickly pull together a complex song with just a few sequencer and clock tricks.
> I'll make one with 16 steps later - this is just proof of concept.
Until then I'll just open this up in 4 windows and pretend. Sounds great actually! I will have to examine this in the morning to understand what all the parts really do though.
@stevex - it's just grabbing a number between 0 and 1 that's being produced by the random node. The number value itself is irrelevant - it's the relation between the numbers (which is the smallest, which is the largest, what values are in between) that determine the random patterning of 1,2,3,4. That's what the sorting algorithm does - it puts them in order of smallest to largest, assigns the numbers 1-4 to those numbers, then routes them to the sequencer in the order determined by their "flam" selection.
For example
Random node is spitting out 0-1 values. 4 S&H nodes are triggered in quick succession. From this you get the step and its value.
Step - Value: 1 - .35 2 - .3 3 - .9 4- .1
The High/Low algorithm sorts this list and you get:
Value - Random Number Assignment: .1 - 1 .3 - 2 .35 - 3 .9 - 4
It then references the order that the values came out originally in and substitutes the value for the random number assignment.
So the resulting sequence that you get from those original random values is: 3, 2, 4, 1
No matter what the random numbers end up being, you'll always get some kind of sequence of 1,2,3,4 as the chances of picking two identical random numbers is like 1 in several billion billion or something.
kinda...but you need to extend the sorting algorithm considerably, because you can't just replicate this x3, you have to sort them all, which makes for many more branches. I'll do it this weekend and then do a Build video where I explain it all step-by-step.
Is there a way to implement something like quicksort for n number of inputs? In a strange way, this is retrograde to the premise of Audulus, which is a visual node-based programming environment optomized for sound design. Here we are trying to go back to the 1960's in terms or rearranging arrays of data.
There is, this one is like batch sort or something? It was visually the easiest to work out for me (plus a little module that swaps low and high is pretty cool!). When sorting this few terms I dunno if there'a gonna be a significant processor savings from one algo to another.
I was just thinking that extending the same sorting process over 16 elements would create exponential spaghetti. I agree that for the 4-element version the sorting is visually legible.
@RobertSyrett It is sort of odd. A Mac mini should not be spending 2% processing power on sorting 4 numbers. I wonder if the expression library can be expanded.
@biminiroad - what I mean is, at the instant that you request a new order with a clocked input, wouldn't it fail to give you a new number until the timers have reached their first number at least? I think that's why I see a glitch in your waveform viewer every time the pattern is altered.
@SteveX - it's not just on the sorting - it's on the 4x S&H, the MIDI button, the sequencer, the truncate function, etc...Audulus is processing everything in real time which is somewhat inefficient, but it has the added advantage of being modulatable at a high rate. It's why Audulus doesn't have a Bang message. In the future we're thinking about a control signal with a lower sampling rate, but compared to the 45% CPU solutions, this is pretty efficient.
And yeah I could set the sampling there at a faster rate, but at 1/1000th of a second, it's not causing any audible change. I suppose it could just use 4 random nodes with different seeds but I just wanted to show @RobertSyrett how to "flam" the S&H's without having to use the CPU-heavy delay node. It might be a marginal improvement to use the random nodes, which might bear out over more steps (and would get rid of that little glitch problem, since they're all sampled at once).
Bangs are processed differently in that they're not sampled as frequently as audio. Right now, everything is sampled for every processor cycle, which is not quite audio rate, but very close to it. Bangs happen as interrupts (I believe, someone correct me if I'm wrong) and they use less CPU. The advantage of not having separate signal types is that everything just works together and you don't have to explain the difference between the two - it's all just numbers in, numbers out. The disadvantage is when you get down to nitty gritty DSP stuff, it can be handy to have control signals sampled less frequently.
Just realized you can't use multiple noise nodes because patterns emerge - especially if you use seeds of 1-16, but even primes! Flamming the noise node is the way to go for "true" randomness.
Done for the night - not all functions are working - the knobs are going to be for gate height so you can adjust the volume of each note individually. Just have a look inside though! Turn up the clock real high and just watch it bioluminesce...