Jump to content
Sign in to follow this  
  • entries
    5
  • comments
    10
  • views
    4,482

About this blog

Opusmodus Blog

Entries in this blog

Stephane Boussuge

L'utilisation des tonalités est basée sur quelques principes, le plus important étant que: si vous voulez appliquer plusieurs tonalités, il faut les appliquer à plusieurs listes sinon, Opusmodus vous renverra un signal d'erreur. Par exemple, pour appliquer '((major) (natural-minor)) il faut au moins 2 listes à traiter:

(setf ex1 (tonality-map '((pentatonic)(natural-minor))
                        '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

vous pouvez également spécifier des paramètres de tonalité directement au niveau de la tonalité:

(setf ex2 (tonality-map '((pentatonic :root f4) (natural-minor :root e5))
                        '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

vous pouvez utiliser à peu près n'importe quoi comme tonalité:

(setf ex3 (tonality-map '((d4e4f4G4a4b4c5) (f4g4ab4c5d5e5))
                        '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

(setf ex4 (tonality-map '(((0 1 2 4 5 7 8)) ((0 2 3 6 7 11)))
                        '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

(setf ex5 (tonality-map '(((f mb5)) ((d maj7)))
                        '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

Maintenant tonalité et bibliothèques:

J'utilise la fonction MCLIST (mapcar 'list) devant LIBRARY pour "parentheser" la sortie, car comme vous avez pu le constater dans mes exemples au dessus, TONALITY-MAP à besoin de tonalités entre parenthèses.

(setf ex6 (tonality-map (mclist (library 'modes 'minor nil :random 3))
                        '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

Maintenant, nous allons utiliser TONALITY-SERIES qui sert à "préparer" des suites de tonalité et qui simplifie beaucoup le travail des parenthèses ;-)

Préparation de la structure harmonique

(setf ex7-path (tonality-series (library 'modes 'minor nil :random 3)))

 

Application de la structure:

(setf ex7-path (tonality-map ex7-path '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

Autre exemple: Préparation de la structure harmonique

(setf ex8-path (tonality-series '(d4f4g4a4c5 e4gs4as4c5d5)))

 

Application de la structure:

(setf ex7-path (tonality-map ex8-path '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

Autre exemple: préparation de la structure harmonique

(setf ex9-path (tonality-series '((c m) (f maj))))

 

Application de la structure:

(setf ex9-path (tonality-map ex9-path '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

Autre exemple: Préparation de la structure harmonique

(setf ex10-path (tonality-series '(pentatonic dorian)
                                  :root '(d4 g4)
                                  :closest 'down))

 

Application de la structure:

(setf ex10-path (tonality-map ex10-path '((c4 d4 e4 f4 g4) (c4 d4 e4 f4 g4))))

 

Voila, ce ne sont que quelques exemples très basiques mais qui, je l'espère, pourrons vous éclairer un peu sur l'usage de tonality-.... dans Opusmodus.

SB.

Stephane Boussuge

La fonction GEN-CHORD2 d'Opusmodus peut se révéler très utile pour la génération de structures harmoniques.

 

 

En voici un petit exemple.

Nous commençons par générer une série qui nous servira de base pour la génération de nos accords.

(setf row (rnd-row :type :pitch))

 

Voici pour commencer l'utilisation la plus simple de gen-chord2.

Quand le paramètre :offset n'est pas précisé la fonction déplace la fenêtre dans la série

du nombre de pas correspondant au parametre taille (size) de l'accord.

(setf chords1 (gen-chord2 8 4 row))

 

Voici maintenant un exemple avec l'utilisation de :offset pour garder des notes communes entre les accords.

Un offset de '(2 3) aura pour effet de conserver sur des accords de 4 sons, 1 et 2 notes commune alternativement,

permettant ainsi une transition plus douce d'accord en accord.

La fonction commence par effectuer un offset (déplacement de la fenetre) de 2 dans la série et

génère un accord de 4 sons puis se déplace de 1 dans la série,

ressort l'accord de 4 sons correspondant à sa position et ainsi de suite.

(setf chords2 (gen-chord2 8 4 row :offset '(2 3)))

 

Utilisation des transpositions.

Même chose que précédement mais avec des transposition aléatoire des accords entre -6 et +6 demi-tons.

Tout d'abord, création d'une liste de valeurs de transpositions:

(setf transpo-val (rnd-sample 8 (gen-integer -6 6)))

 

Puis utilisation de la liste dans la fonction:

(setf chords3 (gen-chord2 8 4 row :offset '(2 3) :transpose transpo-val))

 

Ajout d'une contrainte de tessiture avec :ambitus

(setf chords4 (gen-chord2 8 4 row :offset '(2 3) :transpose transpo-val :ambitus '(c4 c5)))

 

Voici maintenant une partition utilisant la structure que nous venons de créer.

Utilisation des accords comme base de mapping pour une application

sur un contour mélodique:

Contour basé sur un vecteur.

(setf vecteur (gen-white-noise 200))
(setf smooth-vect (vector-smooth 0.63 vecteur))

 

Contour mélodique (on transforme le vecteur en notes)

(setf contour (vector-to-pitch '(g3 c6) smooth-vect))

 

Longueurs

Choix aléatoire de 24 mesures dans une liste de mesures pré-définies:

(setf len (rnd-sample 24 '((s s s s q -q)
                           (e e q s s s s s s s s)
                           (h)
                           (s s q s s s s)
                           (q q e e q -q)
                           )))

 

Assemblage OMN

(setf melo (make-omn            
            :pitch contour
            :length len
            ))

 

Application de la progression d'accords

(setf melo.map (tonality-map (mclist chords4) melo))

 

Contrainte de tessiture:

(setf melo.amb (ambitus '(g3 c6) melo.map))

 

Accompagnement piano

Création d'une liste de figures possibles:

(setf fig '((h c2 e3c4g4)(q c2 e3c4 g3e4 e3c4)(e c4 e3 g3 c3 h c2)))

 

Choix aléatoire de 24 figures parmi cette liste

(setf rchoice (rnd-sample 24 fig))

 

Récupération de la structure des mesures de la mélodie:

(setf mspan (get-span melo.amb))

 

Application de la structure de mesures sur l'accompagnement

(setf acc (length-span mspan rchoice))

 

Application de la structure harmonique sur l'accompagnement

(setf accmp.map (tonality-map (mclist chords4) acc))

 

Définition du score:

(def-score etude           
           (:key-signature 'atonal
            :time-signature (get-time-signature melo.map)
            :tempo 123
            :layout (violin-layout 'violin))

(violin
 :omn melo.amb
 :channel 1
 ;:port 0
 :sound 'gm
 :program 'violin)

(piano
 :omn accmp.map
 :channel 2
 ;:port 0
 :sound 'gm
 :program 'acoustic-grand-piano))

 

Voila, en espérant que ce petit exemple vous a donné des idées.

Vous trouverez en pièce jointe à ce post ce fichier au format .opmo

 

SB.

Stephane Boussuge

Tendency masking is first described by the composer G.M. Koenig.

It is a random selection between two envelope based boundaries.

I have tried to reproduce here this technique for pitch and length selection in a very simple way.

;;; First, boundary description
(setf highb (gen-palindrome '(6 6 6 7 8 8 9 10 10 11 12 13 14 15 16 16 16)))
(setf lowb (gen-palindrome '(6 6 6 5 4 4 3 3 3 2 2 2 2 1 1 1 1)))

;;; Plotting
(list-plot (list highb lowb) :join-points t)

;;; Random pitch selection between boundary
(setf pitch (integer-to-pitch 
             (mapcar (lambda (x y) (rnd-range x y)) highb lowb))) 

;;; Random length selection between boundary
(setf len  (vector-to-length 
            '1/16
            1 8
            (mapcar (lambda(x y) (rnd-range x y)) highb lowb)))

;;; OMN Assembly
(setf phrase (make-omn
              :pitch pitch
              :length len))

SB.

Stephane Boussuge

Patterns finding and replacement can be very useful when composing.

For example, we may want to replace some unwanted motive in a melody, or we may want to generate articulation or velocity based on some patterns of length or pitch.

Another use is to compose a new section based on and old one with patterns replacement from old to new etc, etc... the possibility are naturally endless.

 

I propose here a function named motive-replace who are able to execute this task.

This function is not in a "good" Lisp but works for me and i hope it can be useful for other users.

Naturally, if you can improve this function, i invite you to share your thoughts on this blog.

First, we define some utility function, starting with a function for find one motive and replace it:

(defun one-motive-replace (old new mat)
  (flatten 
   (loop
     for idx from 0 to (-(length mat)1)
     collect (if (equal 
                  (loop 
                    for i from 0 to (-(length old)1)
                     collect (nth (+ idx i) mat))
                  old)
               (and (setf idx (+ idx (-(length old)1)))
                    new)
               (nth idx mat)))))

#|Usage
(one-motive-replace  '(a b c) '(1 2 3)  '(d b s a b c e j g))
=> (d b s 1 2 3 e j g)
(one-motive-replace  '(a b c) '(1 2) '(d b s a b c e j g))
=> (d b s 1 2 e j g)
|#

 

Now, we define a function able to find and replace multiple motives:

(defparameter *res* '())
(defun multi-motives-replace (oldlist newlist mat)
  (cond ((null oldlist) '())
        (t (setf *res* (one-motive-replace (car oldlist) (car newlist) mat))
           (multi-motives-replace (cdr oldlist) (cdr newlist) *res*)))
  *res*)

#|Usage
(multi-motives-replace '((a b c) (e j)) '((1 2 3) (8 9))  '(d b s a b c e j g))
=> (d b s 1 2 3 8 9 g)
|#

 

And finally we define the final function for motivic-replacement who choose between one or multiple motif replace functions based on the list predicate of the first parameter:

(defun motive-replace (old new mat)
  "motive-replace will find an exact motive (old) in a list
  and will replace it by a new one (new).
  Note: It is not pattern matching but can be useful."
  (do-verbose
   ("motive-replace")
  (if (listp (car new))
    (multi-motives-replace old new mat)
    (one-motive-replace old new mat))))
    
#|Usage
(motive-replace '(a b c) '(1 2 3)  '(d b s a b c e j g))
=> (d b s 1 2 3 e j g)
(motive-replace '(a b c) '(1 2) '(d b s a b c e j g))
=> (d b s 1 2 e j g)
(motive-replace '((a b c) (e j)) '((1 2 3) (8 9)) '(d b s a b c e j g))
=> (d b s 1 2 3 8 9 g)
|#

SB.

Stephane Boussuge

A simple example based on an All Interval Row for pitch material and euclidean rhythm for Flute rhythmic generation.

;; All interval row generation
(setf row (air 16 :prime :type :pitch))
;;; Strings chords
;; Chords gen from Air
(setf chords1 (harmonic-progression
               '(0 0 0 0 2 2 2 2)
               row
               :size 4
               :step '(1 2 2 1) ;; step throught row
               :relative t      ;; chords relative path voice leading
               :seed 8392
               ))

;; Strings chords assembly with pitches from chords1 
;; and length generation (whole notes '(w) repeated 32 times)
;; dynamic = pp
(setf chords1.omn (filter-tie   ;; tie repeated notes
                   (make-omn
                    :length (gen-repeat 32 '((w)))
                    :pitch chords1
                    :velocity '((pp))
                    )))

;;; Melody generation for Flute
;; Get the length (size) of chords1.omn
(setf size (length chords1.omn))

;; Pitch material
(setf melo1.pmat (rnd-order
                  (melodize
                   (gen-trim
                    size
                    (mclist
                     (harmonic-progression
                      '(0 0 0 0 2 2 2 2)
                      row
                      :size 5
                      :step '(1 2 2 1)
                      ))))))

;; Melodic generation with euclidean rhythm
(setf melo1.omn (pitch-transpose
                 12
                 (make-omn
                  :pitch melo1.pmat
                  :length (euclidean-rhythm 
                           (gen-repeat size '(16)) 
                           1
                           12
                           's
                           :type 2
                           )
                  :velocity '((mf))
                  )))

(def-score temp 
           (
            :key-signature 'chromatic 
            :time-signature '(4 4) 
            :composer "Stéphane Boussuge"
            :copyright "Copyright © 2017 s.boussuge"
            :tempo 64
            )

(strings1
 :omn chords1.omn
 :channel 1
 :port 0
 :sound 'gm
 :program 'acoustic-grand-piano
 :controllers (1 (gen-dynamic-controller chords1.omn))
 )

(flute1
 :omn melo1.omn
 :channel 2
 :port 0
 :sound 'gm
 :program 'acoustic-grand-piano
 :controllers (1 (gen-dynamic-controller melo1.omn))
 )
)

 

SB.

AudioOutput.mp3

Sign in to follow this  
×