Jump to content

torstenanders

Members
  • Posts

    497
  • Joined

  • Last visited

Posts posted by torstenanders

  1. It is handy that Opusmodus can display multiple score snippets and full scores alongside each other.

     

    Is there perhaps also a way to re-play some snippet still shown? Either with some GUI element that I may have missed or programmatically (they all have a unique name shown, like "UNTITLED 101 (Snippet)").? There is a function audition-musicxml-last-score, is there perhaps a function to again audition a score that is specified by its name? 

     

    Thanks! 

     

    Best,

    Torsten

  2. Dear Achim,

     

    From your error message at the end (There is no package named "PW" ) it looks like you did not follow the installation instructions, which you can find at https://github.com/tanders/cluster-engine  In a nutshell, you should load it with ASDF and for that put it at a location where ASDF can find it. Instead, when you are putting it into ~/Opusmodus/Extensions/ then files are loaded in a wrong order.  

     

    Best,

    Torsten

     

  3. I just got a copy of EW ComposerCloud and had a look at this. Wow -- this setup is a true monster, and way too much for my poor mere 8GB laptop (with unfortunately no way to extend the memory). I can confirm that in principle your setup works on my computer (Opusmodus can control sound playback of the instruments), but even when I reduce the bidule-file to only the string section, my machine has difficulties handling it. Sigh. 

     

    How much memory are you using? 

     

    I wish Play would have a purge feature similar to Kontakt, where you can basically start with an empty patch, and all samples needed are by and by loaded. (Play has some purge functionality, but it is more limited, only useful when the score is already fixed, which is not terribly useful in an environment like Opumodus). (I would probably need a second computer and something like Vienna Ensemble Pro to handle a full orchestra, in particular as I would be interested in using multiple articulations...)

     

    In your setup, you are running a separate Play instance for each instrument, and then you load several articulations per instrument into that Play instance, each on a different MIDI channel. I don't quite understand how this should work, as each instrument is controlled by only a single MIDI channel.  

     

    Best,

    Torsten

  4. I assume internally of tonality-map there is a comparison of pitch classes (modulus 12 of pitches) deduced from the input "raw" music with the input pitch classes of the underlying harmony/spectra (called tonalities here). All that would be needed technically is to instead allow for a comparison among pitches or MIDI note numbers instead (i.e. skipping the modulus 12 calculation). This behaviour could be the default or controlled with a keyword argument to tonality-map.

     

    Best,

    Torsten

     

  5. Simply slightly edit the algorithms below by inserting some additional output. Below I simply took one of the algorithms you linked and added a single print statement. If instead you want to collect all the results, then just accumulate them in some variable with a scope surrounding your algorithm function.

    (defun bubble-sort/naive (sequence)
      (let ((end (length sequence)))
        (labels ((compare-and-swap (index modified)
                   ;; print intermediate results
                   (print sequence)
                   (if (= index (1- end))
                       (if modified (compare-and-swap 0 nil) (values))
                       (let ((index+1 (1+ index)))
                         (if (> (elt sequence index) (elt sequence index+1))
                             (let ((x (elt sequence index)))
                               (setf (elt sequence index) (elt sequence index+1)
                                     (elt sequence index+1) x)
                               (compare-and-swap index+1 t))
                             (compare-and-swap index+1 modified))))))
          (unless (< end 2)
            (compare-and-swap 0 nil))
          sequence)))
    
    (bubble-sort/naive '(3 1 9 5 3 6 4 2 3 7))


    Best,

    Torsten

  6. I like how the function tonality-map allows specifying some input harmony (called tonality) and raw music, where the "raw" music is then quasi-quantised into the given harmony. 

     

    However, I would like to control in which octaves specific tones are allowed to occur. tonality-map allows specifying an underlying harmony that ranges over multiple octaves, but it seems that internally only octave-less pitch classes are used, and any tone in the harmony can occur in any octave in the result. By contrast, in the spectral tradition of music thinking, you change the underlying spectrum if you scramble in which octaves pitches occur. For example, if you have a spectrum or chord that approximates the overtone series, then that spectrum sounds rather consonant, regardless how far up in the overtone series you allow tones to be included. However, if you then randomly octave-transpose the pitches of this spectrum/chord, then it can become much more dissonant, without changing any pitch classes.

     

    To be more specific here is a dummy example with simple traditional chords where tones are distributed across octaves in a certain way. 

     

    (tonality-map 
     ;; underlying harmony or spectra
     '((c4g4e5b5d6) (g3d4b5f5a4))
     ;; input music
     '((h c4f5 cs4fs5) (d4g5 cs4gs5) (eb4as5 f4a5) (e4gs5 c4gs5))
     ;; harmonic rhythm
     :time '(w w w_w))
    => ((h c4e5 c4g5) (h a3d5 g3d5) (h e4b5 e4b5) (h e4g5 c4g5))

     

    As you can see, the tone G in the first tonality occurs only in octave 4, but in the result, in the second chord of the first bar (still following the first tonality) we have a g5 instead. Now, you might feel that the g5 does not musically do any harm, but in the second tonality, there is an A only in octave 6, while in the function output in the related third chord the A occurs three octaves lower in octave 3, where it greatly increases the dissonance degree of this chord/scale. 

     

    So, is there a way to restrict the octaves of tones in the result to be restricted to the octaves of these tones in the respective tonalities? Alternatively, is there another function that complements tonality-map, where I can force some "raw" music to follow some underlying harmony with a given harmonic rhythm, and where the octaves of the resulting pitches can be restricted?

     

    Thank you! 

     

    Best,

    Torsten

  7. Citing the documentation: "INIT-SEED can be used at the start of algorithmic compositions employing high degrees of randomness in order to create consisted results, without having to worry about supplying seed N values to all the other functions which may also use random generation."

     

    The function init-seed does not give you any new value actually (it just returns its argument), but in the background as a side-effect initialises the random generation of all Opusmodus random functions, so that their results are consistent on re-evaluation. 

     

    Just try removing it in your function :)

     

    Besides, programs that reduce any changes to global states and side effects to the absolute minimum (which is most often using no stateful programming at all) are more easy to maintain and expand. Your little function introduces two stateful operations that are not needed here: setf (better use a local let) and init-seed. (This is even more important when writing concurrent code, which can be necessary when doing real-time stuff, e.g., when you have multiple processes running in parallel changing the same global variables without further precaution.)   

     

    Best,

    Torsten

  8. On 3/31/2018 at 7:40 PM, lviklund said:
    
    (defun doseed (&key seed)
            (setf seed (init-seed (rnd-range 1 999999)))
            (print seed))
    
    
    (rnd-sample 5 '(c4 e4 g4 b4) :seed (doseed))

    This works for me.

     

    /Lasse

     

    Below is a more secure variant of that function, which does not overwrite the seeds of all other functions. Calling init-seed is not needed here... 

     

    I avoided using do in the function name, as functions/macros named such are by convention looping constructs. 

     

    Best,

    Torsten

     

    (defun mk-seed (&optional seed)
      "Generates a random seed value, prints and returns it. Useful for exploring different results of random processes, but then keeping a found solution.
    
      Args:
      - seed (int): optionally fixes generated seed.
    
      Examples:
    
      (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed))
      ; 405621 rnd-sample
      => (c4 e4 d4) 
    
      (rnd-sample 3 '(c4 d4 e4) :seed (mk-seed 13))
      ; 13 rnd-sample
      => (e4 d4 e4) 
      "
      (print (if seed seed (rnd-range 1 999999))))

     

  9. > Perhaps if possible also with the variable name as a label to keep track of things when using several random functions in complex code:

    (setf bin-rhythm (gen-binary-rnd 5 5 2 1))
    => bin-rhytm gen-binary-rnd :seed 37
    

    This should be easy to do with a revision of the macro do-verbose, but as users, we have no access to its definition to change it. (The macro would check the value of the variable seed in its environment.)

    Side remark: If anyone revises do-verbose, it would be highly welcome to be able to switch off its effect altogether, because Common Lisp offers much better builtin debugging facilities than what this macro does. 

     

    Anyway, here is an easy workaround for your particular situation. 

     

    (setf bin-rhythm (gen-binary-rnd 5 5 2 1 :seed (print 123)))
    ; printed: 123 gen-binary-rnd
    => ((0 0 1 0 0) (1 0 1 0 1) (0 1 1 0 1) (1 1 0 1 1) (0 1 0 1 1))


    See also the discussion in the thread linked below.

     

    Best,

    Torsten

     

     

  10. Wow, that is fancy :)

     

    Here is one that is even slightly more fancy, where the resulting softer velocity values also react to the velocity input, and also the pitch of easy beats is slightly different.   

     

    (defun metronome (sequence &key (pitch 'c4) (velocity 90))
      (let* ((ts (get-time-signature sequence))
             (len (loop for i in ts
                    collect (gen-repeat (car i) (list (/ 1 (second i))))))
             (vel (loop for i in ts
                    collect (append (get-velocity (list velocity) :type :symbol)
                                    (gen-repeat (1- (car i)) 
                                                (get-velocity (list (- velocity 25))
                                                              :type :symbol)))))
             (pitch (loop for i in ts
                      collect (cons pitch
                                    (pitch-transpose 
                                     -2 (gen-repeat (1- (car i)) pitch))))))
        (make-omn :length len
                  :pitch pitch
                  :velocity vel)))

     

    TA

  11. > If you open a midi-file created with Opusmodus with Logic, all the tracks will be created, the tempo map, the bar changes and logic will load instruments exactly as you describe.

     

    Yes, indeed. The only thing missing from Jor's list would be proper automation data, AFAIK. You can have CC data, but Logic automation data is a different animal. 

     

    Best,

    Torsten

  12. I see -- they need to be declared in in the :controllers section. Thanks a lot! 

     

    I now got it almost working. Below is my current sound set again. I had to simplify the combination symbols to I1, I2 etc (the former underscore was confusing the OMN parser).


    What is missing still is support for combining articulations like II+II2 (i.e., use division II with combination 2 of that division). I can have combinations like stacc+II or leg+II2, but II+II2 is only notated, the playback does not work.

     

    Here are two examples. The first one works fine, but is not actually what I need.

     

    '((q c4 stacc+II) (e c4 leg d4 stacc e4 II4+leg f4 stacc) (q g4 marc -q -h))

     

    The second example demonstrates the problem.

     

     '((q c4 II+II2) (e c4 leg d4 stacc e4 II4+leg f4 stacc) (q g4 marc -q -h))

     

    Specifically, whether I notate II+II2 or II2+II, II is executed, but II2 is not. The later II4+leg again triggers the combination 4 fine. 

     

    I had a look at a resulting exported MIDI file, and indeed in the combination II+II2 the CC message for II is output, but the program change message for II2 is not. If II2 or one of its friends is used independently or in a combination like stacc+II2 it does work, though.

     

    Is there perhaps some bug in the sound set definition here that only kicks in when user-defined articulations are combined? 

     

    Thanks again! 

     

    Best,

    Torsten

     

    PS: I only define support for predefined combinations of stops instead of stops directly for multiple reasons. This is more easy to define (less symbols overall), and is independent of specific organs or chosen stop combinations -- I can change the registration (combinations of stops used at certain moments) and even the organ without changing the score (generation). 

     

     

    (add-text-attributes

     ;; Setting divisions and couplings
     ;; Note: I don't notate couplers with plus (e.g., I + II), but instead simply I and II 
     ;; (Notation revised manually later in Sibelius)
     '(G_C "G.C.")
     '(Ped "Ped")
     '(I "I") 
     '(II "II")
     '(III "III")
     '(-Ped "- Ped")
     '(-I "- I") 
     '(-II "- II")
     '(-III "- III")

     ;; divisional combinations for the organ
     ;; 
     ;; Pedal
     '(P1 "P: 1")
     '(P2 "P: 2")
     '(P3 "P: 2")
     '(P4 "P: 4")
     '(P5 "P: 5")
     '(P6 "P: 6")
     '(P7 "P: 7")
     '(P8 "P: 8")
     '(P9 "P: 9")
     '(P10 "P: 10")
     ;;
     ;; I
     '(I1 "I: 1")
     '(I2 "I: 2")
     '(I3 "I: 2")
     '(I4 "I: 4")
     '(I5 "I: 5")
     '(I6 "I: 6")
     '(I7 "I: 7")
     '(I8 "I: 8")
     '(I9 "I: 9")
     '(I10 "I: 10")
     ;;
     ;; II
     '(II1 "II: 1")
     '(II2 "II: 2")
     '(II3 "II: 2")
     '(II4 "II: 4")
     '(II5 "II: 5")
     '(II6 "II: 6")
     '(II7 "II: 7")
     '(II8 "II: 8")
     '(II9 "II: 9")
     '(II10 "II: 10")
     ;;
     ;; III
     '(III1 "III: 1")
     '(III2 "III: 2")
     '(III3 "III: 2")
     '(III4 "III: 4")
     '(III5 "III: 5")
     '(III6 "III: 6")
     '(III7 "III: 7")
     '(III8 "III: 8")
     '(III9 "III: 9")
     '(III10 "III: 10")

     )


    ;;; TODO: uncomment when errors like "there is no controller named: cc20" are fixed
    (def-sound-set GrandOrgue-organ
      :programs
      (:group couplers           
              Ped (cc20 127)
              -Ped (cc20 1)
              I (cc21 127)
              -I (cc21 1)
              II (cc22 127)
              -II (cc22 1)
              III (cc23 127)
              -III (cc23 1)
              G_C (cc30 127)

       ;; sends program change messages to switch combinations for a certain division 
       :group combinations 
              P1 1
              P2 2
              P3 3
              P4 4
          P5 5
              P6 6
              P7 7
              P8 8
              P9 9
          P10 10

              I1 21
              I2 22
              I3 23
              I4 24
          I5 25
              I6 26
              I7 27
              I8 28
              I9 29
          I10 30          
              II1 41
              II2 42
              II3 43
              II4 44
          II5 45
              II6 46
              II7 47
              II8 48
              II9 49
          II10 50

              III1 61
              III2 62
              III3 63
              III4 64
          III5 65
              III6 66
              III7 67
              III8 68
              III9 69
          III10 70
          )
              
     :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
              Pedal                  64  ; not 'Ped'
              Sustain                64
              Sost-Ped               66
              Sostenuto              66
              Una-Corda              67
              Soft-Pedal             67
          
              :group Matrix
              cc1 1
              cc20 20
              cc21 21
              cc22 22
              cc23 23
              cc30 30
      ))

  13. I would like to define a new sound set to control a particular setting of the virtual organ GrandOrgue (https://sourceforge.net/projects/ourorgan/), a very nice and flexible pipe organ simulator. After investing quite some amount of time I now got some setting that allows me to nicely control GrandOrgue from Sibelius, and I would like to reproduce that control in Opusmodus. For that, I need to send certain CC messages and program change messages depending on articulations in the score. For example, I use articulations like 'I', to set the current staff to the organ division I (usually main) or 'II" for the division II (swell).

     

    Now, I might be simply missing something obvious here (e.g., a typo), but I keep getting error messages like the following when evaluating my sound set below this message, but I cannot find out what I am doing wrong. 

     

    > Error: In sound set grandorgue-organ, program ped, there is no controller named: cc20

     

    Can anyone perhaps see what I am missing here? Thanks a lot! 

     

    Best,

    Torsten

     

    (def-sound-set GrandOrgue-organ
      :programs
      (:group couplers           
              Ped (cc20 127)
              -Ped (cc20 1)
              I (cc21 127)
              -I (cc21 1)
              II (cc22 127)
              -II (cc22 1)
              III (cc23 127)
              -III (cc23 1)
              G_C (cc30 127)
    
       ;; sends program change messages to switch combinations for a certain division 
       :group combinations 
              P_1 1
              P_2 2
              P_3 3
              P_4 4
              P_5 5
              P_6 6
              P_7 7
              P_8 8
              P_9 9
              P_10 10
    
              I_1 21
              I_2 22
              I_3 23
              I_4 24
              I_5 25
              I_6 26
              I_7 27
              I_8 28
              I_9 29
              I_10 30
              
              II_1 41
              II_2 42
              II_3 43
              II_4 44
              II_5 45
              II_6 46
              II_7 47
              II_8 48
              II_9 49
              II_10 50
    
              III_1 61
              III_2 62
              III_3 63
              III_4 64
              III_5 65
              III_6 66
              III_7 67
              III_8 68
              III_9 69
              III_10 70
          )
              
     :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
              Pedal                  64  ; not 'Ped'
              Sustain                64
              Sost-Ped               66
              Sostenuto              66
              Una-Corda              67
              Soft-Pedal             67
          
              :group Matrix
              cc1 1
              
      ))

     

  14. It would be useful for playback, if certain articulations would affect the sounding note durations and velocity values. With some articulations this already seems to be the case (e.g., stacc seems to reduce note durations by 50%), while other articulations are ignored during playback in that regard (e.g., leg is notated, but makes seemingly no difference in playback -- notes played legato are not overlapping, as would be expected, nor are non-legato notes very slightly separated). Other articulations are seemingly even wrongly set (e.g., marc is an accent, but it instead shortens the note).

     

    Here is a little example demonstrating the problem, which results in the attached MIDI file.

    EDIT: The upload failed, but you can easily listening to this or export it to MIDI yourself.

     

    '((e c4 leg d4 e4 leg f4) (q g4 marc -q -h))

     

    Can users somewhere set/correct these playback settings?

     

    BTW: Ideally settings would allow for code (functions) evaluationed on the fly. That would allow, e.g., to add custom humanisation, e.g., to slightly vary the length of staccato articuations, or the velocity values set by non-legato notes.... 

     

    Thanks!

     

    Best,

    Torsten

  15. You already know how to translate a MIDI pitch number into a representation consisting of two pieces of information, a pitch class integer and an octave integer. The conversion can be applied in both directions.

     

    Now, you can apply a similar conversion to a pitch class integers, converting them into a scale degree (integer) and an accidental (another integer), depending on a scale (a set of pitch classes). Again, this conversion can be done in both ways (there are multiple solutions if you allow for enharmonic equivalence).

     

    Once you have such a representation, you can then do diatonic transpositions (depending on whatever scale) within the scale degree domain, and finally translate your  results back into pitch classes, or MIDI pitch numbers.

     

    I have a draft of a paper discussing this formally. A preliminary version of this paper has been published at SMC, http://uobrep.openrepository.com/uobrep/handle/10547/622264 Don't get scared away by the constraint programming aspect. Such conversions can also be implemented as plain deterministic functions.

     

    This can be seen as a kind of mapping, if you want, if you also see the relation between MIDI pitch numbers and pitch classes as a mapping :)

     

    Best,

    Torsten

     

  16. You can roll such a function easily yourself. The modulus function is part of Common Lisp.

     

    ;; modulus 12 of 60

    (mod 60 12)

    ; => 0

     

    (defun mod12 (xs)
      (loop for x in xs
        collect (mod x 12)))

     

    (mod12 '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 24 48))
    ; => (0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 0 0)

     

    To empower yourself, once you know how to program a simple function, you simply need to google for the modulus function

     

      http://lmgtfy.com/?q=common lisp modulo

     

    :)

     

    Best,

    Torsten

×
×
  • Create New...

Important Information

Terms of Use Privacy Policy