torstenanders

Members
  • Content count

    164
  • Joined

  • Last visited

  • Days Won

    16

torstenanders last won the day on April 22

torstenanders had the most liked content!

About torstenanders

  • Rank
    Advanced Member

Contact Methods

  • Website URL
    www.torsten-anders.de/

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

773 profile views
  1. Thanks. For completeness, below is a link to another rnd-pick variant with probability support. Best, Torsten
  2. Sorry -- this is really about single-nested alternatives for rnd-pick, not a double nested lists. Torsten
  3. Thanks! Torsten
  4. Is there perhaps a way to specify different noteheads as articulation, or is this perhaps planned for the future? For example, diamond, triangle, cross, accent shape etc. are used in contemporary music, e.g., to indicate certain playing techniques. Just asking Thanks! Best, Torsten
  5. Sorry, you seemingly just misread my question These double nested lists are single-nested alternatives for rnd-pick, but rnd-pick by default removes the nesting. (rnd-pick '(((h q) (h)) ((h. q) (h)) ((h. h) (h)))) => (3/4 1/4 1/2) Stephane pointed out that this can be avoided by setting the argument :encode to nil, but if others later run into this problem again this is still not explained in the documentation. I would argue that the default behaviour should be to preserve the (single) nesting, should it not? > In OM we don't use double nested list. > what is the purpose of this. This was not my question here, but I actually do use further nesting levels occasionally to represent additional information for intermediate processing, e.g., for representing sections Best, Torsten
  6. Great, thanks! I somehow missed omn-replaced. Torsten
  7. I want to manually revise some score, but I would get lost in a very long list of OMN data. So, I automatically added bar number comments to the pretty printout -- helps me a lot :) (pprint-part '((s g1 ff gs1 p a1 ff b1) (s c2 mf cs2 ff d2 e2 mf) (e f2 p s fs2 ff g2 p a2) (s b2 mf e c3 s cs3 ff eb3) (s e3 mf f3 ff fs3 p a3 mf) (s bb3 ff b3 e c4 p s e4) (e e4 ff s f4 e s b4 p) (e b4 s s mf e fs5 ff) (s fs5 mf f5 p mf e cs6) (s cs6 c6 p e b5 mf s g6 ff) (s g6 p ff e f6 g6 mf) (s g6 g6 p ff e fs6) (s g6 mf p e s fs6) (s fs6 fs6 ff mf ff) (e fs6 p s ff fs6 fs6 mf) (s fs6 fs6 ff p f6) (s fs6 ff mf e e f6) (s f6 e fs6 fs6 p s f6) (s f6 mf fs6 fs6 p f6) (e f6 f6 ff s fs6 p f6 ff) (s f6 p e s s) (s f6 e mf p s ff) (s f6 mf p mf e ff) (s f6 p e s mf p) (s f6 ff e mf s e p) (e f6 s e ff mf) (s f6 p mf e6 ff f6 p) (s f6 ff e6 mf e eb6 p f6 mf) (s f6 e6 d6 f6) (s f6 e6 ff d6 e f6 p) (s f6 mf e6 ff cs6 f6 mf) (s f6 ff f6 cs6 mf f6 ff) (e f6 mf s s cs6 p fs6 mf) (s f6 ff e e6 p s bb5 mf f6) (s e6 p b5 f5 eb6) (s bb5 fs5 ff e cs5 p s a5 mf) (e e5 ff s c5 e gs4 mf s d5) (e bb4 s fs4 d4 e g4) (s e4 ff d4 b3 mf e eb4) (s cs4 p bb3 mf e gs3 p s c4 ff) (s a3 a3 mf e b3 ff gs3) (s bb3 c4 d4 e b3 mf) (s cs4 p eb4 mf e f4 p s eb4 ff) (s e4 fs4 gs4 p fs4 ff) (e g4 p s a4 mf bb4 a4) (s bb4 c5 cs5 p c5 mf) (s cs5 eb5 ff e e5 mf eb5 ff) (s e5 mf e fs5 g5 p s fs5 ff) (s g5 mf gs5 a5 p a5) (e bb5 ff b5 mf s c6 ff c6))) => ? ( ;; Bar 1 (s g1 ff gs1 p a1 ff b1) ;; Bar 2 (s c2 mf cs2 ff d2 e2 mf) ;; Bar 3 (e f2 p s fs2 ff g2 p a2) ;; Bar 4 (s b2 mf e c3 s cs3 ff eb3) ;; Bar 5 (s e3 mf f3 ff fs3 p a3 mf) ;; Bar 6 (s bb3 ff b3 e c4 p s e4) ;; Bar 7 (e e4 ff s f4 e s b4 p) ;; Bar 8 (e b4 s s mf e fs5 ff) ;; Bar 9 (s fs5 mf f5 p mf e cs6) ;; Bar 10 (s cs6 c6 p e b5 mf s g6 ff) ;; Bar 11 (s g6 p ff e f6 g6 mf) ;; Bar 12 (s g6 g6 p ff e fs6) ;; Bar 13 (s g6 mf p e s fs6) ;; Bar 14 (s fs6 fs6 ff mf ff) ;; Bar 15 (e fs6 p s ff fs6 fs6 mf) ;; Bar 16 (s fs6 fs6 ff p f6) ;; Bar 17 (s fs6 ff mf e e f6) ;; Bar 18 (s f6 e fs6 fs6 p s f6) ;; Bar 19 (s f6 mf fs6 fs6 p f6) ;; Bar 20 (e f6 f6 ff s fs6 p f6 ff) ;; Bar 21 (s f6 p e s s) ;; Bar 22 (s f6 e mf p s ff) ;; Bar 23 (s f6 mf p mf e ff) ;; Bar 24 (s f6 p e s mf p) ;; Bar 25 (s f6 ff e mf s e p) ;; Bar 26 (e f6 s e ff mf) ;; Bar 27 (s f6 p mf e6 ff f6 p) ;; Bar 28 (s f6 ff e6 mf e eb6 p f6 mf) ;; Bar 29 (s f6 e6 d6 f6) ;; Bar 30 (s f6 e6 ff d6 e f6 p) ;; Bar 31 (s f6 mf e6 ff cs6 f6 mf) ;; Bar 32 (s f6 ff f6 cs6 mf f6 ff) ;; Bar 33 (e f6 mf s s cs6 p fs6 mf) ;; Bar 34 (s f6 ff e e6 p s bb5 mf f6) ;; Bar 35 (s e6 p b5 f5 eb6) ;; Bar 36 (s bb5 fs5 ff e cs5 p s a5 mf) ;; Bar 37 (e e5 ff s c5 e gs4 mf s d5) ;; Bar 38 (e bb4 s fs4 d4 e g4) ;; Bar 39 (s e4 ff d4 b3 mf e eb4) ;; Bar 40 (s cs4 p bb3 mf e gs3 p s c4 ff) ;; Bar 41 (s a3 a3 mf e b3 ff gs3) ;; Bar 42 (s bb3 c4 d4 e b3 mf) ;; Bar 43 (s cs4 p eb4 mf e f4 p s eb4 ff) ;; Bar 44 (s e4 fs4 gs4 p fs4 ff) ;; Bar 45 (e g4 p s a4 mf bb4 a4) ;; Bar 46 (s bb4 c5 cs5 p c5 mf) ;; Bar 47 (s cs5 eb5 ff e e5 mf eb5 ff) ;; Bar 48 (s e5 mf e fs5 g5 p s fs5 ff) ;; Bar 49 (s g5 mf gs5 a5 p a5) ;; Bar 50 (e bb5 ff b5 mf s c6 ff c6) ) I revise only a single part at a time, as I will also re-bar the music. If I later want to update bar number comments, I can just call pprint-part on the result again. BTW: get-time-signature is useful to extract the time signatures for def-score from the part data. The function pprint-part is defined below. Best, Torsten ;; based on https://groups.google.com/forum/#!topic/comp.lang.lisp/_NP7Ub6hLsE (setf *print-pretty* t *print-miser-width* 0 *print-right-margin* 80) (defun pprint-part (part &optional (stream *standard-output*)) "Pretty prints a part one bar a time, adding a bar line comment before each bar. Args: part: nested OMN list. Example: (pprint-part '((q c4 d4 e4) (h f4 q e4) (h. d2)))" (pprint-logical-block (stream nil :prefix "(" :suffix ")") (pprint-logical-block (stream part) (loop for bar-no from 1 to (length part) for bar in part do (progn (pprint-indent :block 1 stream) (pprint-newline :mandatory stream) (format stream ";; Bar ~A" bar-no) (pprint-newline :mandatory stream) (prin1 bar stream)))) (pprint-indent :block -1 stream) (pprint-newline :mandatory stream)))
  8. BTW, add-omn could also be used to replace some parameter in an existing OMN form, which would be very welcome – it opens up convenient ways to vary music snippets. Torsten
  9. Dear Janusz, Opusmodus is already flexible enough to notate incomplete OMN forms like the following, even though the pitch is missing. '(h mp pizz) Because this expression is no complete OMN, omn-formp returns nil. (omn-formp '(h mp pizz)) => nil However, it would be useful to still be able to disassemble this expression. Currently disassemble-omn returns an error, because the pitch is missing. However, if such expression can even be notated, then why not allowing to also disassemble it as follows. (disassemble-omn '(h c4 mp pizz)) ; desired output -- currently error is caused => (:length (1/2) :velocity (mp) :articulation (pizz)) ; alternative -- likely default pitch needed for consistency => (:length (1/2) :pitch (c4) :velocity (mp) :articulation (pizz)) I am asking for this, because that would allow to implement functions that can build up OMN forms incrementally (as an alternative to make-omn), increasing flexibility. Here is an example of a not yet existing function demonstrating what I am talking about. It would complement the function edit-omn I was proposing earlier today. (add-omn :pitch '(g4 a4) '((q f pizz) (h arco))) => ((q g4 f pizz) (h a4 arco))) What do you think? Thanks! Best, Torsten
  10. Edit: Here are slight variations of these functions that now support arbitrary OMN input -- more useful for varying the dynamics in full snippets directly :) Note that these definitions depend now also on my function edit-omn. Best, Torsten (defun velocity-add-aux (offset velocities &key (simplify T)) (velocity-transform #'vector-add (list (get-velocity velocities) (if (listp offset) (mapcar #'get-velocity offset) (list (get-velocity offset)))) :simplify simplify)) (defun velocity-add (offset velocities &key (simplify T)) "Adds an offset to a list of OMN velocities. Quasi the dynamics equivalent of pitch transposition. Args offset: an offset added to `velocities', can be numeric (between 0 and 1) or a velocity symbol (e.g., pp), and also a list of either. velocities: list of velocities, can be nested. simplify (default T): whether or not to simplify cresc. and dim. in the result with simplify-dynamics. Examples (velocity-add 0.1 '(mf> > > > > pp)) => (f> > > > > p) (velocity-add 'pppp '(mf> > > > > pp)) => (f> > > > > p) (velocity-add 0.1 '((mf> > >) (> > pp))) => ((f> > >) (> > p)) (velocity-add '(0.1 0.2 0.3 0.4 0.5 0.6) '(mf> > > > > pp)) => (f< < < < < ffff) ; omn input (velocity-add 0.1 '((e c4 p< d4 < e4 mf< f4 < g4 f))) " (edit-omn :velocity velocities #'(lambda (vs) (velocity-add-aux offset vs :simplify simplify)))) (defun velocity-smooth-aux (alfa velocities &key (simplify T)) (velocity-transform #'vector-smooth (list alfa (get-velocity velocities)) :simplify simplify)) (defun velocity-smooth (alfa velocities &key (simplify T)) "Smoothes velocity values. Args alfa: parameter controlling the degree of exponential smoothing (usually 0 < alpha < 1). velocities: list of velocities, can be nested. simplify (default T): whether or not to simplify cresc. and dim. in the result with simplify-dynamics. Example (velocity-smooth 0.7 '((ppp p mf ff p< < <) (fff> > f><p ff mf p ppp))) => ((ppp< < < mp< < mp< <) (f< ff> > < ff> > mp)) (velocity-smooth 0.2 '((ppp p mf ff p< < <) (fff> > f><p ff mf p ppp))) => ((ppp< < < < < < <) (< mf mf mf mf mf mf)) " (edit-omn :velocity velocities #'(lambda (vs) (velocity-smooth-aux alfa vs :simplify simplify))))
  11. It is highly useful to have functions that support the full OMN language, because they allow us transform rich music snippets with all parameters. On the other hand, it is easier to define functions for individual parameters. So, why not having a function that automatically adds OMN support (including nested lists) for a function transforming only a single parameter. Here is an example. Lets assume you want to roll your custom pitch transposition function. I choose this example, because everyone hopefully understands that very easily, and can then use this overall approach for their user functions. This demonstration function expects a list of pitch symbols and a numeric transposition interval -- it returns the transposed pitches. Here is the definition of this auxiliary function and a test. (defun my-transposition-aux (interval pitches) (midi-to-pitch (loop for p in (pitch-to-midi pitches) collect (+ p interval)))) ; test (my-transposition-aux 7 '(c4 e4 g4)) ; => (g4 b4 d5) Now, lets generalise this function to support arbitrary OMN input, including nested lists. Some background info for less experienced Lisp programmers: we need to give the new function edit-omn (defined below) as an argument another computer program -- another function. This function does not even have its own name, because it is not a big deal -- it is therefore a lambda expression (an anonymous function, for more on this see http://www.gigamonkeys.com/book/functions.html). (defun my-transposition (interval omn) (edit-omn :pitch omn #'(lambda (ps) (my-transposition-aux interval ps)))) ; my-transposition now "magically" supports arbitrary OMN expressions including nested lists and rests (my-transposition 7 '((q c4 mp -q q e4 q f4) (h g4 tr2))) ; => ((q g4 mp - b4 c5) (h d5 mp tr2)) Below this message is the definition of edit-omn. As you can see, it is not a big deal either (the doc string is much longer than the definition), but hopefully useful. Best, Torsten (defun edit-omn (type notation fun &key (flat T)) "Use function `fun', defined for transforming individual OMN parameters of `type' (e.g., :length, or :velocity) to transform omn expression `notation'. This function is intended as a convenient way to generalise functions your functions to support omn notation as input. Args type: a keyword like :length, :pitch, :velocity, :duration, or :articulation (any keyword supported by function omn or make-omn). fun: a function expecting a parameter sequence of given type. It is sufficient to support only a flat input list, support for nested lists is added implicitly. notation: a omn sequence (can be nested). flat (default T): whether or not `fun' expects a flat input list. Example: roll your own transposition supporting omn input ; first aux def supporting only pitches (defun my-transposition-aux (interval pitches) (midi-to-pitch (loop for p in (pitch-to-midi pitches) collect (+ p interval)))) ; test (my-transposition-aux 7 '(c4 e4 g4)) ; => (g4 b4 d5) ; variant supporting also omn expressions (defun my-transposition (interval omn) (edit-omn :pitch omn #'(lambda (ps) (my-transposition-aux interval ps)))) ; test with nested OMN including a rest (my-transposition 7 '((q c4 mp -q q e4 q f4) (h g4 tr2))) ; => ((q g4 mp - b4 c5) (h d5 mp tr2)) " (let ((params (omn nil notation))) (apply #'make-omn (append (list type (span notation (funcall fun (if flat (flatten (getf params type)) (getf params type))))) (remove-property type params))))) ;; Auxiliary definition (defun remove-property (property property-list) "Removes a property and its value out of a property list" (let ((pos (position property property-list))) (if pos (append (subseq property-list 0 pos) (subseq property-list (+ pos 2))) property-list))) ; (remove-property :test '(:a 1 :test 2 :x 3)) ; => (:A 1 :X 3)
  12. Ah, brilliant. Sorry, I did not realise that this was an argument shared by many functions (like section, seed, or flat), which is therefore not documented. Just noticed the function encode-seq -- is that related to this argument? I understand that this function only removes repeat symbols, which I agree would be useful to do by default. However, encode-seq does not flatten the given lists, while rnd-pick does. That was my actual stumbling block here. (encode-seq '((h. q) (h))) => ((3/4 1/4) (1/2)) (rnd-pick '(((h q) (h)) ((h. q) (h)) ((h. h) (h)))) => (3/4 1/4 1/2) Does it really make sense to flatten the output of rnd-pick by default, or is that perhaps a mistake? Thanks again! Best, Torsten
  13. Dear Janusz, The richness of the dynamics symbols in OMN is great. In terms of hair pins, what we already have are the plain hair pins < and > as well as symbols that end with a hairpin, e.g., p<, or f> – besides all those one-note dynamics. Nevertheless, perhaps this set could be slightly extended even further (now I am getting greedy :) If we want to express that some crescendo or diminuendo, which started on an earlier note, continues until the end of the current note, then we would need symbols that we don't have yet, like the following, <p, <f, >p, >f, i.e., symbols that start with a hairpin. Would you agree that these would be useful to add (in the medium or long term)? With such additional symbols, also some already existing dynamics transformations could also be implemented more consistently. For example, currently velocity-variant and friends works as follows. (velocity-variant '(mf> > > > > pp) :variant 'r) => (pp < < < < mf<) A more consistent result would be the following, but the symbol <mf is not supported yet. (pp < < < < <mf) Thanks! Best, Torsten
  14. It is nice to have velocity transformation functions like velocity-variant and friends, but I would like to go further. How about being able to easily increasing or decreasing the overall volume (basically a dynamics/velocity transposition), or to smoothen dynamics differences in order to create dynamics variations in the composition process? Here are two examples. (velocity-add 0.1 '(mf> > > > > pp)) => (f> > > > > p) (velocity-smooth 0.7 '((ppp p mf ff p< < <) (fff> > f><p ff mf p ppp))) => ((ppp< < < mp< < mp< <) (f< ff> > < ff> > mp)) Below is an implementation of these functions. Further functions like this can now easily be implemented with velocity-transform. The principle idea is to transform OMN velocities into a numeric OMN vector (list), and do whatever transformation you want to do on that vector, and finally to transform the result back into OMN velocities. The details are explained in the comment string of the functions below. Note that these definitions depend on my function simplify-dynamics. Best, Torsten (defun velocity-transform (fun args &key (simplify T)) "Higher-order function for transforming velocities by processing them as an Openmodus vector in the background. Args fun: a function expecting a vector and possibly more arguments. args: the arguments for `fun'. Velocities should be explicitly transformed into numeric values. Example: (get-velocity '(mf> > > > > pp)) simplify (default T): whether or not to simplify cresc. and dim. in the result with simplify-dynamics. Example (velocity-transform #'vector-add (list (get-velocity '(mf> > > > > pp)) '(0.1)))" (let* ((vel-vector (apply fun args)) (result (velocity-to-dynamic (vector-to-velocity (apply #'min vel-vector) (apply #'max vel-vector) vel-vector)))) (if simplify (simplify-dynamics result) result))) (defun velocity-add (offset velocities &key (simplify T)) "Adds an offset to a list of OMN velocities. Quasi the dynamics equivalent of pitch transposition. Args offset: an offset added to `velocities', can be numeric (between 0 and 1) or a velocity symbol (e.g., pp), and also a list of either. velocities: list of velocities, can be nested. Examples (velocity-add 0.1 '(mf> > > > > pp)) => (f> > > > > p) (velocity-add 'pppp '(mf> > > > > pp)) => (f> > > > > p) (velocity-add 0.1 '((mf> > >) (> > pp))) => ((f> > >) (> > p)) (velocity-add '(0.1 0.2 0.3 0.4 0.5 0.6) '(mf> > > > > pp)) => (f< < < < < ffff) " (span velocities (velocity-transform #'vector-add (list (get-velocity (flatten velocities)) (if (listp offset) (mapcar #'get-velocity offset) (list (get-velocity offset)))) :simplify simplify))) (defun velocity-smooth (alfa velocities &key (simplify T)) "Smoothes velocity values. Args alfa: parameter controlling the degree of exponential smoothing (usually 0 < alpha < 1). velocities: list of velocities, can be nested. Example (velocity-smooth 0.7 '((ppp p mf ff p< < <) (fff> > f><p ff mf p ppp))) => ((ppp< < < mp< < mp< <) (f< ff> > < ff> > mp)) (velocity-smooth 0.2 '((ppp p mf ff p< < <) (fff> > f><p ff mf p ppp))) => ((ppp< < < < < < <) (< mf mf mf mf mf mf))" (span velocities (velocity-transform #'vector-smooth (list alfa (get-velocity (flatten velocities))) :simplify simplify)))