function pc:make-chord

55 views
Skip to first unread message

Minoru

unread,
Dec 18, 2022, 5:41:51 AM12/18/22
to Extempore
I've been changing my music codes of extempore v.70 to v.89(extempore-v0.8.9-macos-10.15), then I experienced some errors of 'pc:make-chord' that have never occured on v.70 .

Then I found some changes at 'pc:make-chord' and 'pc:random' .

;; preparing pc:make-chord
(sys:load "/libs/core/pc_ivl.xtm")

;; No.1
(pc:make-chord 36 42 5 '(0 4 7))

;; v.70
;; (36 36 40 40)  ok

;; v.89
;; function(<): argument 2 must be: number
;; argument values: (36.00000000000000000000000 #f) #<PROC <>
;; Trace: cl:merge! <- step

In this case,  'pc:makechord' has .....
;; (map (lambda (x)
;;                (real->integer x))
;;            (cl:sort (cl:remove -1 chord) <)) ; lowest pitch to highest pitch remove -1s

It seems that 'cl:merge!' that is called by cl:sort terminates with the error message because of non number argument. ('cl:merge!' <-- 'cl:sort!' <-- 'cl:sort')

Anyway, cl:sort, cl:sort!, cl:merge!, each of them has no changes between the both version.

So, this problem is fixed when
;; (cl:sort (cl:remove -1 chord) <)) ; lowest pitch to highest pitch remove -1s
is changed as follows
;; (cl:sort (cl:remove #f chord) <)) ; lowest pitch to highest pitch remove -1s

Why should it remove '-1' in v.70 or '#f' in v.89 ?  See No.2 and 3, too.

;; No.2
(pc:make-chord 36 48 5 '(4 7 4 0 4))

;; v .70
;; (36 36 40 43)
;; (36 40 43 43)
;; (36 36 40 43 43)
;; (36 40 40 43)

;; (36 40 40 43 43)
;; ok, no error

;; v .89
;; function(<): argument 1 must be: number
;; argument values: (#f 43) #<PROC <>
;; Trace: step
;;    ... etc ..
;; or (36 40 40 43 43) sometimes ok!

This errored function(<) seems to be used by 'cl:sort', and hence above fixed code solves this problem, too.


;; No.3
(pc:make-chord 36 40 5 '(0 4 7))

;; v.70
;; (36) ok

;; v.89
;; stack-catch: ()
;; stack-catch: ()
;; stack-catch: ()
;; stack-catch: ()
;; function(modulo): argument 1 must be: number
;; argument values: (#f 12) #<PROC modulo>
;; Trace:

In this case,  'pc:makechord' has .....

;; (if  (not pitch) ; if new pitch is #f, try from whole range
;;       (set! chord (cons (pc:random lower upper p) chord))
;;       (set! chord (cons pitch chord)))

the 2nd line uses 'pc:random' which returns #f when not found answer, that is, the variable 'chord' could have non number elements.  ... then

;; (cl:remove (modulo (car chord) 12) p)

this 'modulo' terminates with an error when the variable 'chord' has non number, '#f'.
On the oter hand, 'pc:random' returns -1 in v.70, so this 'modulo' returns an answer without any errors.

So, added fixing again,
;; (set! chord (cons (pc:random lower upper p) chord))
to
;; (set! chord (cl:remove #f (cons (pc:random lower upper p) chord)))            

then, all problems of No.1,2,3 are fixed.

Anyway, the point is ...
v.70  pc:random returns -1 if found no answer
v.89  pc:random returns #f

So,
v.70  'modulo' and 'cl:sort' works without any troubles because argument has number only.
v.89  these functions could terminate with error because argument could have non number '#f'.

It seems to be forgotten to edit some parts of 'pc:make-chord' after v.70 ...  ????

But, I noticed some more again .....

;; (set! chord (cl:remove #f (cons (pc:random lower upper p) chord)))
This code means the variable 'chord' could never have non number element '#f' making errors in this case, so, already fixed line at No.1
;; (cl:sort (cl:remove #f chord) <)) ; lowest pitch to highest pitch remove '#f's
doesn't need to remove '#f' or '-1' any more.
Just sorting only like follows !!
;;(cl:sort chord <)

Now, this is my trial fixed one, including 2 changed lines to remove not '-1' but '#f'

;; Original from  /libs/core/pc_ivl.xtm
(define pc:make-chord
  (lambda (lower upper number pc)
    (let ((chord '()))
      (let loop ((l (round lower))
                       (u (round upper))
                       (n number)
                       (p pc))
        (if (< n 1)
            (map (lambda (x)
                           (real->integer x))
                      ;; 2022-12-17(Sat) 13:03 by minoru
                      ;; (cl:sort (cl:remove -1 chord) <)) ; lowest pitch to highest pitch remove -1s
                      ;; (cl:sort (cl:remove #f chord) <)) ; lowest pitch to highest pitch remove '#f's
                      (cl:sort chord <)) ; lowest pitch to highest pitch remove 'nothing'
            (let* ((range (- u l))
                      (gap (round (/ range n)))
                      (pitch (pc:random l (+ l gap) p)))
              (if (not pitch) ; if new pitch is #f, try from whole range
                    ;; 2022-12-17(Sat) 14:45 by minoru
                    ;; (set! chord (cons (pc:random lower upper p) chord))
                    (set! chord (cl:remove #f (cons (pc:random lower upper p) chord)))              
                    (set! chord (cons pitch chord)))
              (loop (+ l gap)
                        u
                       (- n 1)
                       (if (> (length p) 1)
                            (cl:remove (modulo (car chord) 12) p)
                            pc))))))))


George

unread,
Dec 31, 2022, 4:40:16 PM12/31/22
to Extempore
Minoru
I think you are suggesting a single change to this one line:
which would become:
(cl:sort chord <))

Is that correct?
I will test that out on my setup soon.
Regards
George

Minoru

unread,
Dec 31, 2022, 8:45:20 PM12/31/22
to Extempore
Hi, George and all,
Morning,  Happy new year !

Yes, it is one, just removing unnecessary part.

The other is more important fixing.....

from this line

(set! chord (cons (pc:random lower upper p) chord))
to
(set! chord (cl:remove #f (cons (pc:random lower upper p) chord)))

because 'pc:random' could return #f(non number value) which makes the problem on 'modulo' and 'cl:sort' using '<'.

So, 2 lines.

2023年1月1日日曜日 6:40:16 UTC+9 George:

Minoru

unread,
Dec 31, 2022, 9:12:24 PM12/31/22
to Extempore
Oh I found the way of George ....

So one is George's figure, and the other is

https://github.com/digego/extempore/blob/a3a2563697496c0355c18e4edc92b0c85fe06578/libs/core/pc_ivl.xtm#L388
above line would become:

(set! chord (cl:remove #f (cons (pc:random lower upper p) chord)))

2023年1月1日日曜日 10:45:20 UTC+9 Minoru:
Reply all
Reply to author
Forward
0 new messages