Page 1 of 1

conditionnal loop output

Posted: Sat Feb 20, 2010 7:43 pm
by Matramath
Hi,

I'm newbie in commonlisp. I did not figure out how to collect (or output) in my loop only in the "else do" section.

Code: Select all

(defun make-duration (listpitch)
	; remove duplication and add duration
        (setf at (first (first listpitch)))
        (setf nt (second (first listpitch)))
	(setf dur 0)
	
	(loop for (a b c) in listpitch
		; si nous avons la meme note repete : equal true
		when (equal b nt)
		do
				(setf dur (+ dur (- a at)))
				(setf at a nt b)
                                (setf debut a notep b)
			
		
		; si lesnotes ne sont pas les memes : equal nil 
		else do	
                                (setf dur (+ dur (- a at)))
                                (setf temps dur)
                                (setf at a nt b dur 0)
                
                collect (list debut notep temps)
                )
)
If somebody can give me a clue?!

best,

Mathieu

Re: conditionnal loop output

Posted: Sat Feb 20, 2010 9:06 pm
by nuntius
I'm still trying to understand what you're doing. In the meantime, here's a "well-formatted" version of your code, assuming all variables were meant to be local to this function.

Code: Select all

(defun make-duration (listpitch)
  "remove duplication and add duration"
  (let ((at (first (first listpitch)))
        (nt (second (first listpitch)))
        (dur 0)
        debut
        notep
        temps)
    (loop for (a b c) in listpitch
          when (equal b nt)
          do
          (setf dur (+ dur (- a at))
                at a
                nt b
                debut a
                notep b)
          else do
          (setf dur (+ dur (- a at))
                temps dur
                at a
                nt b
                dur 0)
          collect (list debut notep temps))))

Re: conditionnal loop output

Posted: Sun Feb 21, 2010 1:49 am
by smithzv
I think... You want to walk through your list and collect consecutive elements that have the same note (this looks musical in nature?) and replace them with an element that has (start-time note total-duration). Am I reading this right?

Oh, but you only want to collect in the else do section, not every iteration. We kind of want something like...

Code: Select all

...
          else do
          (progn
             (setf dur (+ dur (- a at))
                     temps dur
                     at a
                     nt b
                     dur 0)
             collect (list debut notep temps))
... but that doesn't work in loop since collect cannot be buried in some form. Someone who knows loop will have to tell you. Does loop even walk the lisp expressions it contains?

In iterate(http://common-lisp.net/project/iterate/) this works:

Code: Select all

(defun make-duration2 (listpitch)
  "remove duplication and add duration"
  (let ((at (first (first listpitch)))
        (nt (second (first listpitch)))
        (dur 0)
        debut
        notep
        temps)
    (iter (for (a b c) in listpitch)
          (if (equal b nt)
              (setf dur (+ dur (- a at))
                    at a
                    nt b
                    debut a
                    notep b)
              (progn
                (setf dur (+ dur (- a at))
                      temps dur
                      at a
                      nt b
                      dur 0)
                (collect (list debut notep temps)))))))
This still doesn't work as it misses the last note and there are probably some other issues, but I think it solves your problem of selectively collecting.

Re: conditionnal loop output

Posted: Sun Feb 21, 2010 4:47 am
by Matramath
Thanks alot for all these information. I will continue to work on it. You where right about music. I want to remove repetitive note from a list and keep

1 : the position in milliseconde of the first note
2 : the note value
3 : calculate the total duration of the new note (add all the duration value of the iterate note)

from this kind of list (position-of-the-note-in-millisec midicent db)
((100 4900 42) (110 4900 65) (120 4900 43) (130 6000 35) (140 6000 86) (150 6100 63))

I would like to get ((100 4900 30) (130 6000 20) (150 6100 10))

Mathieu

Re: conditionnal loop output

Posted: Sun Feb 21, 2010 5:43 am
by Kompottkin
smithzv wrote:Oh, but you only want to collect in the else do section, not every iteration. We kind of want something like...

Code: Select all

...
          else do
          (progn
             (setf dur (+ dur (- a at))
                     temps dur
                     at a
                     nt b
                     dur 0)
             collect (list debut notep temps))
... but that doesn't work in loop since collect cannot be buried in some form. Someone who knows loop will have to tell you.
Like this:

Code: Select all

...
          else do (setf dur (+ dur (- a at))
                        temps dur
                        at a
                        nt b
                        dur 0)
               and collect (list debut notep temps)