NoobHowTo:: seeded random


#2

Is my question not clear enough or is it not possible with the Axoloti? (I dont think so :wink: )
What I need is very similar to the builtin random but with an extra seed input to control it.
Please give me a helping hand!
Cheers


#3

Sorry, I get many questions, sometimes a few escape my attention.

Of course it is possible.
It is not clear to me how much of a helping hand you expect. If you have some programming background and dissect related objects, you can figure this out. If you have relevant questions from a programmer's perspective about the code, I'll be more likely to answer.

My current development efforts go into the object editor and other deep stuff, rather than adding another object.

Perhaps others can tune in?


#4

Thank you vey much for your reply! :blush:
I am so sorry for not being clear, my english is very bad, its very hard to express myself...

So basically my main goal is to reproduce the RandomPattern module of the Nord Modular G2.
To do that I need a random function what outputs the same random value if it is feeded with the same "seed".
I made a screenshot about this, however it doesnt needs to have trig input:

Its just a very basic thing but I am stucked badly...
I have some experience with c and python, but I never compiled anything, just made shaders and scrips for 3d apps. I looked at the help patcher of the script object but its still very unclear how to -for example- sum the values of the inlets and output it...
Is there any reference or more examples how to script in the object editor or use the script object?

I welcome any suggestions to do that! I cannot go forward with my patches for days :sob:

Many thanks!


#5

Something i do in patching it's to create some complex network of lfo's (the ones with phase reset, each one with a different base pitch) and feed the output of one into another (multiplied by a constant) into the pitch input. This way i create some kind of FM synthesis, which should result in a pseudo white noise (except it's not audio rate)

If you want to vary the seed you can modify the amount of fm of some oscillators, and if you want to reset simply phase reset the oscillators.


#6

Yes :smile: I did exactly the same to get pseudorandom, but there must be an easier way to do this...
I dont want to waste cpu time with lfos, so that is why I started this topic.


#7

Ok, here is the forum thread about this:


If I use table/save I can re-use it later in different patches, so it can be satisfactory.
But I am still interested in a bit more elegant solution :sunglasses: if there is any.

In the k rate code of uniform f trig there is:
"""
if ((inlet_trig>0) && !ntrig) { val = (int32_t)(GenerateRandomNumber())>>4; ntrig=1;}
else if (!(inlet_trig>0)) ntrig=0;
outlet_rand= val;
"""
Can I duplicate the object and modify it somehow to get the solution ?


#8

Basically you want to replace the call to GenerateRandomNumber() with some pseudo-random number generator (PRNG) for which you control the seed. Probably it's easiest to implement it directly in the object code. I don't know much about PRNG's, but something like this seems simple and sufficient, and should not be too hard to port to axoloti:

Obviously you need a little bit of understanding of the axoloti objects and datatypes, but I think you can learn that by looking at other objects and from posts in the forum (I haven't tried myself to code anything in axoloti so I can't just give you step-by-step solution, sorry)


#9

@skogn did you get this working? I'd love to see a version of the NM Pattern module for the Axoloti, too.

a|x


#10

Here's an algorithm for a seeded random number generator in JavaScript:

/// http://indiegamr.com/generate-repeatable-random-numbers-in-js/

// the initial seed
seed = 6;

// in order to work 'seed' must NOT be undefined,
// so in any case, you HAVE to provide a seed
seededRandom = function(max, min) {
	max = max || 1;
	min = min || 0;

	seed = (seed * 9301 + 49297) % 233280;
	var rnd = seed / 233280;

	return min + rnd * (max - min);
};

It should be possible to feed different seed numbers to that, in order to get pseudo-random sequences. I seem to remember the NM Pattern Gen having 127 x127 (16,129 total) patterns.

I think I will give this a try myself. This could be a good starter me in producing custom Axoloti objects. I have a few slightly more complicated ideas, but this would be a good stepping-stone to achieving them, I think.

Cheers,

a|x


#11

Having said all that, isn't the 'lfsrseq' object pretty much what we're both looking for?
Maybe this was made in response to this thread.

Could someone explain the what the 'lval' input on this object is for?

a|x


#12

To answer the above- it's not. 'lfsrseq' seems to be a shift-register sequencer, than outputs triggers, rather than continuous values (like say, the Turing Machine Eurorack module).

a|x


#13

@skogn Try this (my first custom Axoloti Object :smile: ).

a|x

nmpgen.axo (2.9 KB)


#14

Code for the above, in case you're interested.

<objdefs appVersion="1.0.8">
    <obj.normal id="tbnmpgen" uuid="f4aa3eb163415b6fc796e576dde754a273a022ac">
        <sDescription>Pseudo-random (repeatable) pattern generator. Based on Nord modular PatternGen module.</sDescription>
        <author>toneburst</author>
        <license>BSD</license>
        <inlets>
            <bool32.rising name="trig" description="Trigger Pulse" />
            <bool32.rising name="r" description="Reset Pulse" />
        </inlets>
        <outlets>
            <frac32.bipolar name="out" description="Pattern Out (Bipolar)" />
        </outlets>
        <displays />
        <params>
            <frac32.u.map name="bank" description="Bank" />
            <frac32.u.map name="pattern" description="Pattern" />
        </params>
        <attribs>
            <spinner name="length" description="Pattern Length" MinValue="0" MaxValue="128" DefaultValue="16" />
        </attribs>
        <code.declaration><![CDATA[

int32_t pattern[128] = {};
int32_t counter 0;
int ntrig = 0;
int rtrig = 0;
int32_t bindex;
int32_t pindex;
int32_t outval;
int init = 1;

/////////////////////////////////////////////////////////////////////////
// Seeded Random Number Generator ///////////////////////////////////////
// http://blog.embedded-office.com/en/blog-artikel/items/random-1.html //
// (cryptographically rubbish, but should be fine for our porpoises) ////
/////////////////////////////////////////////////////////////////////////

int32_t rstate = 1;

int32_t updatestate() {
	int32_t a = 5;
	int32_t b = 12345;
	int32_t m = 511;
	rstate = ((rstate * a + b) % m) - 255;
	return rstate;
}

//////////////////////////
// Update Pattern Array //
//////////////////////////

void newpattern(int32_t a, int32_t b, int len) {
	rstate = a * 64 + b;
	for(int i = 0; i < len; i++) {
		pattern[i] = updatestate();
	}
}

        ]]>
        </code.declaration>
        <code.krate><![CDATA[

///////////////////////////////
// Loop Running For 1st Time //
///////////////////////////////

if (init) {
	newpattern(param_bank, param_pattern, attr_length);
	init = 0;
}

///////////////////////////////
// Trigger Input Rising Edge //
///////////////////////////////

if ((inlet_trig>0) && !ntrig) {
    // Check for changes to parameters
    // and regenerate array if params changed
	if ((param_bank != bindex) || (param_pattern != pindex)) {
		newpattern(param_bank, param_pattern, attr_length);
		bindex = param_bank;
		pindex = param_pattern;
	}
    // Update/reset counter
    counter = (counter>attr_length)? 0 : counter + 1;
    // Set output value until next trigger
    outval = pattern[counter];
    ntrig=1;
} else if (!(inlet_trig>0)) {
    ntrig=0;
}

/////////////////////////////
// Reset Input Rising Edge //
/////////////////////////////

if ((inlet_r>0) && !rtrig) {
    rtrig = 1;
    counter = 0;
} else if (!(inlet_r>0)) {
    rtrig=0;
}

outlet_out = outval<<19;

    ]]>
    </code.krate>
    </obj.normal>
</objdefs>

a|x


#15

this is better off in the community library...
then if you refine it, users will automatically get the latest and greatest


#16

Good time to learn to use the library, then!

How do I get Push access to the repo on Github (here, I presume)?
I have a github account with id 'toneburst'.

a|x


#17

I have added you to the collaborator list.


#18

Thanks johannes. I now realise thetechnobear meant the User Contributions forum here, rather than the one on GitHub.

I'm happy to be involved in that too, though.

a|x


#19

No, I meant github via Axoloti 1.0.8 UI, see here : https://sebiik.github.io/community.axoloti.com.backup/t/about-the-community-library-category/1005


#20

Thanks for the link. I'll read through that now.

Cheers,

a|x


#21

late reaction, but the easiest fix, I think, is to generate a random integer list with a random generator from the internet, then put this in an array like:
int32_t seededRandom[2048]={543663,8268463,4372,7375,828,,,,,,,,,,etc,,,,,,,,325674;}
then generate a new array from this with a for-loop:
if(update>0)
{
for(i=0;i<64;i++)
for(i=0;i{int16_t pas=(SMMUL(i<SMMUL(i<arrey[i]=seed[pas]<

//next one uses a "smooth" over the update of an array, smoothly fading from the old array in pesition into Position.
pesition[i]=pesition[i]+___SMMUL((Position[i]-pesition[i])<}

where seed1 functions as an offset to the readout position of the array and seed2 controls how it steps through the array. the "/2048)*2048 limits the random selection to the 2048 points in the array and wraps back to zero if it would have gone over.