- ;; handle notes with strings assigned and fingering of 0
- (for-each
- (lambda (note string finger)
- (let ((digit (if (null? finger)
- #f
- finger)))
- (if (and (null? string)
- (not (eq? digit 0)))
- (set! unassigned-notes (cons note unassigned-notes))
- (if (eq? digit 0)
- (let ((fit-string
- (find (lambda (string)
- (open-string string (note-pitch note)))
- free-strings)))
- (if fit-string
- (begin
- (delete-free-string fit-string)
- (set-fret note fit-string))
- (begin
- (ly:warning (_ "No open string for pitch ~a")
- (note-pitch note))
- (set! unassigned-notes (cons note unassigned-notes)))))
- (let ((this-fret (calc-fret (note-pitch note) string tuning))
- (handle-negative
- (ly:context-property context
- 'handleNegativeFrets
- 'recalculate)))
- (cond ((or (>= this-fret 0)
- (eq? handle-negative 'include))
- (begin
- (delete-free-string string)
- (set-fret note string)))
- ((eq? handle-negative 'recalculate)
- (begin
- (ly:warning (_ "Requested string for pitch requires negative fret: string ~a pitch ~a") string (note-pitch note))
- (ly:warning (_ "Ignoring string request."))
- (set! unassigned-notes (cons note unassigned-notes))))))))))
- notes defined-strings defined-fingers)
-
- ;; handle notes without strings assigned
+ ;;; body of determine-frets-and-strings
+ (let* ((pitch-alist (apply (lambda (mylist)
+ (let ((index -1))
+ (map (lambda (note)
+ (begin
+ (set! index (1+ index))
+ (cons (note-pitch note)
+ index)))
+ mylist)))
+ notes '()))
+ (pitches (map note-pitch notes)))
+
+ ;; handle notes with strings assigned and fingering of 0
+ (for-each
+ (lambda (pitch-entry string-fret-finger)
+ (let* ((string (list-ref string-fret-finger 0))
+ (finger (if (eq? (length string-fret-finger) 3)
+ (list-ref string-fret-finger 2)
+ '()))
+ (pitch (car pitch-entry))
+ (digit (if (null? finger)
+ #f
+ finger)))
+ (if (or (not (null? string))
+ (eq? digit 0))
+ (if (eq? digit 0)
+ ;; here we handle fingers of 0 -- open strings
+ (let ((fit-string
+ (find (lambda (string)
+ (open-string string pitch))
+ free-strings)))
+ (if fit-string
+ (set-fret! pitch-entry fit-string #f)
+ (ly:warning (_ "No open string for pitch ~a")
+ pitch)))
+ ;; here we handle assigned strings
+ (let ((this-fret
+ (calc-fret pitch string tuning))
+ (handle-negative
+ (ly:context-property context
+ 'handleNegativeFrets
+ 'recalculate)))
+ (cond ((or (and (>= this-fret 0) (integer? this-fret))
+ (eq? handle-negative 'include))
+ (set-fret! pitch-entry string finger))
+ ((eq? handle-negative 'recalculate)
+ (begin
+ (ly:warning
+ (_ "Requested string for pitch requires negative fret: string ~a pitch ~a")
+ string
+ pitch)
+ (ly:warning (_ "Ignoring string request and recalculating."))
+ (list-set! string-fret-fingers
+ (cdr pitch-entry)
+ (if (null? finger)
+ (list '() #f)
+ (list '() #f finger)))))
+ ((eq? handle-negative 'ignore)
+ (begin
+ (ly:warning
+ (_ "Requested string for pitch requires negative fret: string ~a pitch ~a")
+ string
+ pitch)
+ (ly:warning (_ "Ignoring note in tablature."))
+ (kill-note! string-fret-fingers
+ (cdr pitch-entry))))))))))
+ pitch-alist string-fret-fingers)
+ ;; handle notes without strings assigned -- sorted by pitch, so
+ ;; we need to use the alist to have the note number available