Hi Dario,

On 5/6/21, Dario Sanfilippo <sanfilippo.da...@gmail.com> wrote:
> Even if calling an external random function, don't you always have the
> problem of calling it with a different seed each time to get a different
> stream at each run?

Attached is my code relating to this. There's a c++ function, which
takes a dummy argument and returns a random value, and two faust
randomness functions which take such a random value as a seed. One is
a continuous noise function (like no.noise), and the other one takes a
trigger and outputs a new random value when triggered. (rn.dsp should
really be called rn.lib, but I had to rename it to defeat some weird
filtering gmail applies to attachments.)

These output in the full integer range, so I also included some
scaling functions, rndscale, which takes a maximum value to scale its
input down to, and rndtorange, which takes a maximum and minimum. And
there are rndscaleint and rndtorangeint which take the same arguments
and output integers.

Usage would be something like:

// continuous (white) noise
import("rn.lib");
process = rnd(0) : intnoise : rndtorange(10, 20);

// triggered noise
ba = library("basics.lib");
trig = ba.pulse(2);
process = rnd(0),trig : rng : rndtorange(10, 20);

// multiple noise streams (note distinct dummy arguments for distinct
calls to rnd)
process = first,second,third with {
    first  = rnd(0) : intnoise : rndtorange(10, 20);
    second = rnd(1) : intnoise : rndtorange(10, 20);
    third  = rnd(2) : intnoise : rndtorange(10, 20);
};

I remembered why I found that it was better to just use foreign
functions for a seed, and then iterate on that seed with faust
functions: faust will treat a function with constant inputs as having
a constant output. In other words, it won't actually call a foreign
function more than once over time if its inputs are constant.

Hope that helps. Let me know if you've any questions.

Cheers,
James
/*

TODO seems to work, but check that this actually returns different random values i) each call per run ii) each run?
i.e. by playing an osc of given freq

TODO rewrite comments, incl. why we don't just export the seed itself here any more (seemed like a good idea at the time)

provides a random seed
used in random.lib to init PRNG
32-bit really random unsigned int, 0 <= output <= UINT_MAX
but expensive, so only use it as an fconstant to seed a PRNG
see that file for a few words on why only pass the seed into faust as opposed to using a PRNG in c++

if you wanna test it:

#include <iostream>
#include <climits>
#include <bitset>
std::cout << std::bitset<32>(UINT_MAX).to_string() << '\n';
std::cout << std::bitset<32>(re.min()).to_string() << '\n';
std::cout << std::bitset<32>(re.max()).to_string() << '\n';
std::cout << std::bitset<32>(re()    ).to_string() << '\n';

*/

/*
default_random_engine max: 2147483646 (01111111111111111111111111111110)
default_random_engine min:          1 (00000000000000000000000000000001)
                 UINT_MAX: 4294967295 (11111111111111111111111111111111)
*/

#include <random>

// call from faust as ffunction(int re(), "random_seed.h", ""), i.e. by calling random_engine's operator function
// random_device initialised to call its operator function (for a single, truly random seed value) then discarded;
// (the extra brackets are necessary to parse the double-call)
static std::default_random_engine re((std::random_device())());

int rnd(int dummy) {
	/* int r = re() << 1;
	printf("dummy %d; returning %d\n", dummy, r);
	return r; */
	// shift left as default_random_engine's output is always positive (1 <= x <= INT_MAX)
	return re() << 1;
}

Attachment: rn.dsp
Description: Binary data

_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to