Jump to content

torstenanders

Members
  • Posts

    497
  • Joined

  • Last visited

Reputation Activity

  1. Like
    torstenanders got a reaction from AM in rnd-pick variant that leaves selection unchanged   
    I would like to randomly pick a nested list. That works in principle, but the nesting is lost.
    (rnd-pick '(((h q) (h)) ((h. q) (h)) ((h. h) (h)))) => ((3/4 1/4) (1/2)) ; instead returns (3/4 1/4 1/2) I guess I have to roll my own :)
    (defun rnd-pick2 (selections &key (prob 0.5) seed) "Randomly selects a value from `selections' (without transforming that value). Very similar to rnd-pick, but leaves selected value unchanged (e.g., unflattened). Args prob: a floating-point number. Probability value. The default is 0.5. Example (rnd-pick2 '(((h q) (h)) ((h. q) (h)) ((h. h) (h)))) => ((h. q) (h)) " (rnd-seed seed) (nth (rnd1 :low 0 :high (1- (length selections)) :prob prob :seed (seed)) selections)) Best,
    Torsten
  2. Like
    torstenanders got a reaction from AM in structural interferences   
    > I would advise to search the library, you might find thinks you never thought of 
     
    What strategies do you suggest for searching the rather large library of existing functions. Though this question sounds a bit simple, it really mean it seriously. The search facility only searches through function names, AFAIK, and a name like gen-surround is not exactly easy to guess. What other strategies could be there for finding relevant functions?
     
    Better support for finding relevant functions could perhaps be an important addition of version 2?
     
    Best,
    Torsten
      added 8 minutes later Dear André,
    > sampling-list BTW: The built-in Common Lisp function subseq is very similar, see http://www.lispworks.com/documentation/HyperSpec/Body/f_subseq.htm
     
    subseq is likely much faster than sampling-list, if that is important: calling nth very often in sampling-list needs to go through the input list again and again.
     
    Best,
    Torsten
  3. Like
    torstenanders reacted to Avner Dorman in Opposite of chordize?   
    Hi Torsten,
     
    Would these work?
     
    (pitch-melodize '(c4e4g4))
    => (c4 e4 g4)
     
    And (pitch-to-midi '(c4e4g4))
    =>((60 64 67))
     
    or (flatten (pitch-to-midi '(c4e4g4)))
    => (60 64 67)
     
    All the best,
    Avner 
  4. Like
    torstenanders got a reaction from lviklund in Merging and disassembling articulation symbols   
    I thought we better have a function zipping articulations for us, in particular if there are articulation lists of different length. The function definition is below. Here is a usage example. Apologies to all string players that this does not necessarily make sense musically :)
     
    (make-omn :length '(1/8 1/8 1/16 1/16 -1/16 1/8 1/8 1/8 1/8) :articulation (zip-articulations '(default stacc stacc default) '(ubow dbow) '(ponte)) :swallow NIL :flat T) => (e ubow+ponte nil stacc+dbow+ponte s stacc+ubow+ponte nil dbow+ponte - e ubow+ponte nil stacc+dbow+ponte nil stacc+ubow+ponte nil dbow+ponte)  
    Janusz: as with the dynamics function, this function does also not yet handle nested lists.
     
    Best,
    Torsten
    ;;; TODO: support nested lists -- somehow store nesting structure, then process flattened list and apply nesting back (defun zip-articulations (&rest arts) "Expects lists of articulations and combines them to a single list of merged articulations. Shorter lists are circled to the length of the longest. Example: (zip-articulations '(default leg leg default) '(breathy))" (let ((max-length (apply #'max (mapcar #'length arts)))) (mapcar #'merge-articulations (matrix-transpose (mapcar #'(lambda (xs) (circle-repeat xs max-length)) arts))))) (defun circle-repeat (pattern n) "Circle through elements in pattern (a list) until n elements are collected. NOTE: only supports flat list so far." (let ((l (length pattern))) (loop for i from 0 to (- n 1) collect (nth (mod i l) pattern)))) ; (circle-repeat '(bb4 g4 f4) 20)  
  5. Like
    torstenanders got a reaction from lviklund in Merging and disassembling articulation symbols   
    Here is some application example for the above functions.
     
    (setf my-rhythm '(1/8 1/8 1/16 1/16 -1/16 1/8 1/8 1/8 1/8)) (setf arts-1 (pattern-map '(((1/8 1/8) (leg stacc))) my-rhythm :otherwise '(default))) (setf arts-2 (pattern-map '(((1/8) (tasto))) my-rhythm :otherwise '(ord))) (mapcar #'merge-articulations (matrix-transpose (list (flatten arts-1) (flatten arts-2)))) => (leg+tasto stacc+tasto ord ord ord leg+tasto stacc+tasto leg+tasto stacc+tasto)  
  6. Like
    torstenanders got a reaction from lviklund in velocity-to-dynamic limitation   
    OK, I now defined the necessary auxiliary functions and almost finished the function. What is still missing is support for nested lists that retains the nesting structure. Janusz, you did this in several OMN functions already, it might be more easy if you add that yourself :)
     
    Best,
    Torsten
     
    (defun cresc-p (dyn) "Example: (cresc-p 'p<) => T" (and (velocityp dyn) (let ((str (symbol-name dyn))) (equal (subseq str (1- (length str))) "<")))) (defun dim-p (dyn) "Example: (dim-p 'f>) => T" (and (velocityp dyn) (let ((str (symbol-name dyn))) (equal (subseq str (1- (length str))) ">")))) ;;; TODO: support nested lists -- somehow store nesting structure, then process flattened list and apply nesting back (defun simplify-dynamics (dynamics) "Removes intermediate textual dynamic indicators from longer hairpins (e.g., generated by velocity-to-dynamic or gen-dynamic). Example: (simplify-dynamics '(pppp< < ppp< pp< < p< < mp< mf< < f< < ff> > mf> mp> p> ppp> pppp)) => (pppp< < < < < < < < < < < < ff> > > > > > pppp)" (append (list (first dynamics)) (loop for (d1 d2 d3) on dynamics when (and d2 d3) collect (cond ((or (and (cresc-p d1) (cresc-p d3)) (and (not (eq d2 '<)) (not (eq d3 '<)) (< (get-velocity d2) (get-velocity d3)))) '<) ((or (and (dim-p d1) (dim-p d3)) (and (not (eq d2 '>)) (not (eq d3 '>)) (> (get-velocity d2) (get-velocity d3)))) '>) (t d2))) (last dynamics)))  
  7. Like
    torstenanders got a reaction from lviklund in velocity-to-dynamic limitation   
    Thanks! Should be fixed now.
    (defun simplify-dynamics (dynamics) "Removes intermediate textual dynamic indicators from longer hairpins (e.g., generated by velocity-to-dynamic or gen-dynamic). Example: (simplify-dynamics '(pppp< < ppp< pp< < p< < mp< mf< < f< < ff> > mf> mp> p> ppp> pppp)) => (pppp< < < < < < < < < < < < ff> > > > > > pppp) " (append (list (first dynamics)) (loop for (d1 d2 d3) on dynamics when (and d2 d3) collect (cond ((or (and (cresc-p d1) (dim-p d3)) (and (dim-p d1) (cresc-p d3))) d2) ((or (and (cresc-p d1) (cresc-p d3)) (and (not (member d2 '(< >))) (not (member d3 '(< >))) (not (member d2 *one-note-dynamic-symbol*)) (not (member d3 *one-note-dynamic-symbol*)) (< (get-velocity d2) (get-velocity d3)))) '<) ((or (and (dim-p d1) (dim-p d3)) (and (not (member d2 '(< >))) (not (member d3 '(< >))) (not (member d2 *one-note-dynamic-symbol*)) (not (member d3 *one-note-dynamic-symbol*)) (> (get-velocity d2) (get-velocity d3)))) '>) (t d2))) (last dynamics)))  
  8. Like
    torstenanders got a reaction from opmo in velocity-to-dynamic limitation   
    OK, I now defined the necessary auxiliary functions and almost finished the function. What is still missing is support for nested lists that retains the nesting structure. Janusz, you did this in several OMN functions already, it might be more easy if you add that yourself :)
     
    Best,
    Torsten
     
    (defun cresc-p (dyn) "Example: (cresc-p 'p<) => T" (and (velocityp dyn) (let ((str (symbol-name dyn))) (equal (subseq str (1- (length str))) "<")))) (defun dim-p (dyn) "Example: (dim-p 'f>) => T" (and (velocityp dyn) (let ((str (symbol-name dyn))) (equal (subseq str (1- (length str))) ">")))) ;;; TODO: support nested lists -- somehow store nesting structure, then process flattened list and apply nesting back (defun simplify-dynamics (dynamics) "Removes intermediate textual dynamic indicators from longer hairpins (e.g., generated by velocity-to-dynamic or gen-dynamic). Example: (simplify-dynamics '(pppp< < ppp< pp< < p< < mp< mf< < f< < ff> > mf> mp> p> ppp> pppp)) => (pppp< < < < < < < < < < < < ff> > > > > > pppp)" (append (list (first dynamics)) (loop for (d1 d2 d3) on dynamics when (and d2 d3) collect (cond ((or (and (cresc-p d1) (cresc-p d3)) (and (not (eq d2 '<)) (not (eq d3 '<)) (< (get-velocity d2) (get-velocity d3)))) '<) ((or (and (dim-p d1) (dim-p d3)) (and (not (eq d2 '>)) (not (eq d3 '>)) (> (get-velocity d2) (get-velocity d3)))) '>) (t d2))) (last dynamics)))  
  9. Like
    torstenanders got a reaction from Stephane Boussuge in Merging and disassembling articulation symbols   
    EDIT: OK, I now this this myself:
     
    (defun merge-articulations (arts &key (empty-articulations '(- default))) "Merges list of OMN articulations to a combined attribute. Args: arts: a list of OMN articulations empty-attributes: articulations to ignore in a combination. Examples: (merge-articulations '(ten ponte ubow)) => ten+ponte+ubow (merge-articulations '(- stacc)) => stacc" #| ; can be uncommented when articulationp works (assert (every #'articulationp arts) (arts) "All values to merge must be OMN attributes: ~A.~%" arts) |# (intern (reduce #'(lambda (a1 a2) (format nil "~A+~A" a1 a2)) (mappend #'(lambda (art) (unless (some #'(lambda (a) (eq art a)) empty-articulations) (list (symbol-name art)))) arts)))) (defun disassemble-articulations (art) "Splits a combined OMN articulations into a list of its individual attributes. Example: (disassemble-articulations 'leg+ponte) => (leg ponte)" #| (assert (articulationp art) (art) "Value not OMN articulations: ~A.~%" art) |# ;; split-string seems to be part of OMN (mapcar #'intern (split-string (symbol-name art) :separator "+")))  
  10. Like
    torstenanders got a reaction from Stephane Boussuge in Merging and disassembling articulation symbols   
    Here is some application example for the above functions.
     
    (setf my-rhythm '(1/8 1/8 1/16 1/16 -1/16 1/8 1/8 1/8 1/8)) (setf arts-1 (pattern-map '(((1/8 1/8) (leg stacc))) my-rhythm :otherwise '(default))) (setf arts-2 (pattern-map '(((1/8) (tasto))) my-rhythm :otherwise '(ord))) (mapcar #'merge-articulations (matrix-transpose (list (flatten arts-1) (flatten arts-2)))) => (leg+tasto stacc+tasto ord ord ord leg+tasto stacc+tasto leg+tasto stacc+tasto)  
  11. Like
    torstenanders reacted to Stephane Boussuge in BUG? length-map cannot handle - as otherwise value   
    My way is to define a word default in the user-attributes file in extension:
     
    '(default "") This way, i can use default articulation name but without notation on score, just as "-" sign.
     
    SB.
     
     
     
  12. Like
    torstenanders got a reaction from Stephane Boussuge in A possible motivic lengths approach to articulation generation   
    If you are reading this later, motif-map meanwhile became PATTERN-MAP.
  13. Like
    torstenanders got a reaction from Stephane Boussuge in velocity-to-dynamic limitation   
    I would like to algorithmically generate dynamic markings with dynamic indications like mp plus hairpins. The code snippet below shows vector values created with custom envelopes that I would like to translate, and the function velocity-to-dynamic almost does that for me already (vector-to-velocity is primarily there to translate a vector into a list).
     
    (velocity-to-dynamic
     (vector-to-velocity
      0.1 0.7
      #(0.0 0.07936508 0.15873016 0.23809525 0.31746033 0.39682543 0.4761905 0.5555556 0.63492066 0.71428573 0.79365087 0.8730159 0.952381 0.9259259 0.74074066 0.5555556 0.37037033 0.18518525 0.0)))
     
    My problem is that velocity-to-dynamic creates lots of intermediate dynamic indications, where instead I would prefer a long hairpin connecting only the extreme dynamic indications. Instead of
     
       (pppp< < ppp< pp< < p< < mp< mf< < f< < ff> > mf> mp> p> ppp> pppp)
     
    I would like to get something like the following result, which is much clearer for the performer.
     
       (pppp< < < < < < < < < < < < ff> > > > > > pppp)
     
    Would it be possible to revise velocity-to-dynamic accordingly, or should I better roll my own? Thanks!
     
    EDIT: On second thought, a separate function would likely be better, because that can then be used for all functions that generate hairpins, e.g., also gen-dynamic.
     
    Best,
    Torsten
     
    PS: A remaining problem would be how to handle rests, where hairpins will be interrupted. A possible solution could be to keep the output of velocity-to-dynamic as is, and instead be able to specify that the final score generation leaves out intermediate dynamic markings as those shown above, but keeps them for rests. However, that might be tricky to implement. Leaving the proper handling of rests to users and instead to simplify the output of velocity-to-dynamic with a new function is much simpler.
     
  14. Like
    torstenanders reacted to opmo in step-to-pitch   
    Example with start:
    (tonality-step '(c4d4e4f4g4a4) '(1 1 -1 2 2 -1) :start -2) => (g3 a3 c4 a3 d4 f4 e4)  
  15. Like
    torstenanders reacted to opmo in step-to-pitch   
    Will be part of the next update. 
  16. Like
    torstenanders reacted to opmo in step-to-pitch   
    This is how the new function TONALITY-STEP will work:
     
    tonality-step (scale step &key start ambitus (sort t))
    (tonality-step '(c4 d4 e4 g4 a4 f4) '(1 1 -1 2 2 -1)) => (c4 d4 e4 d4 f4 a4 g4) (tonality-step '(c4 d4 e4 g4 a4 f4) '(1 1 -1 2 2 -1 5 3 2 3 -2 -2 1 1)) => (c4 d4 e4 d4 f4 a4 g4 f5 c6 e6 a6 f6 d6 e6 f6) (tonality-step '(c4 chromatic) '(1 1 -1 2 2 -1)) => (c4 cs4 d4 cs4 eb4 f4 e4) (tonality-step '(c4 messiaen-mode6) '(1 1 -1 2 2 -1 5)) => (c4 d4 e4 d4 f4 gs4 fs4 d5) (tonality-step '(c4 messiaen-mode6) '(1 1 -1 2 2 -1 5 3 2 3 -2 -2 1 1)) => (c4 d4 e4 d4 f4 gs4 fs4 d5 fs5 bb5 d6 b5 gs5 bb5 b5) (tonality-step '(c4 messiaen-mode6) '(1 2 -1 2 2 -1 5 3 2 3 -2 -2 1 1) :ambitus 'scale) => (c4 d4 f4 e4 fs4 bb4 gs4 e4 gs4 b4 e4 c4 bb4 b4 c4) (tonality-step '(c4 messiaen-mode6) '(1 2 -1 2 2 -1 5 3 2 3 -2 -2 1 1) :ambitus '(c3 a4)) => (c4 d4 f4 e4 fs4 bb3 gs4 e4 gs4 b3 e4 c4 bb3 b3 c4) (tonality-step '((c4d4e4g4a4f4) (c3 messiaen-mode6) (c4d4e4g4a4f4)) '((1 1 -1 2 2 -1) (5 3 2 3 -2 -2 1 1) (2 -1 3 2 3 -2 -2 1 1))) => ((c4 d4 e4 d4 f4 a4 g4) (c3 gs3 c4 e4 gs4 f4 d4 e4 f4) (c4 e4 d4 g4 c5 f5 d5 a4 c5 d5))  
  17. Like
    torstenanders got a reaction from Stephane Boussuge in Bug in snippet audition and notation of multiple statements?   
    Dear Janusz and Stephane,
     
    I understand both your points, thanks for your feedback.
     
    Still, I think it would be useful if snippet output would work more like the normal evaluation, where after evaluating multiple statements/expressions only the last result is returned. Such an implicit progn is useful behaviour. Many Lisp forms therefore also have an implicit progn (e.g., the bodies of defun, lambda, and let, case, catch, when etc.).
     
    It seems that if multiple expressions are selected, then snippet output instead tries to notate/play each of them, resulting in the errors reported above.
     
    It seems a simple solution would be to enclose all code for snippet output with a progn, so that snippet output also supports an implicit progn. This would not break any existing functionality, but would fix the reported problem, which then saves time during coding (no need to evaluate multiple lines separates, or to write progn), and avoids unnecessary surprises by newcomers.
     
    Best,
    Torsten
  18. Like
    torstenanders reacted to opmo in Shortcut for plotting?   
    Not that simple, but will be in the next update :-)
     
     
  19. Like
    torstenanders got a reaction from Stephane Boussuge in Shortcut for plotting?   
    Opusmodus already comes with a number of convenient shortcuts for auditioning and notating snippets.
     
    It would be useful to complement them by a shortcut for plotting vectors. When evaluating a vector or list of numbers, it would basically though the following code around it.
    (list-plot <vector or list to plot goes here>            :join-points T            :point-radius 2)  
    Thanks a lot!
     
    Best,
    Torsten
  20. Like
    torstenanders got a reaction from AM in Need more open windows/frames   
    The Opusmodus editor allows to have a number of "windows" open next to each other, but not enough for me. With Emacs I have commonly 3-4 frames with code open next to each other, in addition to the documentation, output viewers etc. (nice to have multiple screens :)
     
    Any chance to do the same and open 3-4 files from the current project/workspace side by side?
     
    EDIT: Note that I can open additional files, but only if they are not part of the current project/workspace -- going beyond that restriction would help. 
     
    Thanks!
     
    Best,
    Torsten
  21. Like
    torstenanders got a reaction from AM in OMN Symbol VOICE   
    Dear Janusz,
     
    After our chat last night I still think that it would be useful to make voice numbers optional. If they are absent, this could simply mean that they are in increasing order, starting with 1. So, the following two snippets would be equivalent.
    (:1 (q e4 ff h f4 q c5)  :2 (e fs4 ff gs4 bb4 gs4 q fs4 f4)  :3 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)) ((q e4 ff h f4 q c5)  (e fs4 ff gs4 bb4 gs4 q fs4 f4)  (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)) Now, the problem with the latter notation is that it cannot be distinguished from a sequence of bars, which is why I proposed another notation to mark parallel voices (those brackets). Alternatively, we could simply require another level of parentheses. 
    (((q e4 ff h f4 q c5))  ((e fs4 ff gs4 bb4 gs4 q fs4 f4))  ((s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4))) This could also be done by a simple function that expects an arbitrary number of voices with or without sublists for bars, and then creates the additional lists (or voice number markers) behind the scene.
    (make-voices (q e4 ff h f4 q c5)  (e fs4 ff gs4 bb4 gs4 q fs4 f4)  (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)) Anyway, as I pointed out before I suspect we quickly run into cases where the time signatures of different voices get inconsistent -- regardless of the notation used, and that it would be useful to optionally specify time signatures explicitly, like in def-score. This would simply cause a re-barring behind the scene, which is not a big deal.
    (make-voices (q e4 ff h f4 q c5)  (e fs4 ff gs4 bb4 gs4 q fs4 f4)  (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4) :time-signature '((1 1 1 1) 4)) Tempo specifications for snippets would be very useful as well, and so would be partial scores with instrument names specified instead of voice numbers, but that might be too much :)
     
    Best,
    Torsten
  22. Like
    torstenanders got a reaction from Stephane Boussuge in MittWoch   
    Sounds you really settle in there :)
     
    Best,
    Torsten
  23. Like
    torstenanders reacted to opmo in OMN Symbol VOICE   
    I am working on a new omn symbol VOICES and wonder which way is more natural to write.
    I would like to hear your comments and ideas on this.
     
    Here are the two examples.
     
    With symbol :vx

    1) Each voice after each event, next to each other (1 bar 4/4):
    symbol option :vx (:v1 q cs5 ff :v2 q gs4 ff :v3 q f4 ff :v4 q f3 ff :v1 q eb5 ff :v2 q gs4 ff :v3 q c4 ff :v4 q gs3 ff :v1 q cs5 ff :v2 q gs4 ff :v3 q f4 ff :v4 q cs3 ff :v1 q f5 ff :v2 q cs5 ff :v3 q gs4 ff :v4 q cs3 ff) symbol option :x (:1 q cs5 ff :2 q gs4 ff :3 q f4 ff :4 q f3 ff :1 q eb5 ff :2 q gs4 ff :3 q c4 ff :4 q gs3 ff :1 q cs5 ff :2 q gs4 ff :3 q f4 ff :4 q cs3 ff :1 q f5 ff :2 q cs5 ff :3 q gs4 ff :4 q cs3 ff)  
    2) Each voice in a separate bar (1 bar 4/4):
    symbol option :vx (:v1 (q bb4 ff g4 gs4 e g4 f4)  :v2 (q cs5 ff b4 gs4 fs4)  :v3 (q f4 ff bb3 gs3 e bb3 gs3)  :v3 (q d3 ff e eb3 d3 q c3 bb2)) symbol option :x (:1 (q e4 ff h f4 q c5) :2 (e fs4 ff gs4 bb4 gs4 q fs4 f4)  :3 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)  :4 (q c3 ff h f2 q f3))  
    The symbol option :1 :2 :3 :4
    (:1 (q e4 ff h f4 q c5)  :2 (e fs4 ff gs4 bb4 gs4 q fs4 f4)  :3 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)  :4 (q c3 ff h f2 q f3))  
    will print in the Listener:
    (:|1| (q e4 ff h f4 q c5)  :|2| (e fs4 ff gs4 bb4 gs4 q fs4 f4)  :|3| (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)  :|4| (q c3 ff h f2 q f3))  
    I personally think the second option is better to control.
     
    Best wishes,
    JP
  24. Like
    torstenanders got a reaction from lviklund in alternate-omns   
    Below is a function that might be interesting for others as well. When I starting writing this function it was much more complicated, but it got more simple by and by 🙂 A formatted version as an RTF file of the documentation is attached, below is a plain text version.
     
    For completeness I also attached the documentation of the function circle-repeat, used by the function below. Unfortunately, the file names are destroyed by the software of this forum, sorry.
     
    Best,
    Torsten
     
    alternate-omns ids omns
     
    Arguments and Values
     
    ids       a list of integers, indicating the position of OMN expressions in omns.
    omns     a list of OMN expressions (can also be plain lengths, or pitches etc.) between which to switch.
     
    Description
    This function alternates between sublists of multiple OMN expressions.
    This function can be useful, e.g., to switch between different musical characteristics. Each characteristic (e.g., gesture) and its development can be specified by a combination of parameters (rhythm, pitches, dynamics, and playing techniques) in a sequence of OMN expressions. The output of the function switches between these characteristics as specified in the first argument to the function. The following example demonstrates this.
     
    (alternate-omns  (gen-eval 10 '(rnd-pick '(0 1)))  (list   (make-omn    :length (length-rest-series (rnd-sample 7 '(7 8 9))             (length-divide 3 2                            (rnd-sample 7 '((q q q) (h e e) (h.) (h q)))))    :pitch '(d4 e4 f4 g4)    :velocity '(pp))   (make-omn    :length '(s s s s)    :pitch (gen-rotate :right '(c5 d5 f5 a5 g5 e5) :type :seq)    :velocity '(ff)    :span :pitch)))
    Alternatively, one can switch between plain sequences of OMN lengths, or pitches etc.
    (alternate-omns   '(0 0 1 0 1 0 1 1 0 0 1 1 1)   (list     (gen-rotate :left '(-1/20 1/20 1/20 1/20 1/20) :type :seq)    '((q e e))))  
    Examples
    Remember that resulting OMN expressions can be “re-barred”.
    (omn-to-time-signature  (alternate-omns   '(0 0 1 0 1 0 1 1 0 0 1 1 1)   (list    (make-omn     :length (gen-rotate :left '(-1/20 1/20 1/20 1/20 1/20) :type :seq)     :pitch '(d4 e4 f4 g4)     :velocity '(ff))    (make-omn     :length '(q e e)     :pitch (gen-rotate :left '(c5 e5 f5) :type :seq)     :velocity '(pp pp)     :attribute '(ten stacc stacc)     :span :pitch)))  '(4 4))  
    Implementation
    (defun alternate-omns (ids omns) "This function alternates between sublists of multiple omn expressions. It can be useful, e.g., to switch between different musical characteristics. Args: ids: a list of integers, indicating the position of OMN expressions in omns. omns: a list of OMN expressions (can also be plain lengths, or pitches etc.) between which to switch." (let ((omn-no (length omns))) (assert (every #'(lambda (x) (and (integerp x) (< x omn-no))) ids) (ids) "alternate-omns: must be a list of integers between 0 and (1- (length omns)): ~A" ids) (let ((hash (make-hash-table))) (loop for i from 0 to (1- omn-no) for my-omn in omns ;; span (circular repeat if necessary) omn sublists to number of occurences in specs ;; and fill hash table with that as side effect do (setf (gethash i hash) (circle-repeat my-omn (count i ids)))) (alternate-omns-aux ids hash)))) (defun alternate-omns-aux (ids hash) (loop for id in ids collect (pop (gethash id hash)))) (defun circle-repeat (pattern n) "Circle through elements in pattern (a list) until n elements are collected. NOTE: only supports flat list so far." (let ((l (length pattern))) (loop for i from 0 to (- n 1) collect (nth (mod i l) pattern))))  
    TXT.rtf
    TXT.rtf
  25. Like
    torstenanders got a reaction from Stephane Boussuge in alternate-omns   
    Below is a function that might be interesting for others as well. When I starting writing this function it was much more complicated, but it got more simple by and by 🙂 A formatted version as an RTF file of the documentation is attached, below is a plain text version.
     
    For completeness I also attached the documentation of the function circle-repeat, used by the function below. Unfortunately, the file names are destroyed by the software of this forum, sorry.
     
    Best,
    Torsten
     
    alternate-omns ids omns
     
    Arguments and Values
     
    ids       a list of integers, indicating the position of OMN expressions in omns.
    omns     a list of OMN expressions (can also be plain lengths, or pitches etc.) between which to switch.
     
    Description
    This function alternates between sublists of multiple OMN expressions.
    This function can be useful, e.g., to switch between different musical characteristics. Each characteristic (e.g., gesture) and its development can be specified by a combination of parameters (rhythm, pitches, dynamics, and playing techniques) in a sequence of OMN expressions. The output of the function switches between these characteristics as specified in the first argument to the function. The following example demonstrates this.
     
    (alternate-omns  (gen-eval 10 '(rnd-pick '(0 1)))  (list   (make-omn    :length (length-rest-series (rnd-sample 7 '(7 8 9))             (length-divide 3 2                            (rnd-sample 7 '((q q q) (h e e) (h.) (h q)))))    :pitch '(d4 e4 f4 g4)    :velocity '(pp))   (make-omn    :length '(s s s s)    :pitch (gen-rotate :right '(c5 d5 f5 a5 g5 e5) :type :seq)    :velocity '(ff)    :span :pitch)))
    Alternatively, one can switch between plain sequences of OMN lengths, or pitches etc.
    (alternate-omns   '(0 0 1 0 1 0 1 1 0 0 1 1 1)   (list     (gen-rotate :left '(-1/20 1/20 1/20 1/20 1/20) :type :seq)    '((q e e))))  
    Examples
    Remember that resulting OMN expressions can be “re-barred”.
    (omn-to-time-signature  (alternate-omns   '(0 0 1 0 1 0 1 1 0 0 1 1 1)   (list    (make-omn     :length (gen-rotate :left '(-1/20 1/20 1/20 1/20 1/20) :type :seq)     :pitch '(d4 e4 f4 g4)     :velocity '(ff))    (make-omn     :length '(q e e)     :pitch (gen-rotate :left '(c5 e5 f5) :type :seq)     :velocity '(pp pp)     :attribute '(ten stacc stacc)     :span :pitch)))  '(4 4))  
    Implementation
    (defun alternate-omns (ids omns) "This function alternates between sublists of multiple omn expressions. It can be useful, e.g., to switch between different musical characteristics. Args: ids: a list of integers, indicating the position of OMN expressions in omns. omns: a list of OMN expressions (can also be plain lengths, or pitches etc.) between which to switch." (let ((omn-no (length omns))) (assert (every #'(lambda (x) (and (integerp x) (< x omn-no))) ids) (ids) "alternate-omns: must be a list of integers between 0 and (1- (length omns)): ~A" ids) (let ((hash (make-hash-table))) (loop for i from 0 to (1- omn-no) for my-omn in omns ;; span (circular repeat if necessary) omn sublists to number of occurences in specs ;; and fill hash table with that as side effect do (setf (gethash i hash) (circle-repeat my-omn (count i ids)))) (alternate-omns-aux ids hash)))) (defun alternate-omns-aux (ids hash) (loop for id in ids collect (pop (gethash id hash)))) (defun circle-repeat (pattern n) "Circle through elements in pattern (a list) until n elements are collected. NOTE: only supports flat list so far." (let ((l (length pattern))) (loop for i from 0 to (- n 1) collect (nth (mod i l) pattern))))  
    TXT.rtf
    TXT.rtf
×
×
  • Create New...

Important Information

Terms of Use Privacy Policy