Jump to content
Sign in to follow this  
  • entries
  • comments
  • views

Patterns replacement

Sign in to follow this  
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)
     for idx from 0 to (-(length mat)1)
     collect (if (equal 
                    for i from 0 to (-(length old)1)
                     collect (nth (+ idx i) mat))
               (and (setf idx (+ idx (-(length old)1)))
               (nth idx mat)))))

(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*)))

(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."
  (if (listp (car new))
    (multi-motives-replace old new mat)
    (one-motive-replace old new mat))))
(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)


Sign in to follow this  


Recommended Comments

There are no comments to display.

Add a comment...

×   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.

  • Create New...