Jump to content
Sign in to follow this  
opmo

Opusmodus 1.3.24844

Recommended Posts

– New function:

CHORD-PROGRESSION - sorts a sequence of chords and pitches to the lowest or highest chord note.

 

– Update:
AMBITUS function allows range smaller than 6 semitones.

– Fixed:
Quick Start - Lesson 1 - OMN


– Documentation updates.

 

 

CHORD-PROGRESSION

This function will sort a sequence of chords and pitches to the lowest or highest chord note.

 

Sorting to lowest chord note:

(chord-progression '(g2g3 a2a4 a2a3 g2d4 g2g4 a2e4))
=> (g2g3 g2d4 g2g4 a2a3 a2e4 a2a4)

8C229A3B-7A0A-4A60-9F76-7E174F8F2006.png

 

Sorting to highest chord note:

(chord-progression '(g2g3 a2a4 a2a3 g2d4 g2g4 a2e4) :sort 'high)
=> (g2g3 a2a3 g2d4 a2e4 g2g4 a2a4)

D720E44F-2DB9-4991-A10D-13B9B641C1E9.png

 

 

Examples:

(setf omn '((q d4a4g5 fs4eb5bb5 eb4fs5d5 bb4g5a5 fs4eb5d6 bb4a5g6)
            (q g4d4a4 bb4fs4eb4 a4g5d6 eb5bb5fs6 bb4a5g5 eb5d5fs5)))

 

C55A2624-602A-4AB6-ADB5-17DF01D8423C.png

(chord-progression omn)

 

750710D7-D622-4A6F-9D63-59CA94443202.png

 

(chord-progression omn :sort 'high)

 

984D68A2-4876-4626-A829-714346AD9A8A.png

 

 

(chord-progression omn :sort '(high low) :reverse '(nil t))

DE0788C8-062C-4EDE-937F-884B0BBFE945.png

 

Best wishes,

Janusz

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
      – Fixed:
      Removed AllNotesOff in Live Coding Instrument sequence-loop. 

      – Documentation updates.
       
      Finally the Live Coding Instrument is working as it should, no more notes off while waiting. 🙂

      Best wishes,
      Janusz
    • By opmo
      1.3.24805 
       
      – New functions:
       closest-path  comparative-closest-path  relative-closest-path  
      – Changes:
       CHORD-CLOSEST-PATH renamed to COMPARATIVE-CLOSEST-PATH.
       CHORD-RELATIVE-PATH renamed to RELATIVE-CLOSEST-PATH.
       A new keyword :lc (live coding) added to PS function.
       The default DEF-UNFOLD-SET set name renamed to om.
      :variant and :relative keywords removed from HARMONIC-PROGRESSION function.
       
      – Fixed:
       HARMONIC-PROGRESSION
       HARMONIC-PATH
       PITCH-VARIANT
       PITCH-ROW 
       
      – Documentation updates.
      – 'Quick Start' workspace update.
       
       
      VOICE LEADING FUNCTIONS
       
      CLOSEST-PATH
       
      The function CLOSEST-PATH returns a series of chords taking the closest path to the previous chord.
       
      (closest-path '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4))
      (closest-path '(c4e4g4 c5e5a5 e5fs5a5b5 d5f5bb5d6 g4c5d5f5))  

       
      (closest-path '(c4e4g4 c5e5a5 e5fs5a5b5 d5f5bb5d6 g4c5d5f5)               :start 'c3eb4f5d5)  
       

       
      (closest-path '(g5 cs3f3bb3gs4c5d5 fs5 a5b5eb6e6g2 cs3f3bb3gs4                 c5 d5fs5a5b5 eb6e6g2cs3 f3 bb3gs4c5 d5fs5a5                 b5eb6e6g2cs3f3 bb3 gs4c5d5fs5 a5b5 eb6e6g2cs3f3                 bb3gs4c5d5 fs5 a5b5eb6e6g2cs3 f3bb3gs4 c5                 d5fs5a5b5 eb6 e6g2cs3f3))  

       
      (closest-path '(g5 cs3f3bb3gs4c5d5 fs5 a5b5eb6e6g2 cs3f3bb3gs4                 c5 d5fs5a5b5 eb6e6g2cs3 f3 bb3gs4c5 d5fs5a5                 b5eb6e6g2cs3f3 bb3 gs4c5d5fs5 a5b5 eb6e6g2cs3f3                 bb3gs4c5d5 fs5 a5b5eb6e6g2cs3 f3bb3gs4 c5                 d5fs5a5b5 eb6 e6g2cs3f3)               :start 'c3eb4f5d6)  

       
      (closest-path '((eb3f3a3 f3a3b3 g3bb3cs4 e3g3bb3)                 (g4bb4cs5 bb4cs5e5 b4eb5f5 a4b4eb5)                 (b3eb4f4 eb4f4a4 e4fs4bb4 c4e4fs4)))  

      (closest-path '((eb3f3a3 f3a3b3 g3bb3cs4 e3g3bb3)                 (g4bb4cs5 bb4cs5e5 b4eb5f5 a4b4eb5)                 (b3eb4f4 eb4f4a4 e4fs4bb4 c4e4fs4)))               :start '(c3eb4 f5d5 eb4f5))  

       
       
       
       
      COMPARATIVE-CLOSEST-PATH
       
      The function COMPARATIVE-CLOSEST-PATH returns a series of chords taking the comparatively closest path to the previous chord, derived from randomising the pitch order of a given chord before the ‘find closest interval’ process.
       
      (comparative-closest-path '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4))
       
       
      Etc…
       
      (comparative-closest-path '(c4e4g4 c5e5a5 e5fs5a5b5 d5f5bb5d6 g4c5d5f5))  

       
      Etc…
       
       
      (comparative-closest-path '(c4e4g4 c5e5a5 e5fs5a5b5 d5f5bb5d6 g4c5d5f5)                           :start 'c3eb4f5d5)  

       
      Etc…
       
      (comparative-closest-path '(g5 cs3f3bb3gs4c5d5 fs5 a5b5eb6e6g2 cs3f3bb3gs4                             c5 d5fs5a5b5 eb6e6g2cs3 f3 bb3gs4c5 d5fs5a5                             b5eb6e6g2cs3f3 bb3 gs4c5d5fs5 a5b5 eb6e6g2cs3f3                             bb3gs4c5d5 fs5 a5b5eb6e6g2cs3 f3bb3gs4 c5                             d5fs5a5b5 eb6 e6g2cs3f3))  

       
      Etc…
       
      (comparative-closest-path '(g5 cs3f3bb3gs4c5d5 fs5 a5b5eb6e6g2 cs3f3bb3gs4                             c5 d5fs5a5b5 eb6e6g2cs3 f3 bb3gs4c5 d5fs5a5                             b5eb6e6g2cs3f3 bb3 gs4c5d5fs5 a5b5 eb6e6g2cs3f3                             bb3gs4c5d5 fs5 a5b5eb6e6g2cs3 f3bb3gs4 c5                             d5fs5a5b5 eb6 e6g2cs3f3)                           :start 'c3eb4f5d6)  

       
      Etc...
       
      (comparative-closest-path '((eb3f3a3 f3a3b3 g3bb3cs4 e3g3bb3)                             (g4bb4cs5 bb4cs5e5 b4eb5f5 a4b4eb5)                             (b3eb4f4 eb4f4a4 e4fs4bb4 c4e4fs4)))  

       
      Etc…
       
      (comparative-closest-path '((eb3f3a3 f3a3b3 g3bb3cs4 e3g3bb3)                             (g4bb4cs5 bb4cs5e5 b4eb5f5 a4b4eb5)                             (b3eb4f4 eb4f4a4 e4fs4bb4 c4e4fs4))                           :start '(c3eb4 f5d5 eb4f5))  

       
       
      Etc…
       
      With seed and 4 results:
      (gen-eval 4 '(comparative-closest-path               '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4)               :start '(c3c4c5c5)) :seed 23)  

       
       
       
       
       
      RELATIVE-CLOSEST-PATH
       
      The function RELATIVE-CLOSEST-PATH generates cartesian series of intervals form a given chord. It then selects randomly the relative closest path (transition) to the previous chord.
       
      (relative-closest-path '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4))  


       
      Etc…
       
      (relative-closest-path '(c4e4g4 c5e5a5 e5fs5a5b5 d5f5bb5d6 g4c5d5f5))  

       
      Etc…
       
      (relative-closest-path '(c4e4g4 c5e5a5 e5fs5a5b5 d5f5bb5d6 g4c5d5f5)                        :start 'c3eb4f5d5)  

       
      Etc…
       
      (relative-closest-path '(g5 cs3f3bb3gs4c5d5 fs5 a5b5eb6e6g2 cs3f3bb3gs4                          c5 d5fs5a5b5 eb6e6g2cs3 f3 bb3gs4c5 d5fs5a5                          b5eb6e6g2cs3f3 bb3 gs4c5d5fs5 a5b5 eb6e6g2cs3f3                          bb3gs4c5d5 fs5 a5b5eb6e6g2cs3 f3bb3gs4 c5                          d5fs5a5b5 eb6 e6g2cs3f3))  

       
      Etc…
       
      (relative-closest-path '(g5 cs3f3bb3gs4c5d5 fs5 a5b5eb6e6g2 cs3f3bb3gs4                          c5 d5fs5a5b5 eb6e6g2cs3 f3 bb3gs4c5 d5fs5a5                          b5eb6e6g2cs3f3 bb3 gs4c5d5fs5 a5b5 eb6e6g2cs3f3                          bb3gs4c5d5 fs5 a5b5eb6e6g2cs3 f3bb3gs4 c5                          d5fs5a5b5 eb6 e6g2cs3f3)                        :start 'c3eb4f5d6)  

       
      Etc…
       
      (relative-closest-path '((eb3f3a3 f3a3b3 g3bb3cs4 e3g3bb3)                          (g4bb4cs5 bb4cs5e5 b4eb5f5 a4b4eb5)                          (b3eb4f4 eb4f4a4 e4fs4bb4 c4e4fs4)))  

       
      Etc…
       
      (relative-closest-path '((eb3f3a3 f3a3b3 g3bb3cs4 e3g3bb3)                          (g4bb4cs5 bb4cs5e5 b4eb5f5 a4b4eb5)                          (b3eb4f4 eb4f4a4 e4fs4bb4 c4e4fs4))                        :start '(c3eb4 f5d5 eb4f5))  

       
      Etc…
       
      (gen-eval 4 '(relative-closest-path               '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4)) :seed 542) => ((c4e4g4b4 c4e4f4a4 a3b3d4f4 d4e4g4b4)     (c4e4g4b4 e4f4a4c5 d4f4a4b4 b3e4g4d5)     (g3e4b4c5 e3f4a4c5 d3a4b4f5 d3g4b4e5)     (g3e4b4c5 a3f4c5e5 f3a4b4d5 d3e4g4b4))  

       
       
       
       
      Live Coding option in PS function

      The :play :lc (live coding) option allows you to send the result of a PS function to ‘Live Coding Instrument’ in a live coding performance.
       
      (progn   (setf    mat '((-w.)          (h. eb4 pp q g3 -e q gs4 mf -s a5 p tie)          (e. a5 -e q bb4 mf -s q cs5 p -s q. e5 mf -e.)          (q cs5 p h. d5 mf -q c5 pp tie)          (h c5 pp h. gs3 -e a4 p<)          (h. fs5 mp q bb3 c5 p e4 mf tie)          (h e4 -e q cs4 mp h d5 p e f4)          (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 p< leg eb4 < leg g4 f 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)))      (setf    v1 (filter-density '(0.7 0.1 0.2 0.0 0.2 0.3 0.3) mat :type :length)    v2 (filter-density '(0.0 0.2 0.0 0.2 0.2 0.4 0.3) mat :type :length)    v3 (filter-density '(0.2 0.7 0.2 0.2 0.2 0.3 0.2) mat :type :length)    v4 (filter-density '(0.0 0.2 0.2 0.7 0.2 0.2 0.7) mat :type :length))      (setf    vn1 (unfold 'om '(t7 dyn bti vn) v1)    vn2 (unfold 'om '(t7 v? dyn bti vn) v2)    vla (unfold 'om '(v? ra dyn bti va) v3)    vlc (unfold 'om '(t-12 t-5 v? a-12-12 dyn bti vc) v4))      (ps 'gm :sq (list vn1 vn2 vla vlc) :tempo 68 :play :lc)   )  
       
       
      QUICK START WORKSPACE

      To update your 'Quick Start' workspace to the latest version you need to delete the 'Quick Start' folder from the Opusmodus directory first.
      After the deletion go to the Opusmodus menu 'Help' and select 'Install Quick Start Workspace'.
      To open the new 'Quick Start' workspace file simply select 'Open Quick Start Workspace' form the 'Help' menu.
       
      That's all for now,
      best wishes,
      Janusz
    • By opmo
      – New functions: 
      get-sieve-tree sieve-merge sieve-tree-series sieve-tree sieve pick-prob gen-prob create-osc-thread get-osc-thread-from-name send-osc-data osc-thread-alive? end-all-osc-threads end-osc-thread – Howto Score/OSC/OSC Threads.opmo
      – Changes to OSC functions, please check the new OSC documents if you use OSC.
      – Musicxml display improvements.

       
      SIEVE-TREE
      This function returns a sequence of lengths symbols derived from tree-data in a given root, node and level number.
       
      Examples:
      Low density output:
      (sieve-tree 32 2 3)
       
      With a smaller root number and a higher level number we increase the density:
      (sieve-tree 8 2 5)
       
      In the following example we add probability values using lists of paired values to node, level and rest parameters. The first value in the rest lists is a percentage value of the length-rests in a node-level list.
      (sieve-tree '(4 2)             '((2 0.43) (3 0.37))             '((3 0.47) (4 0.56) (5 0.68))             :rest '((20 0.43) (80 0.6) (0 0.7))             :quantize '(1 2 3 4 5 7))  

       
      Here we are increasing the length-rest probability and set the quantize to quarter, eight and quintuplet only:
      (sieve-tree '(4 2)             '((2 0.43) (3 0.37))             '((3 0.47) (4 0.56) (5 0.68))             :rest '((20 0.43) (80 0.6) (90 0.7))             :quantize '(1 2 5))  

       
      The expression below will generate 96 bars of gradual increase in the density:
      (sieve-tree 96 2 7 :seed 43)  
      Let's examine the original tree-data from the expression above. To do that we call the GET-SIEVE-TREE function with the same tree values:
      (get-sieve-tree 96 2 7)  
       
      SIEVE-TREE-SERIES
      SIEVE-TREE-SERIES returns a sequence of lengths symbols derived from a series of tree-data in a given root, node and level number. This function allows you to control individual tree-data parameters ie. density results. Please note, every parameter has a keyword, except the root number.
       
      Examples:
      (sieve-tree-series '((8 :node 2 :level ((3 0.47) (4 0.56) (5 0.68))                         :rest ((40 0.43) (80 0.6) (0 0.7))                         :quantize (1 2 4))                      (3 :node 2 :level ((3 0.47) (4 0.56) (5 0.68))                         :quantize (1 2 3 5 6))                      (2 :node 3 :level ((4 0.46) (5 0.58)) :seed 23)))
       
      (sieve-tree-series '((2 :node 2 :level ((4 0.47) (5 0.66))                         :rest ((40 0.43) (80 0.6) (0 0.7)))                      (8 :node 2 :level ((3 0.47) (4 0.56))                         :quantize (1 2 3 5 6))                      (3 :node 3 :level ((4 0.46) (5 0.58))                         :rest ((40 0.43) (80 0.6) (0 0.7)))))
       
       
      GET-SIEVE-TREE
      GET-SIEVE-TREE returns a tree node degree data from a given root, node and level number.  This function is useful for analysis of the original tree-data used in the SIEVE-TREE function.
       
      Examples:
      (get-sieve-tree 96 2 1) => ((48 48)) (get-sieve-tree 96 3 1) => ((32 32 32)) (get-sieve-tree 96 2 2) => (((24 24) (16 16 16))) (get-sieve-tree 96 3 2) => (((32) (16 16) (32/3 32/3 32/3))) (get-sieve-tree 96 2 3) => (((12 12) (8 8 8)) ((16) (8 8) (16/3 16/3 16/3))) (get-sieve-tree 96 3 3) => (((16 16)) ((8 8) (16/3 16/3 16/3)) ((32/3) (16/3 16/3) (32/9 32/9 32/9))) (get-sieve-tree 96 2 5) => (((3 3) (2 2 2)) ((4) (2 2) (4/3 4/3 4/3)) ((4 4)) ((2 2) (4/3 4/3 4/3))     ((8/3) (4/3 4/3) (8/9 8/9 8/9)) ((4 4) (8/3 8/3 8/3)) ((2 2) (4/3 4/3 4/3))     ((8/3) (4/3 4/3) (8/9 8/9 8/9)) ((8/3 8/3)) ((4/3 4/3) (8/9 8/9 8/9))     ((16/9) (8/9 8/9) (16/27 16/27 16/27)))  
      SIEVE-TREE example with root 8, node 2 and level 5:
      (sieve-tree 8 2 5)
       
      Analysis of the above tree-data:
      (get-sieve-tree 8 2 5) => (((1/4 1/4) (1/6 1/6 1/6)) ((1/3) (1/6 1/6) (1/9 1/9 1/9)) ((1/3 1/3))     ((1/6 1/6) (1/9 1/9 1/9)) ((2/9) (1/9 1/9) (2/27 2/27 2/27))     ((1/3 1/3) (2/9 2/9 2/9)) ((1/6 1/6) (1/9 1/9 1/9))     ((2/9) (1/9 1/9) (2/27 2/27 2/27)) ((2/9 2/9)) ((1/9 1/9) (2/27 2/27 2/27))     ((4/27) (2/27 2/27) (4/81 4/81 4/81)))  
       
      SIEVE
      SIEVE returns a list of numbers to a given modulus, shift and maximum number. This function can be useful in generating root numbers for the SIEVE-TREE function.
      (sieve 4 0 96) => (0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96)  
      Examples:
      (sieve 2 0 60) => (0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32     34 36 38 40 42 44 46 48 50 52 54 56 58 60) (sieve 2 1 60) => (1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33     35 37 39 41 43 45 47 49 51 53 55 57 59)  
      Example with SIEVE-TREE function:
      (sieve-tree (sieve 3 4 14)             '((2 0.43) (3 0.37))             '((3 0.47) (4 0.56) (5 0.68))             :rest '((20 0.43) (80 0.6) (90 0.7)))
       
       
      SIEVE-MERGE
      SIEVE-MERGE returns a list of numbers derived from merging a number of sieve lists. This function can be useful in generating root numbers for the SIEVE-TREE function.
       
      Examples:
      Here we merge two sieve lists, one from (sieve 3 0 96) and one from (sieve 4 0 96):
      (sieve-merge '(3 0 4 0) 96) => (0 3 4 6 8 9 12 15 16 18 20 21 24 27 28 30 32 33 36 39 40 42 44 45 48 51     52 54 56 57 60 63 64 66 68 69 72 75 76 78 80 81 84 87 88 90 92 93 96)  
      Example with SIEVE-TREE and SIEVE-MERGE function:
      (sieve-tree (sieve-merge '(3 2 4 2) 12)             '((2 0.43) (3 0.37))             '((3 0.47) (4 0.56) (5 0.68))             :quantize '(1 2 4 8))
       
       
      PLEASE NOTE!
      The changes to OSC implementation - see below - are thanks to Rangarajan Krishnamoorthy.
      If you use OSC threads please revise your OSC files and make the necessary adjustments.
       
      The CREATE-OSC-THREAD function creates the OSC thread with a given target.
      Here we assign a name Reaktor to a remote-host: 127.0.0.1 and remote-port: 10000:
      (defparameter reaktor '(127.0.0.1 10000)) Here we assign an variable to our OSC thread object, this is important for sending the data with the thread and for ending the thread:
      (setf thd1 (create-osc-thread "thread1" reaktor)) To send OSC messages with the thread we call the SEND-OSC-DATA function:
      (send-osc-data thd1 '((0.0 1/2) (0.0 1/2) (0.08238555 2)                       (0.10876829 1) (0.12127061 11/2))) To end the OSC thread and the sending of the OSC messages, we call the END-OSC-THREAD function:
      (end-osc-thread thd1)  
      The SEND-OSC-THREAD function sends OSC data and performs a small amount of "background" processing on messages in the queue when the processor would otherwise be idle. This function can be called on a created thread any number of times during its lifetime.
      (defparameter reaktor '(127.0.0.1 10000)) (defparameter time (rnd-sample 50 '(1/4 1/2 1/4))) (defparameter values (vector-smooth 0.05 (gen-white-noise 500))) (defparameter data (gen-osc-data 60 values :time time)) (setf thd1 (create-osc-thread "thread1" reaktor)) (send-osc-data thd1 data)  
      The GET-OSC-THREAD-FROM-NAME function returns the OSC thread from a given name. This function is useful if you don’t assign  a variable to the thread object.
       
      Note we are not capturing the thread object returned from this function:
      (create-osc-thread "thread1" reaktor) We can get the thread object using its name when we want:
      (send-osc-data (get-osc-thread-from-name "thread1")                '((0.0 1/2) (0.3254655 1/2) (0.08238555 2)                  (0.10876829 1) (0.12127061 11/2))) (end-osc-thread (get-osc-thread-from-name "thread1")) The OSC-THREAD-ALIVE? function checks if the given OSC thread object is still alive and returns T if true.
      (setf thd1 (create-osc-thread "thread1" '(127.0.0.1 10000))) (end-osc-thread thd1) => nil Test:
      (osc-thread-alive? thd1) => nil  
      The END-OSC-THREAD function will end and destroy a given OSC thread. After the thread is destroyed, you cannot send any messages to it.
      (setf thd1 (create-osc-thread "thread1" '(127.0.0.1 10000))) (end-osc-thread thd1) => nil Test:
      (osc-thread-alive? thd1) => nil The END-ALL-OSC-THREADS function will end and destroy all OSC threads. You cannot send any messages to the threads once they are destroyed.
      (defparameter reaktor '(127.0.0.1 10000)) (create-osc-thread "thread1" reaktor) (create-osc-thread "thread2" reaktor) (create-osc-thread "thread3" reaktor) (create-osc-thread "thread4" reaktor) (end-all-osc-threads) => nil Best wishes,
      Janusz
×
×
  • Create New...