Jump to content

torstenanders

Members
  • Posts

    497
  • Joined

  • Last visited

Everything posted by torstenanders

  1. 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
  2. Does Opusmodus perhaps already have some quantisation function that expects a list of floats and that basically rounds these floats into a metric rhythm, including using tuplets? I am aware of vector-to-length – that implements a simple form of what I am looking for, but it does not support tuplets. Other algorithmic composition systems have more sophisticated quantisation facilities. For example, OpenMusic provides the box omquantify (among other functions in the Kant library). http://support.ircam.fr/docs/om/om6-manual/co/Quantification.html I am aware that quantification is a complex process, but perhaps that is already there in Opusmodus. Best, Torsten
  3. That link says for me "The page you requested does not exist". Am I missing something? Thanks!
  4. 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
  5. 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
  6. 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
  7. 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
  8. > 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 :)
  9. 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
  10. 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
  11. 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
  12. 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
  13. I was not aware that this Bug Reports forum was not available for everyone... Best, Torsten
  14. > 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
  15. 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
  16. > 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
  17. Here is a rather simple function that might be useful for others as well. The function rotate-omn rotates a sequence by the given number of positions, much like gen-rotate. However, you can specify which parameter you want to rotate, whether you want to rotate the flattened sequence or subsequences separately, or only certain subsequences. (setf melody '((-h q c4) (q. f4 e g4 q a4) (h. g4))) (rotate-omn :right melody) ; => ((-h q g4) (q. c4 e f4 q g4) (h. a4)) (rotate-omn :left melody :parameter :length) ; => ((q c4 q. f4 e g4) (q a4 h g4 tie) (q g4 -h)) (rotate-omn 2 melody :section '(1) :flat nil) ; => ((-h q c4) (q. g4 e a4 q f4) (h. g4)) The function is part of my tot library (http://github.com/tanders/tot). It is a generalisation of the built-in gen-rotate, again with a short definition calling my function edit-omn. Best, Torsten
  18. No worries, I am just translating keywords into symbols then for layout settings. Best, Torsten
  19. > How can I receive OSC signals within Opusmodus? Is there a function that allows me to do this? There are OSC libraries for plain Common Lisp out there that you could use, e.g., https://github.com/zzkt/osc or its fork https://github.com/jamieforth/osc Just found these via Google :) Best, Torsten
  20. I would like to use keywords as instrument identifiers in def-score like shown below. (def-score flute (:key-signature 'chromatic :time-signature '(4 4) :tempo 100 :layout (flute-layout :flute)) (:flute :omn '((q c5 d5 f5 g5) (q c5 d5 f5 g5)))) Unfortunately, this does not work for generating notation, only the playback works. The reason I would like to use keywords is that this would provide a more smooth integration with the format I am using for polyphonic score transformations, which looks like shown below (short example for violin and cello). See code examples at https://github.com/tanders/tot/blob/master/sources/score.lisp; you can see the documentation of this code at http://htmlpreview.github.com/?https://github.com/tanders/tot/blob/master/doc/sources/score.html. '(:vln ((q g4) (q. c5 e d5 q e5 f5) (h. e5)) :vlc ((q g3) (q c4 b3 a3 g3) (h. c3))) If it is not possible to have keywords as instrument identifiers in def-score then I can of course transform my keywords automatically into symbols in the Opusmodus package, but I would first like to know whether disallowing keywords in def-score is intentional. Best, Torsten
  21. Dear Stephane, Did you follow the installation instructions at https://github.com/tanders/tot? Have you installed git? Unfortuantely, the installation is a bit complicated, as there are several dependencies. Therefore I explained it at the link above. The package TU is provided by the library ta-utilities, which you can install with git like everything else. If you want to only have the function you could also go directly to the library ta-utilities at GitHub and copy out the missing functions (https://github.com/tanders/ta-utilities/blob/master/my-utilities.lisp), e.g., remove-properties which then in turn depends on remove-property in the same file. Best, Torsten
  22. I sometimes like to turn certain notes into rests. The built-in function length-rest-series is great for that, but it only works with lengths, not full OMN expressions. So, I generalised that function. I can do now, e.g., the following. (setf melody '((s eb6 < leg f5 < leg c5 < leg f5 < leg) (e e6 f - -q))) (note-rest-series '(1 1) melody :swallow T :section '(0)) ; => ((-s - c5 < leg f5 < leg) (e e6 f - -q)) Note that in contrast to the original function length-rest-series, the new function note-rest-series does not only support OMN expressions, but also extra arguments like swallow and section. The definition of this function uses length-rest-series and my function edit-omn for writing such generalisations, and it can therefore be rather short. In fact, the documentation string of the function is much longer than the definition itself :) Please see below. The function edit-omn is part of my tot library, which is available at GitHub. You can see its definition at starting at (currently) line 24 at https://github.com/tanders/tot/blob/master/sources/OMN-utils.lisp. Note that with edit-omn you can also easily turn other functions that expect just a single parameter list (e.g., pitches, or lengths) into functions for OMN expressions by automatically preserving the time signature and very conveniently adding standard arguments like flat or section. Best, Torsten (defun note-rest-series (positions sequence &key (flat nil) (swallow nil) (section nil)) "This function is like the Opusmodus built-in length-rest-series, but supports arbitrary OMN expressions as input and additionally the arguments swallow and section. Args: - positions (list of ints): positions of notes to be turned into rests - sequence (list of lengths or OMN expression): music to process - flat (Boolean): whether positions count for sublists (nil) or the whole list (T) - swallow (Boolean): whether the pitches of notes turned into rests should be shifted to the next note or omitted (swallowed) - section (list of ints): positions of sublists to process. This argument is ignored if flat is T. Example: ;;; (setf melody '((s eb6 < leg f5 < leg c5 < leg f5 < leg) (e e6 f - -q))) ;;; (note-rest-series '(1 1) melody :swallow T :section '(0)) " (edit-omn :length sequence #'(lambda (ls) (length-rest-series positions ls)) :swallow swallow :section section :flat flat))
  23. Is it possible to "un-merge" voices? The function merge-voices is nice for creating a polyphonic part, but beyond that it is also useful for pitch processing functions. E.g., when processing the music with pitch-invert, the result is different with two merged voices and voices inverted separately, because in the former case pitch-invert takes both voices into account. But after the inversion I would like to separate the voices again... Thanks! Best, Torsten
×
×
  • Create New...

Important Information

Terms of Use Privacy Policy