Jump to content
Sign in to follow this  
opmo

Opusmodus 1.3.24622

Recommended Posts

Free update for Opusmodus 1.3. users.

It includes a support for a second screen and multi voice snippets.

The new UNFOLD system opens up a whole new set of possibilities for the composer using OPUSMODUS.
Additional library directory: 'Def-Instrument-Sets'. 

 

New functions:


DEF-INSTRUMENT-SETS

Use this function to define the instrument-sets with a given name. With named instrument-sets a composer can customise OPUSMODUS to reflect MIDI synthesisers or samplers which a studio system (inboard or outboard) might contain. The DEF-INSTRUMENT-SETS function is an essential companion to the PS function (PS stands for ‘Preview Score’ or, ‘Preview Snippet’). To create instrument-sets is fairly easy to do as it resembles the instrument setup from the DEF-SCORE instance.

 

The instrument-set template:

<instrument-name>
(:layout <layout>
  :port <port>
  :channel <channel>
  :sound <sound-set>
  :program <program>
  :controllers <controllers>
  :pan <panning>
  :volume <volume>)

 

To explain how it all works we will define new instrument-sets with two instruments. In our example we will use :oboe and :bassoon as our instrument names with a library name: my-inst. The next step we need to do is to select the corresponding instrument layout. The predefined layouts you will find in the ‘Instrument Layout Presets’ document in the System/Layout library:

 

1D34467B-C851-44F9-9363-3B263FD15CF3.png

 

Examples:

(def-instrument-sets my-inst
                     :instruments
  (:group group
          :oboe
          (:layout oboe-layout
                   :port nil
                   :channel 1
                   :sound 'gm
                   :program '(oboe)
                   :controllers nil
                   :pan (pan 0)
                   :volume 92)

          :bassoon
          (:layout bassoon-layout
                   :port nil
                   :channel 2
                   :sound 'gm
                   :program '(bassoon)
                   :controllers nil
                   :pan (pan -10)
                   :volume 92)
          ))

 

Here is how an instrument from a defined instrument-sets name might be entered into PS:

(ps 'my-inst
    :oboe (list '((s a4 leg d5 leg fs4 leg d5 leg g4 leg d5)
                  (s a4 leg d5 leg fs4 leg d5 leg g4 leg d5)
                  (s a4 leg d5 leg cs5 leg b4 leg a4 leg g4 leg)
                  (s fs4 leg d4 leg e4 leg cs4 leg e d4)))
    :bassoon (list '((e fs3 d3 e3)
                     (e fs3 d3 e3)
                     (e fs3 g3 a3)
                     (e d3 a2 d2)))
    :key-signature '(d maj)
    :time-signature '(3 8 1)
    :tempo 112)

 

You can define as many instrument-sets instances as needed.

 

 


PS

Use this function if you are looking for a quick preview of your score or when a snippet (especially for education) needs a full representation of the intended notation. The PS function name stands for ‘Preview Score’ or ‘Preview Snippet’. In the following examples we use the default instrument-sets library, defined in the ‘GM Instrument Sets.lisp’ file, which you will find in the Library panel. How to create your own instrument-sets library, you will find in the DEF-INSTRUMENT-SETS document.

 

Instrument treble:

(ps 'gm
    :treble (list '((s a4 leg d5 leg fs4 leg d5 leg g4 leg d5)
                    (s a4 leg d5 leg fs4 leg d5 leg g4 leg d5)
                    (s a4 leg d5 leg cs5 leg b4 leg a4 leg g4 leg)
                    (s fs4 leg d4 leg e4 leg cs4 leg e d4)))
    :key-signature '(d maj)
    :time-signature '(3 8 1)
    :tempo 112)

Screenshot 2019-03-05 at 12.13.39.png

 

Instrument piano:

(ps 'gm
    :p (list '((s a4 leg d5 leg fs4 leg d5 leg g4 leg d5)
               (s a4 leg d5 leg fs4 leg d5 leg g4 leg d5)
               (s a4 leg d5 leg cs5 leg b4 leg a4 leg g4 leg)
               (s fs4 leg d4 leg e4 leg cs4 leg e d4))
             '((e fs3 d3 e3)
               (e fs3 d3 e3)
               (e fs3 g3 a3)
               (e d3 a2 d2)))
    :key-signature '(d maj)
    :time-signature '(3 8 1)
    :tempo 112
    :title "G. Ph. Telemann, 12 Fantasie per clavicembalo TWV 33-n.1, 1732")

 

Screenshot 2019-03-05 at 12.13.57.png

 

Examples:

The examples below demonstrate how quickly you can preview your progress at any stage of your work ie. voices, instrumentation etc…

 

(setf
p1 '(q d4 pp s eb4 < leg g4 < leg bb4 < leg a4 q. cs5 mf -e
      3q gs5 > leg fs5 > leg c5 > b4 > leg f4 leg e4)

p2 '(t d4 < leg eb4 < leg g4 < leg bb4 q. a4 marc
      t fs4 mf leg gs4 leg e. c5 e b4 t f5 leg e5 leg d5 leg
      eb5 3q bb5 > a4 > bb5 > e a4 pp stacc -e)

p3 '(q d5 leg eb5 3q g4 stacc bb4 stacc a4 stacc
      e. cs4 marc s gs4 leg q gs4 -q)

p4 '(-q. e d4 pp q. eb5 mf e g4 q bb4 trem a4 trem)

p5 '(q. fs3 pp 3e c3 < leg b4 < leg f4 e d3 mf s eb3 leg
      g3 leg bb3 leg a3 e fs3 leg fs3 3e gs4 > stacc
      c5 > stacc b5 > stacc t f5 pp e.. e5)

p6 '(q cs3 pp -q t gs3 marc e.. fs3 mf leg e c3 -e
      t b3 leg f3 q.. e4 pp)
)

 

Please note how the list function is used to enclose the instrument voices. The number of voices in an instrument should not exceed the layout of a particular instrument. For example a piano uses a two staff notation therefore the input should be a two lists in a list (list (list right-hand) (list left-hand)).

 

(ps 'gm :p (list (list p1) (list p6)))

 

Screenshot 2019-03-05 at 13.16.49.png

 

 

Instrument oboe, clarinet and bassoon:

(ps 'gm
    :ob (list p1)
    :cl (list p3)
    :bn (list p6))

 

Screenshot 2019-03-04 at 18.26.07.png

 

Brass Quintet:

(ps 'gm :b5 (list p1 p2 p3 p4 p5))

 

 

18CA159A-7022-4DA9-9241-904C937F2F48.png

 

 

 


DEF-UNFOLD

UNFOLD

 

The DEF-UNFOLD and UNFOLD function opens up a whole new set of possibilities for the composer using OPUSMODUS. It can prove a very powerful tool in defining methods (functions) from the outset, for a specific work or as a global index of your most used functions. To be able to store methods, processes and solutions and call them at anytime becomes a valuable resource for a composers workflow. This function is a companion to the UNFOLD function.

(def-unfold m1
  var (:pitch (pitch-variant x :variant '?))
  dyn (:velocity (velocity-to-dynamic x))
  )

 

(setf omn '(s bb4 p a4 h. db4 t gs4 mf fs4 c5 b4 q f5 e5))

 

To run the defined methods in a given omn-form sequence use the UNFOLD function:

(unfold 'm1 '(var dyn) omn)

 

Examples:

(def-unfold m2
  7   (:pitch (pitch-transpose 7 x))
  -12 (:pitch (pitch-transpose -12 x))
  ret (:all (gen-retrograde x :flatten t))
  var (:pitch (pitch-variant x :variant '?))
  gf  (nil (gen-fragment '(3) '(3) x))
  lrq (:length (length-rational-quantize x))
  dyn (:velocity (velocity-to-dynamic x))
  ls  (nil (length-span '(6/4 6/4) x))
  ob  (:pitch (ambitus 'oboe x))
  bn  (:pitch (ambitus 'bassoon x))
  hn  (:pitch (ambitus 'french-horn x))
  )

 

Please note that the number of methods within an instance can be much bigger than in the example above.

 

Two bars of omn - opusmodus notation

(setf mat '((q d4 pp s eb4 < leg g4 < leg bb4 < leg a4 q. cs5 mf
             -e 3q gs5 > leg fs5 > leg c5 > b4 > leg f4 leg e4)
            (t d4 < leg eb4 < leg g4 < leg bb4 q. a4 marc
             t fs4 mf leg gs4 leg e. c5 e b4 t f5 leg e5 leg d5 leg eb5
             3q bb5 > a4 > bb5 > e a4 pp stacc -e)))

 

Applying methods:

(setf
t1 (unfold 'm2 7 mat)
t2 (unfold 'm2 '(-12 var ob) mat)
t3 (unfold 'm2 'var mat)
t4 (unfold 'm2 '(-12 gf lrq ls dyn ret var hn) t3)
t5 (unfold 'm2 '(gf lrq ls dyn bn) t2)
)

 

The result with a Wind-Quintet layout:

(ps 'gm :w5 (list t1 t2 t3 t4 t5))

 

Screenshot 2019-03-07 at 17.20.08.png

 

 


 

BIND-TO-INTERVAL

 

The function BIND-TO-INTERVAL will bind (connect) a series of lists (patterns) to each-other with the given interval. Each transposition value is the sum of the last pitch in the list plus the given interval. The result of the process is a start transposition value for the next list. If rotate and variant options are used, the rotate process is the first followed by variant and finally the start transposition.

 

In the example below the last pitch in the first list is g4, with binding interval 1 (semitone), therefore the start transposition value of the next list is gs4:

(bind-to-interval '(1) '((s c4 d4 e4 g4) (s c4 d4 g4 e4)))
=> ((s c4 d4 e4 g4) (s gs4 bb4 eb5 c5))

 

Examples:

(setf pattern '((s c4 d4 e4 g4)
                (s c4 d4 g4 e4)
                (s g4 e4 c4 d4)
                (s c4 d4 f4 g4)
                (s c4 d4 g4 f4)
                (s g4 f4 c4 d4)
                (s c4 d4 g4 f4)
                (s g4 gb4 f4 g4)
                (s g4 gb4 f4 a4)
                (s d4 f4 g4 a4)
                (s a4 g4 f4 d4)
                (s d4 f4 g4 c5)))

 

In this example the binding intervals are 1 and 2 randomly selected:

(bind-to-interval (rnd-sample (length pattern) '(1 2)) pattern)
=> ((s c4 d4 e4 g4) (s gs4 bb4 eb5 c5) (s d5 b4 g4 a4) (s b4 cs5 e5 fs5)
    (s g5 a5 d6 c6) (s d6 c6 g5 a5) (s bb5 c6 f6 eb6) (s f6 e6 eb6 f6)
    (s g6 fs6 f6 a6) (s bb6 cs7 eb7 f7) (s fs7 e7 d7 b6) (s cs7 e7 fs7 b7))

 

In the next example the binding intervals are 13 and -13 with random variant:

(bind-to-interval (rnd-sample (length pattern) '(13 -13)) pattern :variant '?)
=> ((s c4 d4 e4 g4) (s fs3 a3 e3 d3) (s eb4 fs4 bb4 gs4) (s g3 f3 d3 c3)
    (s b1 a1 e1 fs1) (s g2 f2 bb2 c3) (s b1 a1 d2 e2) (s eb1 eb1 d1 cs1)
    (s d2 cs2 c2 e2) (s f3 d3 c3 bb2) (s b3 d4 e4 fs4) (s g5 bb5 c6 f6))

 

Here the binding intervals are 1, -1, 2 -2:

(bind-to-interval '(1 -1 2 -1 2 -1 2) pattern)
=> ((s c4 d4 e4 g4) (s gs4 bb4 eb5 c5) (s b4 gs4 e4 fs4) (s gs4 bb4 cs5 eb5)
    (s d5 e5 a5 g5) (s a5 g5 d5 e5) (s eb5 f5 bb5 gs5) (s bb5 a5 gs5 bb5)
    (s b5 bb5 a5 cs6) (s c6 eb6 f6 g6) (s a6 g6 f6 d6) (s cs6 e6 fs6 b6))

(bind-to-interval '(1 -1 2 -1 2 -1 2) pattern :variant '?)
=> ((s c4 d4 e4 g4) (s gs4 f4 bb4 c5) (s b4 gs4 e4 fs4) (s gs4 bb4 cs5 eb5)
    (s d5 c5 a4 g4) (s a4 g4 e4 d4) (s cs4 eb4 gs4 fs4) (s gs4 a4 bb4 gs4)
    (s a4 bb4 b4 g4) (s fs4 a4 b4 cs5) (s eb5 c5 bb4 gs4) (s g4 e4 d4 a3))

 

Example with rotation:

(bind-to-interval (rnd-sample (length pattern) '(1 2)) pattern
                  :rotate '(1 2 1 2 1))
=> ((s c4 d4 e4 g4) (s a4 f4 g4 c5) (s d5 e5 a5 fs5) (s gs5 cs5 eb5 fs5)
    (s gs5 fs5 cs5 eb5) (s e5 a5 g5 d5) (s e5 b4 cs5 fs5) (s g5 a5 a5 gs5)
    (s bb5 gs5 g5 fs5) (s g5 a5 d5 f5) (s g5 d6 c6 bb5) (s c6 d5 f5 g5))

 

 


PAN

 

This function converts mixer panning values in the range from -100(L) to 100(R) into MIDI pan values. The centre position value in the PAN function is 0.

 

Examples:

(pan 0)
=> 64

(pan '(-12 0 12))
=> (56 64 72)

(pan '(-30 -10 10 30))
=> (45 58 70 83)

 

PAN in DEF-SCORE instrument instants definition:

(def-score SQ
           (:title "String Quartet - VSL Show"
            :key-signature 'chromatic
            :time-signature (get-time-signature vln1)
            :tempo tempo
            :layout (string-quartet-layout
                     'violin1 'violin2 'viola 'cello))
  
  (violin1
   :omn vln1
   :port 0
   :channel 1 :sound 'vsl-violin-solo
   :program 0 :pan (pan -30))
  
  (violin2
   :omn vln2
   :channel 2 :sound 'vsl-violin-solo
   :program 0 :pan (pan -10))
  
  (viola
   :omn vla
   :channel 3 :sound 'vsl-viola-solo
   :program 0 :pan (pan 10))
  
  (cello
   :omn vlc
   :channel 4 :sound 'vsl-cello-solo
   :program patches-vc :pan (pan 30))
  )

 

PAN in DEF-INSTRUMENT-SETS instance:

:string-quartet
  (:layout string-quartet-layout
           :port nil
           :channel '(1 2 3 4)
           :sound 'gm
           :program '(violin violin viola cello)
           :controllers nil
           :pan (pan '(-30 -10 10 30))
           :volume 92)

 

 


Multi Voice Snippet

 

Select or place the mouse cursor at the end of the expression and press ⌘2.

This snippet is very useful in sketching and testing the progress of your work ie. instrumentation, voice density etc…

(setf p1 '(q d4 pp s eb4 < leg g4 < leg bb4 < leg a4 q. cs5 mf -e
           3q gs5 > leg fs5 > leg c5 > b4 > leg f4 leg e4)
      p2 '(t d4 < leg eb4 < leg g4 < leg bb4 q. a4 marc
           t fs4 mf leg gs4 leg e. c5 e b4 t f5 leg e5 leg d5 leg
           eb5 3q bb5 > a4 > bb5 > e a4 pp stacc -e)
      p3 '(q d5 leg eb5 3q g4 stacc bb4 stacc a4 stacc
           e. cs4 marc s gs4 leg q gs4 -q)
      p4 '(q. fs3 pp 3e c3 < leg b4 < leg f4 e d3 mf s eb3 leg
           g3 leg bb3 leg a3 e fs3 leg fs3 3e gs4 > stacc
           c5 > stacc b5 > stacc t f5 pp e.. e5)
      p5 '(-q. e d4 pp q. eb5 mf e g4 q bb4 trem a4 trem)
      p6 '(q cs4 pp -q t gs4 marc e.. fs4 mf leg e c4 -e
           t b4 leg f4 q.. e4 pp)
      p7 '(-q e d4 leg eb4 h g4 mf leg q. g4 > -e)
      p8 '(s bb3 pp leg a3 h. db3 t gs4 mp fs3 < c5 < b3 q f4 marc e4)
      )

(list p1 p2 p3 p4)

 

Screenshot 2019-02-27 at 17.29.04.png

 

 

 


 

New window display:

(display-midi *last-score* :display :window)
(display-musicxml 'score :display :window)

 

Changes to ‘Evaluate Score’ and ‘Last Score’ shortcut keys.

 

Best wishes,

Janusz

Share this post


Link to post
Share on other sites

I really like seeing the function ps and multi-voice snippet previews -- and ps looks a bit familiar 🙂

TANDERS.GITHUB.IO

 

However, perhaps we can do even better. The real power of the monophonic (old) snippets preview is that in a sequence of algorithmic transformations of musical material, quick score previews can be seen/heard of any intermediate stage without any extra code, just with those snipped keyboard shortcuts. For example, in the 2nd line of short code below, using the shortcut cmd-1 we can see/hear the original motif, its transposition and the inversion of that by simply placing the cursor at different positions in the code before executing that shortcut.

(setf motif-a '(e. ab3 leg s bb3 leg q c4))
(pitch-invert (pitch-transpose 4 motif-a))

 

It would be great to have the same expressive power for polyphonic score snippets. My library (linked above) already contains a number of functions for processing polyphonic scores (e.g., for transposing all parts of a score, or only selected parts). For example, see my functions map-parts or map-parts-equally, that allow to concisely transform selected or all parts of polyphonic scores with arbitrary Opusmodus functions for single parts and possibly part-specific arguments. There function generate-parts does something similar, but starts the music generation from scratch without any input polyphonic score snippet. There are also functions for combining polyphonic snippets in various way (e..g, mixing them or appending them, for replacing instruments etc.)

TANDERS.GITHUB.IO

 

TANDERS.GITHUB.IO

 

The key is having a data structure for polyphonic music that is handed and processed by functions and then somehow processed data in that format is returned -- as Opusmodus does all the time for single parts. However, what I could not do is define is a shortcut for previewing such polyphonic score snippets, which is why I had to instead define a function preview-score that must be called explicitly. 

 

Now, the new multi-voice snippet previews do something similar, but it only works on lists of un-named parts. It could be more powerful by also allowing for the format expected by the function ps. When we only have unnamed parts they can only be identified by their position, which can be tricky, e.g., if during some short section of a piece only certain instruments are playing (well, silent parts can still be represented with rests to preserve the position of parts, but it adds an unnecessary overhead). Also, when doing many transformations on polyphonic scores with many parts with part-specific arguments, the code is easier to read if it refers to specific parts by their name instead of their position.

 

Long story short -- why not having a shortcut for basically what the function ps does, i.e. for a score format with named parts and annotations like tempo etc? It makes perfectly sense musically to algorithmically work with polyphonic snippets that contain all such information, mangle them in various ways, append them etc -- and being able to preview intermediate results at any stage with a mere keyboard shortcut  🙂

 

PS: Apologies for reacting rather late to this...

Share this post


Link to post
Share on other sites

I am trying to clarify my point by adding an example. With the new multi-voice snippet previews we can now do arbitrary processing of polyphonic score snippets. In the code below, some short polyphonic snippet is transposed, but different parts are transposed differently. With this approach, arbitrary Opusmodus functions defined for single parts can be used for processing full polyphonic score snippets on one go, and arbitrary combinations of arguments for such Opusmodus functions can be provided. The trick is to include some special symbol (_) for marking the position of the actual part in the argument list (as different functions expect an OMN sequence at different argument positions), and then in the loop to replace that symbol with the part itself.

 

(setf poly-snippet-1
      '(((q g4) (q. c5 e d5 q e5 f5) (h. e5)) 
        ((q g3) (q c4 b3 a3 g3) (h. c3))))

(loop 
  for part in poly-snippet-1
  for args in '((2 _)
                (7 _))
  collect (apply #'pitch-transpose (substitute part '_ args)))

 

Side note:  #'pitch-transpose  is the function pitch-transpose (instead of a variable named that way). The function apply takes such a function as a first argument and its arguments as a second argument and calls that function. It is somewhat similar to using eval (in case you came across that before), but apply (or its cousin funcall) is preferable in almost all cases over eval (if you are interested in the details, see the link below, interestingly labelled Why exactly is eval evil?: 

apple-touch-icon@2.png?v=73d79a89bded
STACKOVERFLOW.COM

I know that Lisp and Scheme programmers usually say that eval should be avoided unless strictly necessary. I’ve seen the same recommendation for several programming languages, but I’ve not yet seen a

 

While my transposition example above is all good and dandy, for more complex cases and even more so when multiple such transformations are nested -- which is after all what we do all the time -- I would prefer a somewhat more concise notation, and ideally be able to refer to individual parts by the name of their instrument. Below is an example that does that (using code from my library linked above).

(setf poly-snippet-2
      '(:vln ((q g4) (q. c5 e d5 q e5 f5) (h. e5)) 
        :vlc ((q g3) (q c4 b3 a3 g3) (h. c3))))

(map-parts poly-snippet-2
           #'pitch-transpose 
           '(:vln (2 _) 
             :vlc (7 _)))

 

The function map-parts above could obviously be rewritten for the format of poly-score-1, where parts are referred to only by position, but I find naming by part more clear for more complex cases. It would likely be best to have both 🙂   The function map-parts also provides a bunch of other features, that would be far more complex to reproduce with an explicit loop, check out the documentation linked above if you are interested...

 

BTW: I reconsidered what I mentioned above concerning including information like the tempo etc. in the format of the score snippet. While that is possible in principle, perhaps it makes things unnecessarily complex. If we represent a score by a list with keywords labelling instruments (a plist), information like the tempo, key signature etc. could not easily be distinguished. We would better adapt the format (e.g., wrap all parts in an extra list) to make this distinction clear and easily parsable (below is an example), but such a format might become more complex than what we want. Tricky...

 

((:vln ((q g4) (q. c5 e d5 q e5 f5) (h. e5)) 
  :vlc ((q g3) (q c4 b3 a3 g3) (h. c3))
 :tempo 90
 :time-signature 'whatever)

 

Share this post


Link to post
Share on other sites

All this can be done (and more) with PSDEF-INSTRUMENT-SETEDIT-EVENTS and UNFOLD functions.

Share this post


Link to post
Share on other sites

Thank you for coming back.

 

Of course, different approaches and workflows are possible, but these tend to influence what kind of musical results we are getting (e.g., certain approaches and workflows make certain musical results more easy to achieve, and therefore ending up generating these is more likely).  

 

Specifically, the functions you mention (and most of the Opusmodus functions in general) are designed for processing the part of a single instrument, and individually generated parts are then almost always combined into a polyphonic score only in a rather late or a final step. Composing in this order (creating individual parts separately and combining them into a score only rather late) is currently easier, because most functions work that way, and most examples are using that approach. 

 

Instead, I would prefer to work with polyphonic combinations of multiple parts from early on in the composition process. To state a conventional example, when composing something like a sentence or period theme, I would like to be able to vary and then string together polyphonic phrases. And that is only the lowest hierarchic level, of course such a way of working can be used on higher levels too. Or when creating more complex textures, I might generate them by superimposing multiple phrases that are already polyphonic and for multiple instruments in themselves. As a composer, I find it rather natural to use building blocks that already consist of multiple parts for multiple instruments, and then transform such building blocks in various ways for creating variations. 

 

Anyway, I can already do that with my music representation discussed above, I only would find it more convenient to see intermediate results with a mere shortcut.  I guess at some stage we might have support for user-defined keyboard shortcuts, and then I can define one for myself for notating and auditioning intermediate results that are polyphonic score representation with explicitly annotated parts. In the meantime, I just explicitly call my function preview-score, not too much of a deal 🙂

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Topics

    • By opmo
      – Function name changes:
      LENGTH-DIVIDE2 to LENGTH-SUBDIVISION
      LENGTH-DIVIDE3 to LENGTH-SYNCOPATE

      – Function update:
      LENGTH-DIVIDE – changes to arguments.
      LENGTH-SUBDIVISION – changes to arguments.
      LENGTH-SYNCOPATE – changes to arguments.
      POLYGON-RHYTHM – enable fixed sides polygon. 

      – Note:
      If you used any of the functions:
      LENGTH-DIVIDE, LENGTH-DIVIDE2 or LENGTH-DIVIDE3 in your scores,
      please check new documents in order to make the necessary correction.

      – New:
      Enable or disable the DO-VERBOSE macro. 
      (defparameter *do-verbose* nil "Enable or disable traces printed by do-verbose.")  
       
      length-divide
      This function is able to divide number of lengths to a given division value. The :set and :ignore option increases the control for the desired result. When processing the omn-form sequence an optional third value allows you to fill intervalic steps (a root transposition) to new length values derived from the divisions.
       
      (setf rhy '(1/4 1/4 1/4 1/4)) (length-divide '(2 2) rhy) => (1/8 1/8 1/4 1/4 1/8 1/8) (length-divide '(2 4) rhy) => (1/4 1/16 1/16 1/16 1/16 1/16 1/16 1/16 1/16 1/4)  
      Example:
      (length-divide '(1 2) '(1/4 -1/8 1/16 1/16 -1/32 -3/32 1/8 1/1) :seed 34) => (1/4 -1/8 1/16 1/32 1/32 -1/32 -3/32 1/8 1)  
      In the example above only 1 length is divided by 2 - that is the 1/16. In the example below 4 lengths are divided by 2.
      (length-divide '(4 2) '(1/4 -1/8 1/16 1/16 -1/32 -3/32 1/8 1/1) :seed 34) => (1/8 1/8 -1/8 1/16 1/32 1/32 -1/32 -3/32 1/16 1/16 1/2 1/2) (length-divide '(1 2) '(1/4 -1/8 1/16 1/16 -1/32 -3/32 1/8 1/1) :set 'min :seed 34) => (1/4 -1/8 1/32 1/32 1/16 -1/32 -3/32 1/8 1) (length-divide '(1 4) '(1/4 -1/8 1/16 1/16 -1/32 -3/32 1/8 1/1) :set 1/8 :seed 34) => (1/4 -1/8 1/16 1/16 -1/32 -3/32 1/32 1/32 1/32 1/32 1) (length-divide '((2 3) (1 2)) '((1/4 -1/8 1/16 1/16) (1/32 -3/32 1/8 1/1)) :ignore 'max :seed 45) => ((1/4 -1/8 1/48 1/48 1/48 1/48 1/48 1/48) (1/64 1/64 -3/32 1/8 1)) (length-divide '((2 4) (1 2)) '((q -e s s) (s -e. e w)) :set 'max :ignore 1 :seed 65) => ((1/16 1/16 1/16 1/16 -1/8 1/16 1/64 1/64 1/64 1/64) (1/16 -3/16 1/16 1/16 1))
      OMN:
      (setf mat1 '(q c4 d4 e4 f4 g4 a4 b4)) (length-divide '(3 4) mat1 :seed 45) => (s d4 bb3 cs4 b3 cs4 eb4 c4 e4 q s g4 e4 eb4 fs4 q g4 a4 b4)
      Symbol 'r will apply repeat function:
      (length-divide '(3 4 r) mat1 :seed 45) => (s c4 c4 c4 c4 d4 d4 d4 d4 q e4 s f4 f4 f4 f4 q g4 a4 b4)
      Here we use a set of interval values at the end of the division list:
      (length-divide '(3 4 (13 0 1 13)) mat1 :seed 45) => (s cs5 c4 cs4 cs5 eb5 d4 eb4 eb5 q e4 s fs5 f4 fs4 fs5 q g4 a4 b4) (setf mat2 '((e c4 p e4 mp g4 he c5 p) (q c4 f c4 cs4 mp - d5 p d5) (q cs5 mf = - - cs5 p =))) (length-divide '((1 4) (2 4) (2 5)) mat2 :seed 34) => ((e c4 p e4 mp t a4 f4 gs4 fs4 he c5 p) (q c4 f s b3 cs4 bb3 d4 q cs4 mp - d5 p s c5 e5 cs5 eb5) (q cs5 mf cs5 - - 5q eb5 p b4 c5 d5 eb5 c5 eb5 b4 d5 c5))
      In the example below we assign three series of division values to variables s1, s2 and s3:
      (setf s1 '(3 4 (6 12 18 24)) s2 '(3 4 ((13 1 13 0) (13 0 7 1) r)) s3 '(2 5 ((13 0 13 0 13) ?)) ) (length-divide (list s1 s2 s3) mat2 :seed 34) => ((e c4 p t bb4 mp e5 bb5 e6 cs5 g5 cs6 g6 et fs5 p c6 fs6 c7) (q c4 f s cs5 cs4 cs5 c4 q cs4 mp - s eb6 p d5 a5 eb5 d5 d5 d5 d5) (5q d6 mf cs5 d6 cs5 d6 q cs5 - - cs5 p 5q d5 eb5 c5 b4 d5))  
       
      length-subdivision
      This function is able to divide a list of lengths into a number of subdivisions derived from a given length segment value. The :type and :position option increases the control for the desired result. When processing the omn-form sequence an optional third value allows you to fill intervalic steps (a root transposition) to new length values derived from the divisions. This function is a more sophisticated version of LENGTH-DIVIDE. It produces fascinating variants on the simplest of note-lengths, as can be seen below.
       
      (setf rhy '(1/4 1/4 1/4 1/4)) (length-subdivision '(2 1/8) rhy) => (1/8 1/8 1/8 1/8 1/8 1/8 1/8 1/8)
      position 's (start):
      (length-subdivision '(2 1/16) rhy :position 's) => (1/16 1/16 1/8 1/16 1/16 1/8 1/16 1/16 1/8 1/16 1/16 1/8)
      position 'e (end):
      (length-subdivision '(2 1/16) rhy :position 'e) => (1/8 1/16 1/16 1/8 1/16 1/16 1/8 1/16 1/16 1/8 1/16 1/16)
      type 'r (rest), position 'e (end):
      (length-subdivision '(2 1/16) rhy :type 'r :position 'e) => (-1/8 1/16 1/16 -1/8 1/16 1/16 -1/8 1/16 1/16 -1/8 1/16 1/16)
      type 'r (rest), position 's (end):
      (length-subdivision '(2 s) rhy :type 'r :position 's) => (1/16 1/16 -1/8 1/16 1/16 -1/8 1/16 1/16 -1/8 1/16 1/16 -1/8)
      type at random, rest or note :
      (length-subdivision '(2 s) rhy :type '? :position 's) => (1/16 1/16 -1/8 1/16 1/16 -1/8 1/16 1/16 -1/8 1/16 1/16 1/8)
      position and type at random:
      (length-subdivision '(1 e) rhy :type '? :position '? :seed 34) => (1/16 1/8 1/16 1/8 1/8 -1/8 1/8 1/8 1/8) (length-subdivision '((2 5q) (1 3q)) rhy :type '? :position 's :seed 34) => (1/20 1/20 3/20 1/12 -1/6 1/20 1/20 3/20 1/12 -1/6) (length-subdivision '((2 5q) (1 3q) (1 e) (1 s)) rhy :seed 34) => (1/20 1/20 3/20 1/12 1/12 1/12 1/8 1/8 3/16 1/16)  
      Example:
      (setf rhy2 '((1/4 1/4 1/4 1/4) (1/4 1/4 1/4 1/4))) (length-subdivision '(1 e) rhy2 :seed 34) => ((1/8 1/8 1/16 1/8 1/16 1/8 1/8 1/8 1/8) (1/16 1/8 1/16 1/8 1/8 1/8 1/8 1/8 1/8)) (length-subdivision '((1 e) (1 3q)) rhy2 :seed 34) => ((1/8 1/8 1/12 1/12 1/12 1/8 1/8 1/6 1/12) (1/16 1/8 1/16 1/6 1/12 1/8 1/8 1/6 1/12)) (length-subdivision '(((1 e)) ((1 3q))) rhy2 :seed 34) => ((1/8 1/8 1/16 1/8 1/16 1/8 1/8 1/8 1/8) (1/12 1/12 1/12 1/6 1/12 1/12 1/6 1/6 1/12)) (length-subdivision '((3 3q) (1 e)) '((q -e e h) (s e. q h)) :seed 65) => ((1/12 1/12 1/12 -1/8 1/8 1/12 1/12 1/12 1/4) (1/16 3/16 1/8 1/8 1/8 1/12 1/12 1/12 1/8)) (length-subdivision '(((3 3q)) ((1 e))) '((q -e e h) (s e. q h)) :seed 65) => ((1/12 1/12 1/12 -1/8 1/8 1/12 1/12 1/12 1/4) (1/16 1/16 1/8 1/16 1/8 1/16 1/8 3/8)) (length-subdivision '(((2 3q)) ((1 e))) '((q -e e h) (s e. q h)) :type '? :seed 65) => ((1/12 1/12 1/12 -1/8 1/8 1/12 1/12 -1/3) (1/16 -1/16 1/8 1/8 1/8 1/8 3/8))
      OMN:
      (setf mat1 '(q c4 d4 e4 f4 g4 a4 b4)) (length-subdivision '(1 e) mat1 :seed 45) => (s cs4 e b3 s d4 e cs4 e4 s f4 e fs4 s d4 e fs4 eb4 f4 a4 bb4 gs4 bb4 a4)
      The symbol 'r (third value) will apply repeat function:
      (length-subdivision '(1 e r) mat1 :seed 45) => (s c4 e s e d4 d4 s e4 e s e f4 f4 g4 g4 a4 a4 b4 b4)
      Here we define the intervals (third value):
      (length-subdivision '(1 e (13 0 13 0)) mat1 :seed 45) => (s cs5 e c4 s cs5 e eb5 d4 s f5 e e4 s f5 e fs5 f4 gs5 g4 bb5 a4 c6 b4) (length-subdivision '(4 s (13 0 13 0)) mat1 :seed 45) => (s cs5 c4 cs5 c4 eb5 d4 eb5 d4 f5 e4 f5 e4 fs5 f4 fs5 f4 gs5 g4 gs5 g4 bb5 a4 bb5 a4 c6 b4 c6 b4) (length-subdivision '(2 3q (13 0 13 0)) mat1 :type '(r n) :seed 45 :position '(e s s s e s s)) => (-3q cs5 c4 eb5 d4 eb5 f5 e4 - fs5 f4 fs5 - gs5 g4 bb5 a4 bb5 c6 b4 -) (setf mat2 '((e c4 p e4 mp g4 he c5 p) (q c4 f c4 cs4 mp - d5 p d5) (q cs5 mf = - - cs5 p =))) (length-subdivision '((1 e (13 0 13 0)) (2 e (13 0 13 0)) (2 3q (13 0 13 0))) mat2 :type '? :seed 34) => ((e c4 p e4 mp g4 q cs6 p e c5 q cs6) (e cs5 f c4 cs5 c4 -3q d5 mp cs4 -q e eb6 p d5 eb6 d5) (-s e cs5 mf -s e d6 cs5 -q - 3e d6 p 3q cs5 d6 3e cs5 e d6 cs5)) (length-subdivision '(((1 e (13 0 13 0))) ((2 s (13 0 13 0))) ((2 3q r))) mat2 :type '? :seed 34) => ((e c4 p e4 mp g4 q cs6 p e c5 q cs6) (e cs5 f s c4 cs5 -e s cs5 c4 e d5 mp s cs4 d5 -q -s eb6 p d5 - eb6 d5 eb6 d5) (3q cs5 mf cs5 cs5 cs5 cs5 cs5 -q - 3q cs5 p cs5 - - cs5 cs5))  
      In the example below we assign three series of values to variables s1, s2 and s3:
      (setf s1 '(2 e (6 12 18 24)) s2 '(1 3q ((13 1 13 0) (13 0 7 1) r)) s3 '(3 5q ((13 0 13 0 13) ?)) ) (length-subdivision (list s1 s2 s3) mat2 :seed 23) => ((e c4 p 3e bb4 mp 3q e5 e cs6 cs5 p cs6 q.) (e fs4 f c5 3q cs5 cs4 cs5 5h mp 5q c4 g4 c4 -q e c4 p c4 3q d5 3h cs4) (e g5 mf cs6 3q d6 3h d5 -q - 5q d6 p cs5 cs5 5h e d6 cs5))  
       
       
      length-syncopate
      The function LENGTH-SYNCOPATE is a valuable way of bringing more rhythmic interest into a length list. The usual idea of syncopating rhythm is to 'choke' certain attacks so that the attack is delayed or pre-empted.
      (setf rhy '(1/4 1/4 1/4 1/4)) (length-syncopate '(1 4) rhy) => (1/4 3/16 1/16 1/4 1/4) (length-syncopate '(2 4) rhy) => (1/16 3/16 1/4 3/16 1/16 1/4)  
      Example:
      (length-syncopate '(1 4) '(1/4 -1/8 1/16 1/16 -1/8 1/8 1/1) :seed 34) => (1/4 -1/8 1/16 1/64 3/64 -1/8 1/8 1)
      In the example above only 1 length is divided by 4 (1, 3) - that is the 1/16. In the example below 2 values are divided by 3: (1, 2) and (2, 1).
      (length-syncopate '(2 3) '(1/4 -1/8 1/16 1/16 -1/8 1/8 1/1) :seed 34) => (1/4 -1/8 1/48 1/24 1/16 -1/8 1/8 2/3 1/3) (length-syncopate '(1 4) '(1/4 -1/8 1/16 1/16 -1/8 1/8 1/1) :set 1/8 :seed 34) => (1/4 -1/8 1/16 1/16 -1/8 1/32 3/32 1)
      Example with :set for each list:
      (length-syncopate '((2 3) (1 4)) '((1/4 -1/8 1/16 1/16) (1/32 -3/32 1/8 1/1)) :set '(min 1/8) :seed 45) => ((1/4 -1/8 1/24 1/48 1/24 1/48) (1/32 -3/32 3/32 1/32 1)) (length-syncopate '((2 3) (1 5)) '((q -e s s) (s -e. q h)) :set 'max :ignore 'h :seed 65 :omn t) => ((3h 3q -e s 3s 3e) (s -e. 5q 5w h))
      OMN:
      (setf mat '(q c4 d4 e4 f4 g4 a4 b4)) (length-syncopate '(3 4) mat :seed 12) => (s b3 e. cs4 q d4 e. fs4 s d4 q f4 g4 a4 e. bb4 s c5)  
      Here we use a set of interval values:
      (length-syncopate '(3 4 ((13 0) (0 14) (1 13))) mat :seed 23) => (s cs5 e. c4 d4 s e5 q e4 f4 s gs4 e. gs5 q a4 b4) (setf mat2 '((e c4 p e4 mp g4 he c5 p) (q c4 f c4 cs4 mp - d5 p d5) (q cs5 mf = - q cs5 stacc p = =)) (length-syncopate '((1 3 (-3 6)) (2 4 (6 0)) (2 5 (11 13))) mat2 :seed 34) => ((e c4 p e4 mp 3e 3q cs5 he c5 p) (q c4 f s fs4 e. c4 q cs4 mp - e. gs5 p s d5 q) (q cs5 mf cs5 - 5w c6 stacc 5q d6 stacc q cs5 p 5q c6 5w d6 q cs5))
       
       
      polygon-rhythm
      In the next three examples below we use a list of fixed polygon sides (non-symmetrical):
      (circle-rhythm-plot (polygon-rhythm '(1 6 10) 16 1) :points 16) To rotate the polygon we change the starting point value:
      (circle-rhythm-plot (polygon-rhythm '(1 6 10) 16 2) :points 16) (circle-rhythm-plot (polygon-rhythm '(0 2 5 7 10 12 13 15 16 18 19 21 23) 24 0) :points 24 :value 1/24)  
      Best wishes,
      JP
    • By opmo
      – Update:
      SNIPPET – length snippet will display without a line staff.

      To display the length SNIPPET line staff, set the *SNIPPET-LENGTH-LINE* to T. 
      (defparameter *snippet-length-line* T "Enable or disable the length snippet line staff display.") The default is: NIL

      – Fixes:
      Bug fix found in length conversion to length-symbols function.
      Missing OM Developer documents (English version).
       
      Best wishes,
      Janusz
    • By opmo
      – Additions:
      ADD-TEXT-ATTRIBUTS – Optional attribute type: :sticky and :non-sticky

      – Fixed:
      Typo error in 'GM Instrument Set.lisp' file.
       
      Best wishes,
      Janusz
×
×
  • Create New...