Jump to content

JulioHerrlein

Members
  • Posts

    816
  • Joined

  • Last visited

Reputation Activity

  1. Thanks
    JulioHerrlein reacted to o_e in Remove Unison from Chord   
    (chord-pitch-unique chords) => (gs3gs4ds5 ab3gs4) hth!
  2. Like
    JulioHerrlein got a reaction from ydepps in Updated library of many custom Opusmodus functions   
    Thank you, Torsten !
    Enjoy !!
    Best,
    Julio
     
     
  3. Thanks
    JulioHerrlein reacted to opmo in OLD VSL Gig Files articulations   
    Naturally you can do that. You find the answer in the Def-Sound-Set Library examples, look for VSL files.

    Example:
    ;; Patches, keyswitches and controllers change events. (def-sound-set VSL-Harmonium-KS                :programs   (:group Stops           Aeoline             (:key c6  :key a0)           Bassoon-Hautbois    (:key cs6 :key a0)           Clairon-Fifre       (:key d6  :key a0)           Clarinette-Bourdon  (:key ds6 :key a0)           Flute-Coranglais    (:key e6  :key a0)           Grandjeu            (:key f6  :key a0)           Percussion          (:key fs6 :key a0)           Voix-Celeste        (:key g6  :key a0)    )      :controllers   (:group Default-Settings           Pitch               0           Velocity-XF         2           Volume              7           Pan                10           Expression         11           Reverb-Dry/Wet     14           Reverb-On/Off      15           Slot-XF            20           Start-Scaler       21           Master-Attack      22           Master-Release     23           Master-Filter      24           Delay-Scaler       25           Tuning-Scaler      26           Humanize           27           Velocity-XF-On-Off 28           Rsamp-On-Off       29           Dynamics-Scaler    30           :group Pedal           Ped                64           Sost-Ped           66           Una-Corda          67                      :group Matrix           cc1                 1              ) )  
  4. Thanks
    JulioHerrlein reacted to opmo in Opusmodus 1.3.24844   
    – 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)
     
    Sorting to highest chord note:
    (chord-progression '(g2g3 a2a4 a2a3 g2d4 g2g4 a2e4) :sort 'high) => (g2g3 a2a3 g2d4 a2e4 g2g4 a2a4)
     
     
    Examples:
    (setf omn '((q d4a4g5 fs4eb5bb5 eb4fs5d5 bb4g5a5 fs4eb5d6 bb4a5g6)             (q g4d4a4 bb4fs4eb4 a4g5d6 eb5bb5fs6 bb4a5g5 eb5d5fs5)))  

    (chord-progression omn)  

     
    (chord-progression omn :sort 'high)  

     
     
    (chord-progression omn :sort '(high low) :reverse '(nil t))
     
    Best wishes,
    Janusz
  5. Thanks
    JulioHerrlein reacted to opmo in sorting chords   
    Here it is:
    (chord-progression '(g2g3 a2a4 a2a3 g2d4 g2g4 a2e4)) => (g2g3 g2d4 g2g4 a2a3 a2e4 a2a4) (chord-progression '(g2g3 a2a4 a2a3 g2d4 g2g4 a2e4) :sort 'high) => (g2g3 a2a3 g2d4 a2e4 g2g4 a2a4)  
    The CHORD-PROGRESSION function will be part of the next release.
  6. Thanks
    JulioHerrlein reacted to opmo in Opusmodus 1.3.24828   
    – 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
  7. Thanks
    JulioHerrlein reacted to opmo in Request: make-omn   
    Implemented in 1.3.24622
  8. Thanks
    JulioHerrlein reacted to opmo in Mixing chord definition in Snippets ... (?)   
    The correct omn grammar:
    '(h g3f4b4db5 (c4 maj7))  
  9. Thanks
    JulioHerrlein reacted to AM in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    (ambitus-octaves 'c3 2 (closest-path '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8))) => (g3b3eb4 gs3cs4e4 b3g3f4 c4f3e4 d4e4f3 e4gs3a3) or you could put this two FUNCTIONS into ONE =>  (closest-path*...
    just take all the values/arguments from the basic version and add the octave-thing?
     
    greetings
    andré
  10. Thanks
    JulioHerrlein reacted to opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    What you expect it is not a closes path. As you can see the first chord in the sequence is b3eb5g3.
     
    There are two option you can use to get the result you are looking for:
     
    1. start chord
    (closest-path '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8) :start 'b4eb4g4)  
    2. ambitus-chord values
    (closest-path '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8) :ambitus-chord 11) @AM  example is another good solution.
  11. Thanks
  12. Like
    JulioHerrlein reacted to opmo in Opusmodus 1.3.24805   
    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
  13. Like
    JulioHerrlein reacted to opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    Should I change the name to CLOSEST-PATH, VOICE-LEADING or leave as it is 🙂
  14. Like
    JulioHerrlein reacted to opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    What you see above is a new revised function.
     
    Examples:
    Now the start is optional.
    (chord-closest-path '(f3d4e5 e3a3gs5)) => (f3e5d4 e5gs3a3) (chord-closest-path '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8)) => (g3b3eb5 gs3cs4e5 b3g3f5 c4f3e5 d4e5f3 e5gs3a3) (chord-closest-path '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8) :start '(c3eb4f5)) => (g5eb4b2 gs5cs3e4 b2g5f4 c3f4e5 d3e5f4 e5gs4a2) (chord-closest-path '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4)) => (c4b4e4g4 e4f4c4a4 b3f4d4a4 d4b3e4g4) (chord-closest-path '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4) :start '(c3eb4f5d6)) => (c3e6g4b5 e6f4c3a5 b2f6d4a5 d4b2e6g5)  
  15. Like
    JulioHerrlein reacted to opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    Please check:
    '(f3d4e5 e3a3gs5) (chord-closest-path '(f3d4e5) '(f3d4e5 e3a3gs5)) => (f3e5d4 e5gs3a3) '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8) (chord-closest-path '(b3eb5g3) '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8)) => (g3b3eb5 gs3cs4e5 b3g3f5 c4f3e5 d4e5f3 e5gs3a3) '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4) (chord-closest-path '(b4g4e4c4) '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4)) => (c4b4e4g4 e4f4c4a4 b3f4d4a4 d4b3e4g4) yours,
    Janusz
  16. Like
    JulioHerrlein reacted to opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    It is not hard if we look for strict result e.i. smallest total without thinking about parallel movement etc...
    Here is the result of our example (strict):
     
    (chord-closest-path '(b4g4e4c4) '(b4g4e4c4 c5a4e4f4 b4a4f4d4 b4g4e4d4)) c-c = 0
    e-e = 0
    g-f = 2
    b-a = 2
    total 4
    etc...
     
  17. Like
    JulioHerrlein reacted to opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    I always try to think of optional rules but I could add strict one as well 🙂
  18. Thanks
    JulioHerrlein got a reaction from opmo in Parsimonious Voice Leading (again): attempts to provide an algorithm   
    Dear Friends,
     
    Avner, I noticed exactly the same behaviour.
    I feel a contradiction in having two results for something called
     "the closest path", because "the closest path", in my interpretation,
     means only one solution: the one in which the sum of the semitones
     of all voice-leading moves are the less.
    It's logically impossible to have "the closest path" with two solutions.
    You cannot have the cake and eat it too...
    If the function alternate between two solutions, maybe could be the
     case that  two solutions would sum the same amount of semitonal
     moves, but the example above do not seems to be that case.
     
    After I realized it, I tried to find a way to assure a more accurate
     expression to represent that one "closest" solution.
     
    Janusz, what do you think ?
     
    All the best !!
    I love Opusmodus !!
    Thank you !
    Best,
    Julio
  19. Like
    JulioHerrlein reacted to opmo in Opusmodus 1.3.24769   
    – 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
  20. Thanks
    JulioHerrlein reacted to opmo in Saving Plots and Piano Rolls to PDF Vectorial Graphics ETC   
    To save the graph in .opmograph format, simply click on the graph and select "Save As..." form the File menu. By default the file will be saved in the "~/Opusmodus/Graphs" folder.
  21. Thanks
    JulioHerrlein reacted to opmo in Saving Plots and Piano Rolls to PDF Vectorial Graphics ETC   
    Will save the result in pdf file format in ~/Opusmodus/Graphs folder.
    (circle-rhythm-plot '(0 3 6 10 11) :points 16 :file "crp1") or
    Click the mouse on the graph-view to copy it to the clipboard (PNG format). This allow you to past the image to any other document - works with display-midi view as well.
     

  22. Thanks
    JulioHerrlein reacted to AM in Providing code examples to students   
    "My focus is on the ever-changing relationship that composers have with rules and procedures."
     
    some ideas/names...?
     
    => MOZART  https://en.wikipedia.org/wiki/Musikalisches_Würfelspiel
    => the LIGETI-analysis of BOULEZ's STRUCTURES ?
    => MESSIAEN in general: https://monoskop.org/File:Messiaen_Olivier_The_Technique_of_My_Musical_Language.pdf, or  specific "MODE DE VALEURS ET D'INTENSITÉS"
    => GOTTFRIED MICHAEL KöNIG
    => XENAKIS (the "ST"-pieces?)
    => HAUER https://de.wikipedia.org/wiki/Zwölftonspiel
     
     
     
     
  23. Like
    JulioHerrlein got a reaction from TomTolleson in Providing code examples to students   
    Dear Friends,
     
    Here 's a way to produce chords from 12 tone rows (Schoenberg opus 25 row):
    (setf op25arnie '(e4 f4 g4 cs4 fs4 ds4 gs4 d4 b4 c4 a4 as4)) (respell (gen-chord2 20 '(3 3 3 1) op25arnie)) Hope it helps a little.
     
    Best,
    Julio
     
     
    Also check this !
    And the Nigel Morgan Parametric Composition book, of course !
    More specific, to keep track of the row:
    (setf op29webernLib (expand-libraries '(library vienna webern r19))) (setf rowint (pitch-to-integer op29webernLib)) (setf pitches (gen-repeat 10 op29webernLib)) (setf lengths (span pitches (gen-repeat 10 '(s s s s -s s e -s s s -s e e -q q)))) (setf text (span pitches rowint)) (def-score Stage-1 (:key-signature 'chromatic :time-signature '(4 4) :tempo 80 :layout (treble-layout 'piano-rh)) (piano-rh :length lengths :pitch pitches :text text ;:velocity dynamics :channel 1 :sound 'gm :program 'acoustic-grand-piano) ) Best,
    Julio
  24. Like
    JulioHerrlein reacted to opmo in Opusmodus 1.3.24622   
    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:
     

     
    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)
     
    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")  

     
    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)))  

     
     
    Instrument oboe, clarinet and bassoon:
    (ps 'gm :ob (list p1)     :cl (list p3)     :bn (list p6))  

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

     
     
     
    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))  

     
     
     
    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)  

     
     
     
     
    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
  25. Thanks
    JulioHerrlein reacted to opmo in HELP needed on Jazz Lines from fragments   
    Function name: BIND-TO-INTERVAL in Opusmodus version 1.3.24622
×
×
  • Create New...

Important Information

Terms of Use Privacy Policy