Jump to content
Sign in to follow this  
opmo

OMN Symbol VOICE

Recommended Posts

I am working on a new omn symbol VOICES and wonder which way is more natural to write.

I would like to hear your comments and ideas on this.

 

Here are the two examples.

 

With symbol :vx


1) Each voice after each event, next to each other (1 bar 4/4):

symbol option :vx
(:v1 q cs5 ff :v2 q gs4 ff :v3 q f4 ff :v4 q f3 ff
 :v1 q eb5 ff :v2 q gs4 ff :v3 q c4 ff :v4 q gs3 ff
 :v1 q cs5 ff :v2 q gs4 ff :v3 q f4 ff :v4 q cs3 ff
 :v1 q f5 ff :v2 q cs5 ff :v3 q gs4 ff :v4 q cs3 ff)
 
symbol option :x
(:1 q cs5 ff :2 q gs4 ff :3 q f4 ff :4 q f3 ff
 :1 q eb5 ff :2 q gs4 ff :3 q c4 ff :4 q gs3 ff
 :1 q cs5 ff :2 q gs4 ff :3 q f4 ff :4 q cs3 ff
 :1 q f5 ff :2 q cs5 ff :3 q gs4 ff :4 q cs3 ff)

 

2) Each voice in a separate bar (1 bar 4/4):

symbol option :vx
(:v1 (q bb4 ff g4 gs4 e g4 f4)
 :v2 (q cs5 ff b4 gs4 fs4)
 :v3 (q f4 ff bb3 gs3 e bb3 gs3)
 :v3 (q d3 ff e eb3 d3 q c3 bb2))

symbol option :x
(:1 (q e4 ff h f4 q c5)
 :2 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 :3 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 :4 (q c3 ff h f2 q f3))

 

The symbol option :1 :2 :3 :4

(:1 (q e4 ff h f4 q c5)
 :2 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 :3 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 :4 (q c3 ff h f2 q f3))

 

will print in the Listener:

(:|1| (q e4 ff h f4 q c5)
 :|2| (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 :|3| (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 :|4| (q c3 ff h f2 q f3))

 

I personally think the second option is better to control.

 

Best wishes,

JP

Share this post


Link to post
Share on other sites

Dear Janusz,

 

I greatly welcome support for polyphony directly in OMN expressions. Thanks for plans to introduce these, and thanks for consulting us on your plans! 

 

I would prefer individual voices expressed as individual sequences, which would exclude option 1. The most easy way might be to simply express voices a lists in a list (i.e., without any necessary to name voices), but then this notation would be confused with the way OMN expresses bars in a voice (as sublists). You already introduced special syntax options for other composite data in order not to overload the notion of nested lists, by introducing your special chord symbols. 

 

So, why not introducing some special syntax for a group of voices as well like, e.g., the following. Here, a pair of brackets -- [ ... ] -- surrounds the voices, where each voice is notated with OMN as before (i.e., possibly with nested lists expressing bars, the special notation for chords etc.).

[(q e4 ff h f4 q c5)
 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 (q c3 ff h f2 q f3)]

Such bracket syntax is pretty strait forward to implement in Common Lisp, likely more easy than the special OMN chord symbols, using reader macros. For an example see, e.g., https://gist.github.com/chaitanyagupta/9324402, where a much more complex syntax (JSON) is parsed with reader macros. Another example is http://frank.kank.net/essays/hash.html, which defines a custom hash-table syntax with reader macros.

 

While I would like in principle to have an option for polyphony without the need to name individual voices (e.g., to express polyphony for keyboard instruments), it would also be very useful to optionally be able to freely name voices, e.g., according to a later def-score expression, as in the following snippet.

[:flute (q e4 ff h f4 q c5)
 :oboe (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 :french-horn (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 :bass-clarinet (q c3 ff h f2 q f3)]

If the reader macro treads individual symbols as optional voice names followed by a list representing the actual voice, both notations above should be possible to support.

 

Also, we may want to be able to express changes of the polyphony (number of parallel voices), as well as expressing sections this way. Why not using plain lists containing the proposed voice groups to expresses again sequences of musical material, as in the following example, where a two-voice section is followed by a monophonic section.

([(q e4 ff h f4 q c5)
  (e fs4 ff gs4 bb4 gs4 q fs4 f4)]
 [(s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)])

Finally, a restriction would likely be that parallel voices have to share the same metric structure. That should be easy enough to enforce by raising an exception otherwise, but it might be a case of errors users easily run into when algorithmically generating polyphonic music. So, a more smart way to deal with that would be welcome. No idea right now how to address that, though.

 

What do you think?

 

Best,

Torsten

 

PS: Note that I very rarely define custom reader macros, because they also have their downsides (e.g., bracket pairs would not be recognised by the Lisp editor of Opusmodus out of the box), but in this particular case I think they would be a good idea. OMN introduced its own syntax already anyway, and aims to combine readability, conciseness and simplicity. The proposed notation of groups of voices fits in that nicely in my view. 

Share this post


Link to post
Share on other sites

great thing!

for me it's important to have the voice-symbol also in (single-events omn-list), and to read it like (omn :voice omn-list), and (voicep  omn-list)

 

greetings

andré 

Share this post


Link to post
Share on other sites
15 hours ago, torstenanders said:

 

I would prefer individual voices expressed as individual sequences, which would exclude option 1.

 

Great thoughts Torsten. Some very good ideas in your answer and I agree (when I understand :-) ) with your reasoning.

 

/Lasse

Share this post


Link to post
Share on other sites
16 hours ago, torstenanders said:

Finally, a restriction would likely be that parallel voices have to share the same metric structure. That should be easy enough to enforce by raising an exception otherwise, but it might be a case of errors users easily run into when algorithmically generating polyphonic music. So, a more smart way to deal with that would be welcome. No idea right now how to address that, though.

 

On second thought, with def-score we have exactly the same issue (which, btw is also shared by all your other voice grouping proposals above), and with def-score this is addressed by the option to specify the time signature separately. Perhaps we could do the same here? If so, perhaps we could also specify the tempo for snippets with voices? Now, I am getting greedy ;-)  --  but being able to specify tempi would really be handy.  E.g.,

[(q e4 ff h f4 q c5)
 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 (q c3 ff h f2 q f3)
 :time-signature '((1 1 1 1) 4)
 :tempo 100]

BTW: This voice group reader macro -- [...] -- would best be complemented by a pretty printing option, which ensures that any results containing such voice groups are printed with the same syntax using brackets. That way, dealing with this extended OMN data structure remains as easy and direct as OMN is so far. Behind the scenes, voice groups can then be represented with an arbitrary data structure (e.g., objects). An example for such pretty printing is shown also at http://frank.kank.net/essays/hash.html, where the hash tables are printed with the special syntax introduced there.

 

Of course, as AM pointed out, functions for processing any such voice groups would need to use special accessor functions like omn and friends, but that is already the case with other functions processing OMN, in particular functions processing the notes of chords with their special syntax.

 

Best,

Torsten

Share this post


Link to post
Share on other sites

Dear Janusz,

 

After our chat last night I still think that it would be useful to make voice numbers optional. If they are absent, this could simply mean that they are in increasing order, starting with 1. So, the following two snippets would be equivalent.

(:1 (q e4 ff h f4 q c5)
 :2 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 :3 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4))
((q e4 ff h f4 q c5)
 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4))

Now, the problem with the latter notation is that it cannot be distinguished from a sequence of bars, which is why I proposed another notation to mark parallel voices (those brackets). Alternatively, we could simply require another level of parentheses. 

(((q e4 ff h f4 q c5))
 ((e fs4 ff gs4 bb4 gs4 q fs4 f4))
 ((s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)))

This could also be done by a simple function that expects an arbitrary number of voices with or without sublists for bars, and then creates the additional lists (or voice number markers) behind the scene.

(make-voices
 (q e4 ff h f4 q c5)
 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4))

Anyway, as I pointed out before I suspect we quickly run into cases where the time signatures of different voices get inconsistent -- regardless of the notation used, and that it would be useful to optionally specify time signatures explicitly, like in def-score. This would simply cause a re-barring behind the scene, which is not a big deal.

(make-voices
 (q e4 ff h f4 q c5)
 (e fs4 ff gs4 bb4 gs4 q fs4 f4)
 (s g3 ff gs3 q bb3 s gs3 g3 q gs3 f4)
 :time-signature '((1 1 1 1) 4))

Tempo specifications for snippets would be very useful as well, and so would be partial scores with instrument names specified instead of voice numbers, but that might be too much :)

 

Best,

Torsten

Share this post


Link to post
Share on other sites

OK: I changed my mind -- with a simple function like the above make-voices we can have "unnumbered" voices. Then the OMN notation can be consistent using the voice-number keywords you proposed, or whatever :)

 

Best,

Torsten

Share this post


Link to post
Share on other sites

A make-voices function like the one described feels like the most OM:ish way.

I am lost in the technical discussion so I will leave that.

 

Spring greetings from Sweden.

Share this post


Link to post
Share on other sites

Implemented in ver 1.3.24622

Final function name: PS

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

  • Similar Topics

    • By JulioHerrlein
      Parsimonious Voice Leading (again): attempts to provide an algorithm
      In a previous post I deleted, I was trying to find a good way to ensure  the minimal parsimonious Voice-Leading (VL) between a sequence of chords.
      In this post I will try to explain my second attempt.
       
      Let's take a look at a sequence of chords, spreaded out almost in a random way, with no VL
      (setf chordstovl2 '(b3eb5g3 cs6e7gs3 b4f5g6 f7e5c2 d4f7e4 gs7e2a8) Let's specify and evaluate a variable for the number of voices used:
      (setf voices 3) Let's try to think the best way to connect this pitches with minimal movement. I will apply the following expression to ensure a better and less ambiguous result when applying the CHORD-CLOSEST-PATH function.
       
      Evaluate voices before
      (setf voices 3) Then
      (setf chordized (mclist (chordize-list (gen-divide voices (setf vlfinal (integer-to-pitch (modus (interval-to-pitch (replace-map '((-11 1) (-10 2) (-9 3) (-8 4) (-7 5) (7 -5) (8 -4) (9 -3)(10 -2)(11 -1)) (integer-to-interval (modus (pitch-to-midi (setf chordmelo (pitch-melodize chordstovl2)))))) :start (car chordmelo))))))))) Please note the use of the replace-map function ensuring that no movement will be greater than a tritone away. This means that a movement like "C to G" (7 semitones) will be convertet in a G to C (5 semitones). This ensure a modulo 12 (octave constraint) reduction of all the material and also a constraint in terms of the size of the movements that will not exceed 6 semitones.
       
      Finally, I will apply the CHORD-CLOSEST-PATH function
      (chord-closest-path (car chordized) (chordize-list (gen-divide voices vlfinal))) Hope it help some VL efforts.
       
      Best,
      Julio Herrlein
    • By Jorvd
      Hi everyone, this one should be pretty simple but I can't seem to figure it out yet.
      I am trying to notate this (see attachment) first bar in OM.
      So far I have this:
      (h e3c4g4e5 f3f4a4d5 z^q g4 f4 h g3d4b4 c3c4e4c5 ) Which doesn't work yet, although it's close.
      Additionally, I would love to use the same figured bass notation (with the brackets and everything).
      I know how to use the text attribute for Instruments but it seems to map everything based on white-space between the text, maybe I'm missing something?

      Thanks!
      - Jor
       

    • By Stephane Boussuge
      Hi, 
      here are the two functions i use daily in my workflow.
       
      The first gen-pitch-line can be used as this but is also required for the second function svoice1.
       
      svoice1 is a generic omn generator i find useful for my work.
       
      ;;; ------------------------------------------------------------------------------ ;;; GEN-PITCH-LINE ;;; Fonction de génération de hauteurs basées sur une conversion de vecteur de bruit ;;; avec un grand choix de type de bruit, taux de compression du vecteur, filtrage des répétitions et ambitus. (defun gen-pitch-line (nb-pitch &key (compress 1) (ambitus '(c4 c6)) seed filter-repeat (type :white)) (setf seed (rnd-seed seed)) (let (pitches) (do-verbose ("gen-pitch-line :seed ~s" seed) (labels ((white-or-pink (nb-pitch seed type) (if (eq type ':pink) (gen-pink-noise nb-pitch :seed seed) (gen-white-noise nb-pitch :seed seed :type (if (eq type ':white) :normal type)))) (process (nb-pitch &key (compress 1) (ambitus '(c4 c6)) seed filter-repeat type) (setf pitches (vector-to-pitch ambitus (vector-smooth compress (white-or-pink nb-pitch seed type)))) (when filter-repeat (setf pitches (gen-trim nb-pitch (filter-repeat filter-repeat pitches)))) pitches) ) (process nb-pitch :compress compress :ambitus ambitus :filter-repeat filter-repeat :seed (seed) :type type))))) #| USAGE (gen-pitch-line 24 :compress 0.42 :type :white :filter-repeat 1) (gen-pitch-line 24 :compress 0.42 :type :pink :filter-repeat 1) (gen-pitch-line 24 :compress 0.42 :type :extreme :filter-repeat 1) (gen-eval 8 '(make-omn :pitch (gen-pitch-line 24 :compress 0.42 :type :white :filter-repeat 1) :length (euclidean-rhythm 16 1 16 's :type 2) ) :seed 33) |# ;;; ------------------------------------------------------------------------------ ;;; SVOICE1 ;;; VERSION 0.1 (defun svoice1 (nb-pitch &key (level 16) (low 1) (high 16) (ratio 1/16) (e-type 2)(e-rotate nil)(e-variant nil) (compress 1)(filter-repeat nil)(pline-type :white) (p-divide nil)(articulation nil) (length nil)(pitch nil)(velocity nil) (seed nil)(articulation-map nil) (add-interval-if-length nil) (i-length '1/16) (i-list '(-4 -5 -3 -7)) ) (setf seed (rnd-seed seed)) (do-verbose ("svoice1 :seed ~s" seed) (let* (( pitch (if pitch pitch (if p-divide (gen-divide p-divide (gen-pitch-line nb-pitch :compress compress :seed (seed) :filter-repeat filter-repeat :type pline-type)) (gen-pitch-line nb-pitch :compress compress :seed (seed) :filter-repeat filter-repeat :type pline-type)))) (len (if length length (euclidean-rhythm level low high ratio :type e-type :rotate e-rotate :variant e-variant :seed (seed)))) (art (if articulation articulation (if articulation-map (length-map articulation-map len :otherwise '(default)) ))) (velo (if velocity velocity '(mf))) ) (if add-interval-if-length (add-interval-if-length (make-omn :pitch pitch :length len :velocity velo :articulation art ) :length-val i-length :interval-list i-list ) (make-omn :pitch pitch :length len :velocity velo :articulation art ))))) #| USAGE (svoice1 32) (svoice1 32 :seed 1234) (svoice1 32 :pitch '(c4 d4 e4) :articulation '(marc)) (svoice1 32 :length '((h h)(q q e e e e))) (svoice1 32 :pitch '(c4 g4) :length '((h h)(q q e e e e)) :velocity '((f)(pp))) (svoice1 32 :i-list '(-7 -4 -5 -3) :low 1 :high 4) (svoice1 128 :p-divide 8 :level (gen-repeat 12 '(16)) :compress 0.16) (svoice1 128 :p-divide 8 :level (gen-repeat 12 '(16)) :compress 0.16 :articulation-map '((1/8 stacc)(1/16 leg))) (svoice1 128 :p-divide 8 :level (gen-repeat 12 '(16)) :low 8 :high 8 :compress 0.16 :articulation-map '((1/8 stacc)(1/16 leg))) (svoice1 128 :p-divide 8 :level (gen-repeat 12 '(16)) :low 8 :high 8 :compress 0.16 :articulation-map '((1/8 stacc)(1/16 leg)) :add-interval-if-length t) (svoice1 128 :p-divide 8 :level (gen-repeat 12 '(16)) :low 2 :high 16 :compress 0.16 :articulation-map '((1/8 stacc)(1/16 leg))) (tonality-map '(((0 2 4 6 8 10) :root d4)) (svoice1 128 :p-divide 8 :level (gen-repeat 12 '(16)) :low 2 :high 16 :compress 0.16 :articulation-map '((1/8 stacc)(1/16 leg))) ) |# S.
×
×
  • Create New...