Jump to content


  • Content count

  • Joined

  • Last visited

  • Days Won


torstenanders last won the day on December 1

torstenanders had the most liked content!

1 Follower

About torstenanders

  • Rank
    Advanced Member

Contact Methods

  • Website URL
  • Skype

Profile Information

  • Gender

Recent Profile Visitors

1,303 profile views
  1. tutorial guide

  2. tutorial guide

    That link says for me "The page you requested does not exist". Am I missing something? Thanks!
  3. Group orchestration / instrumentation example

    Just helping others to read this code: the key data here are the variables after the comment ;; Group orchestration. Each variable grp1, grp2, etc. set for each part in a single bar whether that part should play in the end or not. The order of those groups (bars specifying which voice is playing) is then randomised. Best, Torsten
  4. Translating MIDI velocities into OMN velocities

    Ah, great! The documentation does not mention that the input can also be MIDI velocity integers, so I missed that. Best, Torsten added 2 minutes later BTW: I needed that to translate values from OpenMusic data objects into Opusmodus. I am currently working on a library that will bring OpenMusic functions/methods to Opusmodus... Best, Torsten
  5. I want to translate individual MIDI velocity integers into Opusmodus velocities (i.e. dynamics symbols like p and f). I am aware that I can do this with vector-to-velocity, but I am surprised that this transformation is seemingly so difficult. Below is a function that can do that, but perhaps Opusmodus itself should make this more simple. (defun MIDI-velocity->OMN-velocity (velocity) "Translates individual MIDI velocity integers into Opusmodus velocity symbols. Example: (MIDI-velocity->OMN-velocity 100) => fff" (let ((scaled-velo (/ velocity 127.0))) ; scale into range 0-1 (second (vector-to-velocity 0.0 1.0 `(1.0 ,scaled-velo 0))))) Best, Torsten
  6. Randomly created data can be recreated if you fix a seed. It is very handy that Opusmodus supports setting a seed for all its randomised functions (in contrast to pretty much all other composition systems). You can initialise the seed with init-seed. See also This feature probably makes it unnecessary for you to save/read files. If you still want to write to and read from text files, the Common Lisp macro with-open-file is your friend. For more details see the following links Textbook http://www.gigamonkeys.com/book/files-and-file-io.html Cookbook with examples http://cl-cookbook.sourceforge.net/files.html Language reference http://clhs.lisp.se/Body/m_w_open.htm Best, Torsten
  7. Crazy behavior

    > Maybe a good idea would be some kind of FLUSH function that cleans the environment, > so we don't need to close and reopen the program ;) Setting (and overwriting!) "global variables" with setf results in side effects, which can be difficult to control. Because of that, experienced Lisp programmers use side effects like overwriting "global variables" only rarely and when really necessary, and instead work with constants and "local variables". For quick hacking or testing using setf is very convenient and should not be dismissed, but if you are looking for a way to avoid restarting to create a clean slate then use "local variables". Best, Torsten In Lisp parlance, these are dynamic and lexical variables, not quite the same thing as local and global variables in other languages, but perhaps these terms are more easy to understand :)
  8. Constructing and deconstructing scores

    So, I understand that using OMN-PLIST is the way to go for transforming OMN expressions by a deconstruction-transformation-construction-function, once that is finalised. Thanks! Best, Torsten
  9. Argument Question (simple problem)

    You can define local variables within and outside functions with let. In principle, you can also use setf within a function, but then you are overwriting the value of a global variable. In most cases you want to avoid that. Functions that do not change anything outside them (so called side effects) are much safer. Both let and setf are explained in detail in the very informative online textbook Practical Common Lisp, chapter 6: http://www.gigamonkeys.com/book/variables.html. There you will also learn that Lisp actually distinguishes between lexical and dynamic variables; I was talking here about local and global variables instead for simplicity. In case this chapter covers something you don't follow, just go back a chapter or two and you will learn a lot :) Simple example: (defun my-function (x) (let ((y (+ x 1))) y)) (my-function 42) ; => 43 Best, Torsten
  10. The functions omn and make-omn are powerful tools to construct and deconstruct scores of multiple parameters. However, beyond the parameter keywords that are well-documented (:length, :pitch, :velocity, and :articulation) it seems there are other keywords that represent important parameters of the score that should not be omitted (e.g., when we are transforming scores, and do not want to loose important characteristics). Here is an example. When the following melodic line is deconstructed, then beyond the well-documented parameter keywords it also shows the parameters :duration and :leg. If the :leg parameter would be omitted in the construction of the (possibly transformed) score, then all legato information would be stripped from the original music. (omn nil '((-3h fs4 pp leg g4 leg) (h a4) (-q cs5 mp< ord) (q c5 f stacc -) (-5h - c5 pp leg e5 < leg f5 < leg) (h gs4 pp))) (:length ((-1/6 1/6 1/6) (1/2) (-1/4 1/4) (1/4 -1/4) (-1/10 -1/10 1/10 1/10 1/10) (1/2)) :pitch ((fs4 g4) (a4) (cs5) (c5) (c5 e5 f5) (gs4)) :velocity ((pp pp) (pp) (mp<) (f) (pp < <) (pp)) :duration ((1/6 1/6) (1/2) (1/4) (1/4) (1/10 1/10 1/10) (1/2)) :articulation ((- -) (-) (ord) (stacc) (- - -) (-)) :leg ((2) (-) (-) (-) (3) (-))) Now, my questions are as follows. (1) Do there exist more than the two additional parameters :duration and :leg shown above? For example, have other special articulations their own OMN keywords? (2) Where are all these parameters documented? (3) Are these parameters stable, or will they possibly change in future? Janusz, in your process-omn function we recently discussed, you used (omn-plist :attribute <my-sequence>) instead of (omn :articulation <my-sequence>). Should omn-plist perhaps be used instead for more stable transformation functions when deconstructing scores? If so, it would be helpful to have that function also documented :) Thanks a lot! Best, Torsten
  11. edit-omn update: 'dynamic' arguments supported

    There was a bug for processing OMN lists that are not nested. That has now been fixed, and the updated version is at GitHub. Best, Torsten
  12. 'Stages 13' Typo?

    I was not aware that this Bug Reports forum was not available for everyone... Best, Torsten
  13. 'Stages 13' Typo?

    > Not sure where to report this (if at all) As another user I greatly appreciate others reporting bugs, as that helps making the system more stable. In future, you can report bugs in the special Bug Reports forum below all other forums at https://opusmodus.com/forums/. Thanks, Torsten
  14. Stephane Boussuge wrote on 23 October > your edit-omn function is definitively super-mega useful !! I updated my function edit-omn. Remember that this function is for turning relatively simple functions processing some OMN parameter sequence (e.g., pitch or length lists) quasi automatically into much more expressive functions processing arbitrary OMN expressions, including nested expressions, and automatically supporting typical Opusmodus arguments like section and flat. I now added support for creating functions with 'dynamic' arguments, i.e. arguments where different values are used for processing different sublists of OMN expressions. For example, again consider a generalisation of the builtin Opusmodus function gen-rotate,which represents a very useful compositional concept, but its current implementation is rather restricted. I already showed how the new and generalised function rotate-omn expands the existing gen-rotate by introducing arguments like flat and section as shown below. (setf melody '((-h e c4 e4) (q. f4 e g4 q a4) (q g4 f4 e e4 d4))) ;; Rotate default parameter pitch of 2nd bar (section 1) to the right. ;; The link above shows how to alternatively rotate length values etc. (rotate-omn 1 melody :section '(1) :flat nil) ; => ((-h e c4 e4) (q. a4 e f4 q g4) (q g4 f4 e e4 d4)) Using a new version of rotate-omn defined with the revised edit-omn we can now also specify different rotation amounts for different bars. The first argument of the function is given a list of rotation amounts (0 1 2), so the pitches of the first bar are not rotated at all, the pitches of the first bar are rotated 1 step to the right, and the pitches of the second bar 2 steps. (rotate-omn '(0 1 2) melody :flat nil) => ((-h e c4 e4) (q. a4 e f4 q g4) (q e4 d4 e g4 f4)) Such 'dynamic' function arguments can be combined with the section argument to limit the processing of the input music to only certain bars. The following call rotates the bars 2 and 3 only (section is (1 2)), the first bar of this selection by 2 steps to the right, and the next by 1 step. (rotate-omn '(2 1) melody :section '(1 2) :flat nil) ; => ((-h e c4 e4) (q. g4 e a4 q f4) (q d4 g4 e f4 e4)) Now, remember that this post is actually about simplifying the definition of functions like rotate-omn. The definition of this function is pretty short, as the actual rotation is already implemented by gen-rotate, and all support of arguments like section, flat and now also 'dynamic' arguments is automatically implemented by edit-omn. For getting dynamic arguments, all we need to do is the following. First, we test whether the argument we want to turn into a 'dynamic' argument is a list. If not, we want to use it as a static value. The result of that test (using listp) is bound to the local variable n-list-arg?, because we need to use this value at two places. The argument additional-args on the last line gets our argument n if it is a list. We tell edit-omn how to actually transform the input music (e.g., sublists) by handing it a function -- that is another program that does the actual transformation. In the case below this function is an anonymous function (it has no name). Such functions are defined with lambda, which is pretty much like defun but without expecting a function name. Our anonymous function basically just calls gen-rotate, but if n is a list, then we first need to extract the OMN data to rotate and the amount by which to rotate it from the single argument xs of our anonymous function. (defun rotate-omn (n sequence &key (parameter :pitch) (flat T) (section nil)) (let ((n-list-arg? (listp n))) (edit-omn parameter sequence #'(lambda (xs) (if n-list-arg? (gen-rotate (second xs) (first xs)) (gen-rotate n xs))) :section section :flat flat :additional-args (when n-list-arg? n)))) With this approach you can write relatively simply functions for processing individual parameters, and then turn that relatively simple function into a much more fancy function processing arbitrary OMN expressions, including nested expressions, and automatically supporting typical Opusmodus arguments like section and flat, and now also with dynamic arguments. As mentioned in other posts, the function edit-omn can be found as part of my tot library at GitHub (and yes, that library has a buch of dependencies, and is therefore a bit tricky to install the first time; updates are a bit more easy). I also cleaned up the definition of edit-omn and fixed some bug that way. Best, Torsten
  15. > Given some UNORDERED amount of pitches, how retrive the prime form and/or Forte Number. Check out function pcs-analysis. The problem is that this function does not return, but only print that data, so it is difficult to apply such analysis on a sequence/list of interval sets etc. > How to do this from an existing midi file or XML ? Is t possible to retrive the forte number of every "n" notes of the pitch collection (melody or chord)? You can import MIDI files with function midi-to-score, but not (yet?) MusicXML file. > Can you circunscribe some notes for analysis in a large file ? What do you mean? BTW, for music analysis you may want to have a look at systems designed for that, like the free music21 (http://web.mit.edu/music21/), based on Python. music21 can import music in various formats, including MIDI and MusicXML (the latter is preferable). The kind of analysis you are after is documented in the tutorial, e.g., at http://web.mit.edu/music21/doc/usersGuide/usersGuide_25_postTonalTools1.html?highlight=forte, which shows how you can add, e.g., the Forte class analysis as text (lyrics) to the score, which in turn you could export as MusicXML. With some Python programming you could also export your analysis data in a format that Lisp and thus could in turn import. E.g., you could export it from Python to JSON format (https://docs.python.org/2/library/json.html), and then import that data into Common Lisp (e.g., https://common-lisp.net/project/cl-json/). Best, Torsten