Jump to content

Featured Replies

Posted

Here is a suggestion for posting the random seed value used by a function.

When using Open Music way back in time I remember that you could "lock" a random function if you liked the result, which IMO was a great workflow feature.

Perhaps a similar thing could be achived in Opusmodus if the random seed used for a function was posted to the post window in addition to the result of the evaluation.

If you like the result of a particular seed you could then manually "lock" the randomization using the :seed keyword for the function:

 

; first try different randomizations
(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> gen-binary-rnd :seed 752

(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> gen-binary-rnd :seed 234

; then lock seed if you like the result
(setf bin-rhythm (gen-binary-rnd 5 5 2 1) :seed 234)

 

Perhaps if possible also with the variable name as a label to keep track of things when using several random functions in complex code:

 

(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> bin-rhytm gen-binary-rnd :seed 37

 

I think that this or a similar approach would be a really powerful way of trying different results when working with randomization in Opusmodus.

 

INIT-SEED can be used at the start of algorithmic compositions employing high degrees of randomness in order to create consisted results, without having to worry about supplying seed N values to all the other functions which may also use random generation.


Example:

(setf init-seed (init-seed (rnd1 :low 1 :high 99999)))

init-seed
=> 3467

This way you can recover the initial seed if needed.

  • Author

Yes, I know about init-seed, it's great for setting the overall seed in a complete score context, I guess you mean something like this:

 

(setf seed (rnd-range 1 999999))
(init-seed seed)

(setf pitch (rnd-sample 5 '(c4 e4 g4 b4)))
(setf len (rnd-sample 5 '(s e)))

(setf phrase (make-omn
              :pitch pitch
              :length len
              ))

(def-score flute
           (
            :key-signature 'chromatic
            :time-signature '(4 4)
            :tempo 112
            :layout (flute-layout 'flt)
            )

(flt
 :omn phrase
 :channel 1
 :sound 'gm
 :program 'flute
 )
)

 

If you are happy with the result you can then evaluate the seed variable and paste the posted number into the :seed keyword in one or both of the forms including random functions and thus achieve locking one or several parameters.

 

However, if you just want to evaluate for example the 3rd line over and over again untill you find a pitch line you like, this is quite a cumbersome method.

It would be great to somehow get a report of the current internal state of a single random function, or at least be able to after evaluation get the current random state or seed used. Perhaps I'm misunderstanding something crucial regarding the way the seed functionality is implemented in OM.

  • Author

Also you can't use the method above for a single line if you want to evaluate OMN Notation (cmd + 3 or ctrl + cmd + N) at the same time (or at least I don't know how to do that).

 

(setf seed (rnd-range 1 999999))
(init-seed seed)
(setf pitch (rnd-sample 5 '(c4 e4 g4 b4)))

; Select all then Evaluate and Notation (ctrl + 3)
=> Error: The value 793536 is not of the expected type list.

 

With snippet:

(setf pitch (rnd-sample 5 '(c4 e4 g4 b4) :seed (setf seed (rnd-range 1 999999))))
=> (g4 e4 c4 b4 b4)

Test:

(rnd-sample 5 '(c4 e4 g4 b4) :seed 675029)
=> (g4 e4 c4 b4 b4)

 

Note: ctrl-3 is not for displaying numbers.

 

  • Author

Yes, of course, but in terms of workflow it isn't very practical, I think you would like to keep things separated when trying out individual lines of a score.

Is there a way of somehow getting the seed or random state used under the hood when not providing one yourself?

 

(Sorry about the typo, I meant to write Cmd + 3 in the code example, as in "OMN notation")

(defun doseed (&key seed)
        (setf seed (init-seed (rnd-range 1 999999)))
        (print seed))


(rnd-sample 5 '(c4 e4 g4 b4) :seed (doseed))

This works for me.

 

/Lasse

  • Author

Thanks for the patience and clarification Janusz, and thanks also to Lasse for the useful lisp function.

> Perhaps if possible also with the variable name as a label to keep track of things when using several random functions in complex code:

(setf bin-rhythm (gen-binary-rnd 5 5 2 1))
=> bin-rhytm gen-binary-rnd :seed 37

This should be easy to do with a revision of the macro do-verbose, but as users, we have no access to its definition to change it. (The macro would check the value of the variable seed in its environment.)

Side remark: If anyone revises do-verbose, it would be highly welcome to be able to switch off its effect altogether, because Common Lisp offers much better builtin debugging facilities than what this macro does. 

 

Anyway, here is an easy workaround for your particular situation. 

 

(setf bin-rhythm (gen-binary-rnd 5 5 2 1 :seed (print 123)))
; printed: 123 gen-binary-rnd
=> ((0 0 1 0 0) (1 0 1 0 1) (0 1 1 0 1) (1 1 0 1 1) (0 1 0 1 1))


See also the discussion in the thread linked below.

 

Best,

Torsten

 

 

On 3/31/2018 at 7:40 PM, lviklund said:

(defun doseed (&key seed)
        (setf seed (init-seed (rnd-range 1 999999)))
        (print seed))


(rnd-sample 5 '(c4 e4 g4 b4) :seed (doseed))

This works for me.

 

/Lasse

 

Below is a more secure variant of that function, which does not overwrite the seeds of all other functions. Calling init-seed is not needed here... 

 

I avoided using do in the function name, as functions/macros named such are by convention looping constructs. 

 

Best,

Torsten

 

(defun mk-seed (&optional seed)
  "Generates a random seed value, prints and returns it. Useful for exploring different results of random processes, but then keeping a found solution.

  Args:
  - seed (int): optionally fixes generated seed.

  Examples:

  (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed))
  ; 405621 rnd-sample
  => (c4 e4 d4) 

  (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed 13))
  ; 13 rnd-sample
  => (e4 d4 e4) 
  "
  (print (if seed seed (rnd-range 1 999999))))

 

On 4/6/2018 at 1:38 PM, torstenanders said:

Calling init-seed is not needed here... 

 

I guess it is, if you want to see what value init-seed gives you... Or...?

That was anyway why I did it this way.

 

Anyway, thank you again for your interesting knowledge.

 

/lasse

Citing the documentation: "INIT-SEED can be used at the start of algorithmic compositions employing high degrees of randomness in order to create consisted results, without having to worry about supplying seed N values to all the other functions which may also use random generation."

 

The function init-seed does not give you any new value actually (it just returns its argument), but in the background as a side-effect initialises the random generation of all Opusmodus random functions, so that their results are consistent on re-evaluation. 

 

Just try removing it in your function :)

 

Besides, programs that reduce any changes to global states and side effects to the absolute minimum (which is most often using no stateful programming at all) are more easy to maintain and expand. Your little function introduces two stateful operations that are not needed here: setf (better use a local let) and init-seed. (This is even more important when writing concurrent code, which can be necessary when doing real-time stuff, e.g., when you have multiple processes running in parallel changing the same global variables without further precaution.)   

 

Best,

Torsten

I found a way to display an internal seed if seed is nil (random process).

 

Example without a seed (each time different result):

(rnd-number 12 1 10)
? rnd-number :seed 678732
=> (10 6 10 6 1 9 5 6 10 2 4 2)

 

Now the same function with a manually "lock" using the :seed

(rnd-number 12 1 10 :seed 678732)
? rnd-number :seed 678732
=> (10 6 10 6 1 9 5 6 10 2 4 2)

 

(rnd-pick '((q c4 p d4 ff s a4 stacc) (s e4 app q c5 d5 pp)))
? rnd-pick :seed 598336
=> (q c4 p d4 ff s a4 stacc)

 

Screen Shot 2018-04-07 at 10.30.22.png

 

I hope everybody will be happy with the solution  :-)

To add this functionality to all the functions using random seed will take some time to do.

Hopefully tomorrow :-)

 

Best,

Janusz

  • Author

Thanks Janusz, this was exactly was what I was wishing for, really useful I think!

Create an account or sign in to comment


Copyright © 2014-2025 Opusmodus™ Ltd. All rights reserved.
Product features, specifications, system requirements and availability are subject to change without notice.
Opusmodus, the Opusmodus logo, and other Opusmodus trademarks are either registered trademarks or trademarks of Opusmodus Ltd.
All other trademarks contained herein are the property of their respective owners.

Powered by Invision Community

Important Information

Terms of Use Privacy Policy