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

Patterns replacement

Stephane Boussuge

746 views

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.



0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×