Jump to content

torstenanders

core_group_3
  • Content Count

    317
  • Joined

  • Last visited

  • Days Won

    60

Reputation Activity

  1. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  2. reaction_title_1
    torstenanders got a reaction from lviklund in Updated library of many custom Opusmodus functions   
    > all your hard work to document
     
    I actually do such detailed documentation for my own benefit as well. I once spent several months on developing some personal library that I used for composing some piece, but when I wanted to re-use it some two years later, I could not really understand my own functions anymore. Since then I better err on the side of overdoing the docs 🙂
     
    Best,
    Torsten
     
  3. reaction_title_1
    torstenanders got a reaction from lviklund in Updated library of many custom Opusmodus functions   
    > all your hard work to document
     
    I actually do such detailed documentation for my own benefit as well. I once spent several months on developing some personal library that I used for composing some piece, but when I wanted to re-use it some two years later, I could not really understand my own functions anymore. Since then I better err on the side of overdoing the docs 🙂
     
    Best,
    Torsten
     
  4. reaction_title_1
    torstenanders got a reaction from lviklund in Updated library of many custom Opusmodus functions   
    > all your hard work to document
     
    I actually do such detailed documentation for my own benefit as well. I once spent several months on developing some personal library that I used for composing some piece, but when I wanted to re-use it some two years later, I could not really understand my own functions anymore. Since then I better err on the side of overdoing the docs 🙂
     
    Best,
    Torsten
     
  5. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    Good to hear things are working for you 😉
     
    Note that dependencies of this library are of interest on their own for computer-aided composition. This is particularly true for the constraint library cluster engine and its extension cluster rules, as well as the library fenv. 
     
    Torsten
  6. reaction_title_1
    torstenanders got a reaction from opmo in Updated library of many custom Opusmodus functions   
    > I like the Carnatic Stuff.
     
    To best understand what those functions offer I recommend the book referenced in the doc (Reina, 2016), which was quite an eye-opener for me. There is a partial preview at Google Books (https://books.google.co.uk/books?id=4RSrCwAAQBAJ&printsec=frontcover#v=onepage&q&f=false), and further information is available at the associated websites (http://www.contemporary-music-through-non-western-techniques.com and http://www.rafaelreina.org/book-online-material.html).
     
    Best,
    Torsten
     
    References
    Reina, R. (2016) Applying Karnatic Rhythmical Techniques to Western Music. Routledge. added 8 minutes later I just noticed the perhaps most important Karnatic function so far, gen-karnatic-cell, is not contained in the automatically generated documentation, because the documentation tool seemingly skips functions that are not defined at the top level. I may fix that at some stage, but for now you can read the documentation in the doc string of the function in its source file (rhythm.lisp), or you evaluate the following line and read it in the listener.
     
    (documentation 'gen-karnatic-cell 'function)
     
    Best,
    Torsten
     
  7. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    > I got just four 16th notes.
     
    This function allows for various controls that you did not use – Of course this function also allows for plain sequences of 1/16-notes, when you select its arguments accordingly 🙂   I am interested in CAC as a means of control on a higher level instead of some automatic "magic".
     
    You might want to run the examples below in Opusmodus to get music notation outputs, which are likely more easy to read than the OMN expressions, but nevertheless I provide the OMN expressions for completeness as well.
     
    The argument position (3rd argument) controls the kind of rhythmic cell that you get, see the doc for details. Here is an example where different rhythmic cells are returned. Note that by default all returned cells carry potentially a durational accent. 
     
    (gen-karnatic-cell 4 4 '(0 4 3 2 1 0))
    => ((1/4) (1/16 1/16 1/16 1/16) (1/8 1/16 1/16) (1/8 1/8) (3/16 1/16) (1/4))
     
    Now, if you use the same positions but different gati or jathi settings then you get a somewhat similar rhythm in that different gati/jathi. Below I slightly adapted the positions to make the results even more similar. 
     
    (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (3/16 1/16 1/16) (3/16 1/8) (1/4 1/16) (5/16))
     
    You can, of course, use these in a different time signature (e.g., the tala of your choice).
     
    (omn-to-time-signature (gen-karnatic-cell 4 5 '(0 6 3 2 1 0)) '(4 4))
    => ((q c4 tie s s s s s s e. s s s tie) (e c4 c4 q s q tie s))
     
    If you want to keep track of where the accents are located, you could mark them before this transformation (the function articulate-phrase is defined below this post). You could then manually later revise the notation to instead you the beam-breaking that Reina recommends. 
     
    (omn-to-time-signature 
     (articulate-phrase (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
                        :accent 'marc)
    '(4 4))
    => ((q c4 tie+marc s marc s marc s s s s e. marc s s s tie+marc) (e c4 c4 q marc s q tie+marc s marc))
     
    After the changed jathi above, here is a different gati. Results are more similar, because the underlying data is the same with different gati but the same jathi. Here is an example with quintuplets. 
     
    (gen-karnatic-cell 5 4 '(0 4 3 2 1 0))
    => ((1/5) (1/20 1/20 1/20 1/20) (1/10 1/20 1/20) (1/10 1/10) (3/20 1/20) (1/5))
     
    Here is the same with triplets -- exactly the same, only slower. 
     
    (gen-karnatic-cell 3 4 '(0 4 3 2 1 0))
    => ((1/3) (1/12 1/12 1/12 1/12) (1/6 1/12 1/12) (1/6 1/6) (1/4 1/12) (1/3))

    You can also change the jathi (or even gati) on the fly in a phrase. The given pattern is then 'cycled through'.
     
    (gen-karnatic-cell 4 '(5 5 3 3) '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (1/16 1/16 1/16) (1/16 1/16 1/16) (1/4 1/16) (5/16))

    You can also randomise your position
     
    (gen-karnatic-cell 4 5 '(0 1 ? ? 0))
    => ((5/16) (1/4 1/16) (3/16 1/8) (3/16 1/16 1/16) (5/16))

    And I did not even start discussing the other parameters yet. For example, you can set whether or not cells start with a durational accent (not a karnatic concept, but very useful notion for Western ears when dealing with rhythm). 
     
    (gen-karnatic-cell 4 5 '(3 3 3 3) :accented? '(T nil nil T))
    => ((3/16 1/16 1/16) (1/16 3/16 1/16) (1/16 3/16 1/16) (3/16 1/16 1/16))
     
    You can filter in various ways want kind of rhythm you want, e.g., set the minimum or maximum number of notes per cell. 
     
    (gen-karnatic-cell 4 5 '(? ? ? ?) :min-number '(3 3 3 3) :seed 1)
    =>((1/8 1/8 1/16) (3/16 1/16 1/16) (1/16 1/16 1/16 1/16 1/16) (1/8 1/8 1/16)) 
     
    EDIT: Oops, that are is seemingly not fully working as expected.
     
    I stop here and refer you do the documentation for more details: there are several more arguments that I did not even mention yet. I know that my documentation is rather concise and not a textbook, but it briefly discusses every detail. I said from the beginning, I wrote this for myself, so you might want to first spend a bit of time with the doc 🙂
     
    As you hopefully can see, this function alone allows for a rather rich world of rhythm with rather precise control that allows varying some rhythmic idea in various ways. I am interested here in clearly perceivable rhythmic similarities, e.g., between rhythms in different gati and jathi combinations in the Western tradition of thematic variation.  
     
    Of course, you can also process the result further in various ways. E.g., I am adding ties after long notes and/or subdivide short notes to increase the rhythmic contrast, and I am turning certain notes into rests...
     
    Best,
    Torsten
     
    (defun articulate-phrase (sequence &key (accent 'marc))
      "Add articulations to phrase for more clear rhythmic accents, e.g, an accent on every first beat.
      
      NOTE: This function assumes that `sequence' is a purely rhythmic OMN expression with only length values and perhaps ties. However, a sequence with (constant) pitches is returned, because certain Opusmodus functions do not support an OMN sequence without pitches.
      Examples:
      (articulate-phrase '((h h) (q q q q tie) (q q q q) (-q q) (q q q q)) :accent 'marc)
      => ((h marc h) (q marc q q q tie) (q q q q) (-q q) (q marc q q q))
      "
      (cons 
       ;; First bar
       ;;; NOTE: code repetition...
       (let ((bar1 (first sequence)))
         (if (length-notep (first bar1))
           (if (and (= (count-notes bar1) 1)
                    (eql (first (last bar1)) 'tie))
             (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar1)
             (tu:insert-after bar1 0 accent))
           bar1))
       ;; other bars
       (loop :for (bar1 bar2) :on sequence :while bar2
         ;;; NOTE: code repetition
         :collect (if (and (length-notep (first bar2))
                           (not (eql (first (last bar1)) 'tie)))
                    (if (and (= (count-notes bar2) 1)
                             (eql (first (last bar2)) 'tie))
                      (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar2)
                      (tu:insert-after bar2 0 accent))
                    bar2))))
     
  8. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    > I got just four 16th notes.
     
    This function allows for various controls that you did not use – Of course this function also allows for plain sequences of 1/16-notes, when you select its arguments accordingly 🙂   I am interested in CAC as a means of control on a higher level instead of some automatic "magic".
     
    You might want to run the examples below in Opusmodus to get music notation outputs, which are likely more easy to read than the OMN expressions, but nevertheless I provide the OMN expressions for completeness as well.
     
    The argument position (3rd argument) controls the kind of rhythmic cell that you get, see the doc for details. Here is an example where different rhythmic cells are returned. Note that by default all returned cells carry potentially a durational accent. 
     
    (gen-karnatic-cell 4 4 '(0 4 3 2 1 0))
    => ((1/4) (1/16 1/16 1/16 1/16) (1/8 1/16 1/16) (1/8 1/8) (3/16 1/16) (1/4))
     
    Now, if you use the same positions but different gati or jathi settings then you get a somewhat similar rhythm in that different gati/jathi. Below I slightly adapted the positions to make the results even more similar. 
     
    (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (3/16 1/16 1/16) (3/16 1/8) (1/4 1/16) (5/16))
     
    You can, of course, use these in a different time signature (e.g., the tala of your choice).
     
    (omn-to-time-signature (gen-karnatic-cell 4 5 '(0 6 3 2 1 0)) '(4 4))
    => ((q c4 tie s s s s s s e. s s s tie) (e c4 c4 q s q tie s))
     
    If you want to keep track of where the accents are located, you could mark them before this transformation (the function articulate-phrase is defined below this post). You could then manually later revise the notation to instead you the beam-breaking that Reina recommends. 
     
    (omn-to-time-signature 
     (articulate-phrase (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
                        :accent 'marc)
    '(4 4))
    => ((q c4 tie+marc s marc s marc s s s s e. marc s s s tie+marc) (e c4 c4 q marc s q tie+marc s marc))
     
    After the changed jathi above, here is a different gati. Results are more similar, because the underlying data is the same with different gati but the same jathi. Here is an example with quintuplets. 
     
    (gen-karnatic-cell 5 4 '(0 4 3 2 1 0))
    => ((1/5) (1/20 1/20 1/20 1/20) (1/10 1/20 1/20) (1/10 1/10) (3/20 1/20) (1/5))
     
    Here is the same with triplets -- exactly the same, only slower. 
     
    (gen-karnatic-cell 3 4 '(0 4 3 2 1 0))
    => ((1/3) (1/12 1/12 1/12 1/12) (1/6 1/12 1/12) (1/6 1/6) (1/4 1/12) (1/3))

    You can also change the jathi (or even gati) on the fly in a phrase. The given pattern is then 'cycled through'.
     
    (gen-karnatic-cell 4 '(5 5 3 3) '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (1/16 1/16 1/16) (1/16 1/16 1/16) (1/4 1/16) (5/16))

    You can also randomise your position
     
    (gen-karnatic-cell 4 5 '(0 1 ? ? 0))
    => ((5/16) (1/4 1/16) (3/16 1/8) (3/16 1/16 1/16) (5/16))

    And I did not even start discussing the other parameters yet. For example, you can set whether or not cells start with a durational accent (not a karnatic concept, but very useful notion for Western ears when dealing with rhythm). 
     
    (gen-karnatic-cell 4 5 '(3 3 3 3) :accented? '(T nil nil T))
    => ((3/16 1/16 1/16) (1/16 3/16 1/16) (1/16 3/16 1/16) (3/16 1/16 1/16))
     
    You can filter in various ways want kind of rhythm you want, e.g., set the minimum or maximum number of notes per cell. 
     
    (gen-karnatic-cell 4 5 '(? ? ? ?) :min-number '(3 3 3 3) :seed 1)
    =>((1/8 1/8 1/16) (3/16 1/16 1/16) (1/16 1/16 1/16 1/16 1/16) (1/8 1/8 1/16)) 
     
    EDIT: Oops, that are is seemingly not fully working as expected.
     
    I stop here and refer you do the documentation for more details: there are several more arguments that I did not even mention yet. I know that my documentation is rather concise and not a textbook, but it briefly discusses every detail. I said from the beginning, I wrote this for myself, so you might want to first spend a bit of time with the doc 🙂
     
    As you hopefully can see, this function alone allows for a rather rich world of rhythm with rather precise control that allows varying some rhythmic idea in various ways. I am interested here in clearly perceivable rhythmic similarities, e.g., between rhythms in different gati and jathi combinations in the Western tradition of thematic variation.  
     
    Of course, you can also process the result further in various ways. E.g., I am adding ties after long notes and/or subdivide short notes to increase the rhythmic contrast, and I am turning certain notes into rests...
     
    Best,
    Torsten
     
    (defun articulate-phrase (sequence &key (accent 'marc))
      "Add articulations to phrase for more clear rhythmic accents, e.g, an accent on every first beat.
      
      NOTE: This function assumes that `sequence' is a purely rhythmic OMN expression with only length values and perhaps ties. However, a sequence with (constant) pitches is returned, because certain Opusmodus functions do not support an OMN sequence without pitches.
      Examples:
      (articulate-phrase '((h h) (q q q q tie) (q q q q) (-q q) (q q q q)) :accent 'marc)
      => ((h marc h) (q marc q q q tie) (q q q q) (-q q) (q marc q q q))
      "
      (cons 
       ;; First bar
       ;;; NOTE: code repetition...
       (let ((bar1 (first sequence)))
         (if (length-notep (first bar1))
           (if (and (= (count-notes bar1) 1)
                    (eql (first (last bar1)) 'tie))
             (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar1)
             (tu:insert-after bar1 0 accent))
           bar1))
       ;; other bars
       (loop :for (bar1 bar2) :on sequence :while bar2
         ;;; NOTE: code repetition
         :collect (if (and (length-notep (first bar2))
                           (not (eql (first (last bar1)) 'tie)))
                    (if (and (= (count-notes bar2) 1)
                             (eql (first (last bar2)) 'tie))
                      (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar2)
                      (tu:insert-after bar2 0 accent))
                    bar2))))
     
  9. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    > I got just four 16th notes.
     
    This function allows for various controls that you did not use – Of course this function also allows for plain sequences of 1/16-notes, when you select its arguments accordingly 🙂   I am interested in CAC as a means of control on a higher level instead of some automatic "magic".
     
    You might want to run the examples below in Opusmodus to get music notation outputs, which are likely more easy to read than the OMN expressions, but nevertheless I provide the OMN expressions for completeness as well.
     
    The argument position (3rd argument) controls the kind of rhythmic cell that you get, see the doc for details. Here is an example where different rhythmic cells are returned. Note that by default all returned cells carry potentially a durational accent. 
     
    (gen-karnatic-cell 4 4 '(0 4 3 2 1 0))
    => ((1/4) (1/16 1/16 1/16 1/16) (1/8 1/16 1/16) (1/8 1/8) (3/16 1/16) (1/4))
     
    Now, if you use the same positions but different gati or jathi settings then you get a somewhat similar rhythm in that different gati/jathi. Below I slightly adapted the positions to make the results even more similar. 
     
    (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (3/16 1/16 1/16) (3/16 1/8) (1/4 1/16) (5/16))
     
    You can, of course, use these in a different time signature (e.g., the tala of your choice).
     
    (omn-to-time-signature (gen-karnatic-cell 4 5 '(0 6 3 2 1 0)) '(4 4))
    => ((q c4 tie s s s s s s e. s s s tie) (e c4 c4 q s q tie s))
     
    If you want to keep track of where the accents are located, you could mark them before this transformation (the function articulate-phrase is defined below this post). You could then manually later revise the notation to instead you the beam-breaking that Reina recommends. 
     
    (omn-to-time-signature 
     (articulate-phrase (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
                        :accent 'marc)
    '(4 4))
    => ((q c4 tie+marc s marc s marc s s s s e. marc s s s tie+marc) (e c4 c4 q marc s q tie+marc s marc))
     
    After the changed jathi above, here is a different gati. Results are more similar, because the underlying data is the same with different gati but the same jathi. Here is an example with quintuplets. 
     
    (gen-karnatic-cell 5 4 '(0 4 3 2 1 0))
    => ((1/5) (1/20 1/20 1/20 1/20) (1/10 1/20 1/20) (1/10 1/10) (3/20 1/20) (1/5))
     
    Here is the same with triplets -- exactly the same, only slower. 
     
    (gen-karnatic-cell 3 4 '(0 4 3 2 1 0))
    => ((1/3) (1/12 1/12 1/12 1/12) (1/6 1/12 1/12) (1/6 1/6) (1/4 1/12) (1/3))

    You can also change the jathi (or even gati) on the fly in a phrase. The given pattern is then 'cycled through'.
     
    (gen-karnatic-cell 4 '(5 5 3 3) '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (1/16 1/16 1/16) (1/16 1/16 1/16) (1/4 1/16) (5/16))

    You can also randomise your position
     
    (gen-karnatic-cell 4 5 '(0 1 ? ? 0))
    => ((5/16) (1/4 1/16) (3/16 1/8) (3/16 1/16 1/16) (5/16))

    And I did not even start discussing the other parameters yet. For example, you can set whether or not cells start with a durational accent (not a karnatic concept, but very useful notion for Western ears when dealing with rhythm). 
     
    (gen-karnatic-cell 4 5 '(3 3 3 3) :accented? '(T nil nil T))
    => ((3/16 1/16 1/16) (1/16 3/16 1/16) (1/16 3/16 1/16) (3/16 1/16 1/16))
     
    You can filter in various ways want kind of rhythm you want, e.g., set the minimum or maximum number of notes per cell. 
     
    (gen-karnatic-cell 4 5 '(? ? ? ?) :min-number '(3 3 3 3) :seed 1)
    =>((1/8 1/8 1/16) (3/16 1/16 1/16) (1/16 1/16 1/16 1/16 1/16) (1/8 1/8 1/16)) 
     
    EDIT: Oops, that are is seemingly not fully working as expected.
     
    I stop here and refer you do the documentation for more details: there are several more arguments that I did not even mention yet. I know that my documentation is rather concise and not a textbook, but it briefly discusses every detail. I said from the beginning, I wrote this for myself, so you might want to first spend a bit of time with the doc 🙂
     
    As you hopefully can see, this function alone allows for a rather rich world of rhythm with rather precise control that allows varying some rhythmic idea in various ways. I am interested here in clearly perceivable rhythmic similarities, e.g., between rhythms in different gati and jathi combinations in the Western tradition of thematic variation.  
     
    Of course, you can also process the result further in various ways. E.g., I am adding ties after long notes and/or subdivide short notes to increase the rhythmic contrast, and I am turning certain notes into rests...
     
    Best,
    Torsten
     
    (defun articulate-phrase (sequence &key (accent 'marc))
      "Add articulations to phrase for more clear rhythmic accents, e.g, an accent on every first beat.
      
      NOTE: This function assumes that `sequence' is a purely rhythmic OMN expression with only length values and perhaps ties. However, a sequence with (constant) pitches is returned, because certain Opusmodus functions do not support an OMN sequence without pitches.
      Examples:
      (articulate-phrase '((h h) (q q q q tie) (q q q q) (-q q) (q q q q)) :accent 'marc)
      => ((h marc h) (q marc q q q tie) (q q q q) (-q q) (q marc q q q))
      "
      (cons 
       ;; First bar
       ;;; NOTE: code repetition...
       (let ((bar1 (first sequence)))
         (if (length-notep (first bar1))
           (if (and (= (count-notes bar1) 1)
                    (eql (first (last bar1)) 'tie))
             (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar1)
             (tu:insert-after bar1 0 accent))
           bar1))
       ;; other bars
       (loop :for (bar1 bar2) :on sequence :while bar2
         ;;; NOTE: code repetition
         :collect (if (and (length-notep (first bar2))
                           (not (eql (first (last bar1)) 'tie)))
                    (if (and (= (count-notes bar2) 1)
                             (eql (first (last bar2)) 'tie))
                      (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar2)
                      (tu:insert-after bar2 0 accent))
                    bar2))))
     
  10. reaction_title_1
  11. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    > I got just four 16th notes.
     
    This function allows for various controls that you did not use – Of course this function also allows for plain sequences of 1/16-notes, when you select its arguments accordingly 🙂   I am interested in CAC as a means of control on a higher level instead of some automatic "magic".
     
    You might want to run the examples below in Opusmodus to get music notation outputs, which are likely more easy to read than the OMN expressions, but nevertheless I provide the OMN expressions for completeness as well.
     
    The argument position (3rd argument) controls the kind of rhythmic cell that you get, see the doc for details. Here is an example where different rhythmic cells are returned. Note that by default all returned cells carry potentially a durational accent. 
     
    (gen-karnatic-cell 4 4 '(0 4 3 2 1 0))
    => ((1/4) (1/16 1/16 1/16 1/16) (1/8 1/16 1/16) (1/8 1/8) (3/16 1/16) (1/4))
     
    Now, if you use the same positions but different gati or jathi settings then you get a somewhat similar rhythm in that different gati/jathi. Below I slightly adapted the positions to make the results even more similar. 
     
    (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (3/16 1/16 1/16) (3/16 1/8) (1/4 1/16) (5/16))
     
    You can, of course, use these in a different time signature (e.g., the tala of your choice).
     
    (omn-to-time-signature (gen-karnatic-cell 4 5 '(0 6 3 2 1 0)) '(4 4))
    => ((q c4 tie s s s s s s e. s s s tie) (e c4 c4 q s q tie s))
     
    If you want to keep track of where the accents are located, you could mark them before this transformation (the function articulate-phrase is defined below this post). You could then manually later revise the notation to instead you the beam-breaking that Reina recommends. 
     
    (omn-to-time-signature 
     (articulate-phrase (gen-karnatic-cell 4 5 '(0 6 3 2 1 0))
                        :accent 'marc)
    '(4 4))
    => ((q c4 tie+marc s marc s marc s s s s e. marc s s s tie+marc) (e c4 c4 q marc s q tie+marc s marc))
     
    After the changed jathi above, here is a different gati. Results are more similar, because the underlying data is the same with different gati but the same jathi. Here is an example with quintuplets. 
     
    (gen-karnatic-cell 5 4 '(0 4 3 2 1 0))
    => ((1/5) (1/20 1/20 1/20 1/20) (1/10 1/20 1/20) (1/10 1/10) (3/20 1/20) (1/5))
     
    Here is the same with triplets -- exactly the same, only slower. 
     
    (gen-karnatic-cell 3 4 '(0 4 3 2 1 0))
    => ((1/3) (1/12 1/12 1/12 1/12) (1/6 1/12 1/12) (1/6 1/6) (1/4 1/12) (1/3))

    You can also change the jathi (or even gati) on the fly in a phrase. The given pattern is then 'cycled through'.
     
    (gen-karnatic-cell 4 '(5 5 3 3) '(0 6 3 2 1 0))
    => ((5/16) (1/16 1/16 1/16 1/16 1/16) (1/16 1/16 1/16) (1/16 1/16 1/16) (1/4 1/16) (5/16))

    You can also randomise your position
     
    (gen-karnatic-cell 4 5 '(0 1 ? ? 0))
    => ((5/16) (1/4 1/16) (3/16 1/8) (3/16 1/16 1/16) (5/16))

    And I did not even start discussing the other parameters yet. For example, you can set whether or not cells start with a durational accent (not a karnatic concept, but very useful notion for Western ears when dealing with rhythm). 
     
    (gen-karnatic-cell 4 5 '(3 3 3 3) :accented? '(T nil nil T))
    => ((3/16 1/16 1/16) (1/16 3/16 1/16) (1/16 3/16 1/16) (3/16 1/16 1/16))
     
    You can filter in various ways want kind of rhythm you want, e.g., set the minimum or maximum number of notes per cell. 
     
    (gen-karnatic-cell 4 5 '(? ? ? ?) :min-number '(3 3 3 3) :seed 1)
    =>((1/8 1/8 1/16) (3/16 1/16 1/16) (1/16 1/16 1/16 1/16 1/16) (1/8 1/8 1/16)) 
     
    EDIT: Oops, that are is seemingly not fully working as expected.
     
    I stop here and refer you do the documentation for more details: there are several more arguments that I did not even mention yet. I know that my documentation is rather concise and not a textbook, but it briefly discusses every detail. I said from the beginning, I wrote this for myself, so you might want to first spend a bit of time with the doc 🙂
     
    As you hopefully can see, this function alone allows for a rather rich world of rhythm with rather precise control that allows varying some rhythmic idea in various ways. I am interested here in clearly perceivable rhythmic similarities, e.g., between rhythms in different gati and jathi combinations in the Western tradition of thematic variation.  
     
    Of course, you can also process the result further in various ways. E.g., I am adding ties after long notes and/or subdivide short notes to increase the rhythmic contrast, and I am turning certain notes into rests...
     
    Best,
    Torsten
     
    (defun articulate-phrase (sequence &key (accent 'marc))
      "Add articulations to phrase for more clear rhythmic accents, e.g, an accent on every first beat.
      
      NOTE: This function assumes that `sequence' is a purely rhythmic OMN expression with only length values and perhaps ties. However, a sequence with (constant) pitches is returned, because certain Opusmodus functions do not support an OMN sequence without pitches.
      Examples:
      (articulate-phrase '((h h) (q q q q tie) (q q q q) (-q q) (q q q q)) :accent 'marc)
      => ((h marc h) (q marc q q q tie) (q q q q) (-q q) (q marc q q q))
      "
      (cons 
       ;; First bar
       ;;; NOTE: code repetition...
       (let ((bar1 (first sequence)))
         (if (length-notep (first bar1))
           (if (and (= (count-notes bar1) 1)
                    (eql (first (last bar1)) 'tie))
             (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar1)
             (tu:insert-after bar1 0 accent))
           bar1))
       ;; other bars
       (loop :for (bar1 bar2) :on sequence :while bar2
         ;;; NOTE: code repetition
         :collect (if (and (length-notep (first bar2))
                           (not (eql (first (last bar1)) 'tie)))
                    (if (and (= (count-notes bar2) 1)
                             (eql (first (last bar2)) 'tie))
                      (tu:replace-element (merge-articulations (list accent 'tie)) 1 bar2)
                      (tu:insert-after bar2 0 accent))
                    bar2))))
     
  12. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  13. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    Good to hear things are working for you 😉
     
    Note that dependencies of this library are of interest on their own for computer-aided composition. This is particularly true for the constraint library cluster engine and its extension cluster rules, as well as the library fenv. 
     
    Torsten
  14. reaction_title_2
    torstenanders got a reaction from JulioHerrlein in Updated library of many custom Opusmodus functions   
    Actually, these are warnings and not errors. They point out various issues in the code that could be improved (in particular in the library cluster engine, as you may have noticed), but the code should still work overall. Also, you should see these compilation and warning messages only once (if you never change the code of the relevant library).
     
    Just try to go on and actually run some examples of these libraries. 
     
    Please let me know if you run into an actual error message. (There are some minor bugs of course, but at least for my tot library I try to make them explicit in the documentation as well.)
     
    Best,
    Torsten
  15. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  16. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  17. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  18. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  19. reaction_title_2
    torstenanders got a reaction from AM in Updated library of many custom Opusmodus functions   
    Dear all,

    I updated my library tot (https://github.com/tanders/tot) in various ways. In particular, there are many new functions available.

    You can now read the documentation online at https://tanders.github.io/tot/. However, remember that you can directly evaluate the many examples in the documentation when (after installing the library) you drag the library folder into your Opusmodus project navigator and open the documentation within Opusmodus.
     
    If you are interested in the details of how the library developed, you can see a changelog at https://github.com/tanders/tot/commits/master .

    NOTE: When you install/upgrade this library, make sure you also install/upgrade all its dependencies, as described in the detailed installation instructions at https://github.com/tanders/tot. 
     
    Best,
    Torsten
     
    PS: This is not an official release. As I am primarily developing this library for my own purposes, I keep it rather informal and extend it on a continuous basis for my own composition projects. Anyway, I thought at least some of you might be interested to learn that there have been many developments 🙂
  20. reaction_title_1
    torstenanders got a reaction from AM in Notating and auditioning irregular time signature   
    For sound synthesis purposes (e.g., for an expressive performance), we may want to use note lengths beyond the restricted set of quantised note durations. However, Opusmodus currently prevents various irregular note duration sequences to be auditioned and throws an error instead. What is really interesting, though, is that the notation for such irregular durations still seem to work. It might make sense the other way round (i.e. refusing to notate certain rhythms -- though I am definitely not voting for introducing that :), but I don't see any real reason why arbitrary rhythms may not be auditioned. 
     
    As an example, below is a short example of some arbitrary non-regular rhythm. Opusmodus can notate this rhythm, but when trying to play it back it throws an error.
     
    '((1/10 1/11 1/12 1/13))
     
    Thanks! 
     
    Best,
    Torsten 
  21. reaction_title_1
    torstenanders reacted to AM in HELP on ALL Interval 12-tone Rows and 12-tone control   
    ... a keyword/text search within the feature descriptions would be very useful.... so if i search "all-interval" i could find AIR etc....
  22. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Re-auditioning selected shown scores/snippets   
    It is handy that Opusmodus can display multiple score snippets and full scores alongside each other.
     
    Is there perhaps also a way to re-play some snippet still shown? Either with some GUI element that I may have missed or programmatically (they all have a unique name shown, like "UNTITLED 101 (Snippet)").? There is a function audition-musicxml-last-score, is there perhaps a function to again audition a score that is specified by its name? 
     
    Thanks! 
     
    Best,
    Torsten
  23. reaction_title_1
    torstenanders got a reaction from JulioHerrlein in Re-auditioning selected shown scores/snippets   
    It is handy that Opusmodus can display multiple score snippets and full scores alongside each other.
     
    Is there perhaps also a way to re-play some snippet still shown? Either with some GUI element that I may have missed or programmatically (they all have a unique name shown, like "UNTITLED 101 (Snippet)").? There is a function audition-musicxml-last-score, is there perhaps a function to again audition a score that is specified by its name? 
     
    Thanks! 
     
    Best,
    Torsten
  24. reaction_title_1
    torstenanders reacted to opmo in How to force a time signature for Snippet fast use   
    You find them all in the snippet document.
  25. reaction_title_1
    torstenanders got a reaction from loopyc in Composing various polyphonic textures concisely   
    I am interested in controlling musical textures, i.e., relations between polyphonic parts. I defined a bunch of functions that use the simple polyphonic music representation used also by my function preview-score that I presented shortly (see https://opusmodus.com/forums/topic/902-polyphonic-preview/#comment-2686). Apologies that this post is a bit longer. 
     
    Here is a particularly flexible function: map-parts transforms a polyphonic score. It is a variant of the standard Lisp function mapcar, where a function is applied to every part in a score, but each instrument/part can be given its own function arguments for the transformation. One argument is the respective part of the score. This argument is marked by an underscore (_) in the argument lists.
     
    In the following example, the function pitch-transpose is applied to a score with two very simple parts consisting of only a single note each. This function has two required arguments, a transposition interval (measured in semitones), and the pitch sequence or OMN to transpose. The transposition interval for the first part is 4 (major third upwards), and the underscore marks the position of the violin part to transpose, etc.
     
    Note that you can always see and hear the resulting score by wrapping preview-score around each example. Hopefully these examples sufficiently demonstrate my need to have some shortcut for preview-score :)
    (map-parts '(:vln ((h e4)) :vlc ((h c3))) #'pitch-transpose '(:vln (4 _) :vlc (12 _))) => (:vln ((h gs4)) :vlc ((h c4)))  
    Here are a few more relatively simple application examples. I am first defining some musical material to reduce the length of the remaining definitions. 
    (setf material '((-3h fs4 pp eb4 <) (q e4 < fs4 <) (3h gs4 mp> a4 > bb4 >) (q a4 pp -) (-5h - g4 pp leg eb4 < leg d4 < leg) (q bb4 < e4 <) (5h g4 mp> leg b4 > leg a4 > leg bb4 > leg d4 > leg) (q gs4 pp -)))  
    Now, the next example creates a strict canon formed with the given material -- but without following any counterpoint rules :)  For different parts the material is metrically shifted and transposed.
    This example also shows that map-parts calls can be nested (naturally). The function metric-shift appends some rest before some musical material, but preserves its rhythmical structure, i.e. metrically shifts the material.   
    (map-parts (map-parts `(:vl1 ,material :vl2 ,material :vla ,material :vlc ,material) #'metric-shift '(:vl1 :skip ;; :skip means to leave part unchanged :vl2 (-q _) :vla (-h _) :vlc (-h. _))) #'pitch-transpose '(:vl1 (6 _) :vl2 (4 _) :vla (2 _) :vlc :skip))  
    The next examples shows some simple homorhythmic texture created by randomised transpositions. Each part shares a similar overall pitch profile. Note also that calls can be more concise with a (lambda) function that nests calls to transformation functions -- instead of nesting map-parts as shown above.
    (map-parts `(:vl1 ,material :vl2 ,material :vla ,material :vlc ,material) #'(lambda (transpose seq) ;; static transposition for moving parts into different registers (pitch-transpose transpose ;; randomised transposition of notes in parts (pitch-transpose-n (rnd 10 :low -2 :high 2) seq))) '(:vl1 (7 _) :vl2 (0 _) :vla (-10 _) :vlc (-20 _)))  
    Finally, here is a homophonic texture created by random pitch variants (retrograde, inversion etc.). The global pitch profiles of parts differ here, in contrast to the previous example.
    (map-parts `(:vl1 ,material :vl2 ,material :vla ,material :vlc ,material) #'pitch-variant `(:vl1 (_ :transpose 7 :seed 10) :vl2 (_ :transpose 0 :seed 20) :vla (_ :transpose -10 :seed 30) :vlc (_ :transpose -20 :seed 40)) :shared-args '(:variant ?))  
    All these examples demonstrate very conventional textures, as such textures are more easy to explain.  
     
    For completeness, below is the definition of MAP-PARTS. There are various dependencies that I tried all to add as well. Please let me know if I missed any definition, and apologies in advance.
     
    Best,
    Torsten
    (defun map-parts (score fn part-args &key (parameter nil) (shared-args nil)) "Create or transform a polyphonic score. The original purpose is for creating/transforming musical textures, i.e., relations between polyphonic parts. Applies function `fn' to parts in `score': this function is a variant of the standard Lisp function `mapcar', but specialised for scores. A score is represented in the format discussed in the documentation of the function `preview-score'. Additional arguments for `fn' can be specified in `part-args', and these argument lists can be different for each part. However, one argument is the part of the score. This argument is marked by an underscore (_) in the argument lists. In the following example, the function `pitch-transpose' is applied to a score with two parts. This function has two required arguments, a transposition interval (measured in semitones), and the pitch sequence or OMN to transpose. The transposition interval for the first part is 4 (major third upwards), and the underscore marks the position of the violin part to transpose, etc. ;;; (map-parts '(:vln ((h e4)) ;;; :vlc ((h c3))) ;;; #'pitch-transpose ;;; '(:vln (4 _) ;;; :vlc (12 _))) Args: - score (headerless score): See {defun preview-score} for format description. - fn: A function that expects and returns an OMN sequence or a sequence of parameter values (e.g., lengths, or pitches) as specified in the argument `parameter'. - part-args (plist): Alternating instrument keywords (same as in `score') followed by arguments list for `fn' for that instrument/part. If arguments is :skip, then that part is returned unchanged. - parameter (omn parameter, e.g., :length or :pitch, default nil means processing full OMN expression): If `fn' expects only single parameter to process, then it can be set here. - shared-args (list): For all instruments/parts, these arguments are appended at end end of its part-specific arguments. They are useful, e.g., for keyword arguments. " ;; catching hard-to-find user error... (let* ((instruments (get-instruments score)) (missing-instruments (remove-if #'(lambda (arg-instr) (member arg-instr instruments)) (get-instruments part-args)))) (assert (not missing-instruments) (part-args) "map-parts: Some instruments in `part-args' don't have a matching instrument in `score'. ~A.~%" missing-instruments)) (let ((parts (make-hash-table :test #'equal))) ;; fill hash table, using leading keywords as keys (loop for part in (tu:plist->pairs score) do (setf (gethash (first part) parts) part)) (tu:pairs->plist (loop for instrument-arg-pair in (tu:plist->pairs part-args) for instrument = (first instrument-arg-pair) for part = (gethash instrument parts) for part-omn = (second part) for fn-args = (second instrument-arg-pair) collect (if (equal fn-args :skip) part ; no processing (cons instrument (let ((result (apply fn (append (substitute (if parameter (omn parameter part-omn) part-omn) '_ fn-args) shared-args)))) (list (if parameter (omn-replace parameter result part-omn) result))))) )))) (defun metric-shift (l lengths) "Appends `l' (a length or omn) before `lengths' (a list of lengths or omn), but maintains the metric structure, i.e., the function shifts `lengths' metrically 'to the right' by `l'. Returns an OMN form if lengths is an OMN form, otherwise a length form. Related: assemble-seq (but that does not shift across bars)" (let* ((time-sigs (get-time-signature lengths)) (result (omn-to-time-signature (cons l (flatten lengths)) time-sigs))) (if (omn-formp lengths) result (omn :length result)))) ; (metric-shift '-h '((q q q q) (q q q q))) ; (metric-shift '(h g4) '((q c4 q d4 q e4 q f4) (q c4 q d4 q e4 q f4))) (defun get-instruments (score) "Returns all instruments of `score', a headerless score (see {defun preview-score} for its format)." (at-even-position score)) (defun at-even-position (in-list) (at-position in-list 2 0)) (defun at-position (in-list factor offset) "Returns a list containing every factor-th elements of in-list starting at offset" (mapcar #'(lambda (i) (nth i in-list)) (arithmeric-series factor offset (ceiling (/ (length in-list) factor))))) (defun arithmeric-series (factor offset length) (let (result) (reverse (dotimes (i length result) (push (+ (* i factor) offset) result))))) (defun plist->pairs (plist) (loop :for (key val) :on plist :by #'cddr :collect (list key val))) (defun pairs->plist (pairs) (one-level-flat pairs)) (defun one-level-flat (list) "flatens one level of the given form. Example: (one-level-flat '(((note) (note)) ((pause) (pause)) ((note)))) -> ( (note) (note) (pause) (pause) (note))" (apply #'append list))  
×