NoobHowTo:: seeded random


#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.


#22

I've made a seeded random sequence generator already. Check the toneburst directory in the Contrib library :slight_smile:

a|x


My First Object - Linear Congruential Generator
#23

Here's my contribution to the subject of seeded random.

I've taken the popular Linear Congruential Generator algorithm and made it into an Axoloti patch.

Things to note:
* Quirk: The first value doesn't seem to be correct. I've tested it against some known patterns and it always seems to skip the first state but will return to it when the sequence cycles around.
* Quirk: I connected a button to where I think reset should be but it's not quite perfect. Resets sometimes and not other times.
* There are CONST boxes that set the params Seed, M, A, and B. Dials, or Fractional inputs could be used instead.
* CLOCK is a square LFO in the top left. I've built my patch to require a clock source to advance the linear algorithm to the next step.

Experiment with different SEEDS and params. There are TON of combinations possible that will produce reproducible repeating series of numbes with various periods and variety.

random-linear_congruential_generator_v2.axp (7.5 KB)

I've realized I could save some SRAM by coding this as a standard object -- I'll likely be doing that as an exercise when I have time to wrap my head around the process of coding objects.

Enjoy.


#24

I think that's the same algorithm I used, actually. As you say though, yours is a different take on the same idea.

a|x


#25

@toneburst

I looked for your lcg in the community library listing online (the one with photos) and didn't see it. Didn't look too closely in the object browser in the GUI.

What's it called?