c@43: (in-package :amuse-tabcode) c@43: c@43: (defun word-duration (word default) c@43: (if (typep word 'tabcode::rhythmic-word) c@43: (let ((flag (tabcode::flag word)) c@43: (dots (tabcode::dots word))) c@43: (if flag c@43: (* (car (rassoc flag tabcode::*rhythms*)) c@43: (if dots 3/2 1)) c@43: default)) c@43: 0)) c@43: c@43: (defun word-causes-stop-p (word course) c@43: (or (typep word 'tabcode::rest) c@43: (typep word 'tabcode::barline) c@43: (and (typep word 'tabcode::chord) c@43: (member course (tabcode::playing word) :key #'tabcode::course)))) c@43: c@43: (defun duration-for-course (course buffer start initial-duration) c@43: (let ((duration initial-duration) c@43: (default-duration initial-duration)) c@43: (do ((i start (+ i 1))) c@43: ((>= i (drei-buffer:size buffer)) duration) c@43: (let* ((object (drei-buffer:buffer-object buffer i)) c@43: (word (tabcode-syntax::tabword-word object))) c@43: (when (word-causes-stop-p word course) c@43: (return-from duration-for-course duration)) c@43: (let ((word-duration (word-duration word default-duration))) c@43: (incf duration word-duration) c@43: (when (> word-duration 0) c@43: (setf default-duration word-duration))))))) c@43: c@43: ;;; FIXME: like GET-COURSE-TUNING/GET-TUNING only more hardcoded c@43: (defun fret-to-number (char) c@43: (let ((fret-num (- (char-code char) 97))) c@43: (cond c@43: ((> fret-num 20) (- fret-num 2)) c@43: ((> fret-num 8) (- fret-num 1)) c@43: (t fret-num)))) c@43: (defun midi-pitch-for-playing (course fret) c@43: (let ((tuning #(67 62 57 53 48 43))) c@43: (+ (aref tuning (1- course)) c@43: (fret-to-number fret)))) c@43: c@43: (defun make-tabcode-composition (tabword-buffer) c@43: (let ((time 0) c@43: (notes) c@43: (result) c@43: (current-duration 1)) c@43: (dotimes (i (drei-buffer:size tabword-buffer) (setq notes (nreverse result))) c@43: (let* ((object (drei-buffer:buffer-object tabword-buffer i)) c@43: (tabword (tabcode-syntax::tabword-word object)) c@43: (duration (word-duration tabword current-duration))) c@43: (when (typep tabword 'tabcode::rhythmic-word) c@43: (setf current-duration duration)) c@43: (when (typep tabword 'tabcode::chord) c@43: (dolist (playing (tabcode::playing tabword)) c@43: (let* ((course (tabcode::course playing)) c@43: (fret (tabcode::fret playing)) c@43: (note-duration (duration-for-course course tabword-buffer (1+ i) current-duration))) c@43: (push (make-instance 'tabcode-pitched-event c@43: :course course c@43: :fret fret c@43: :word tabword ; object? c@43: :number (midi-pitch-for-playing course fret) c@43: :time time c@43: :interval note-duration) c@43: result)))) c@43: (incf time duration))) c@43: (let ((composition (make-instance 'tabcode-composition c@43: :time 0 c@43: :interval time))) c@43: (sequence:adjust-sequence composition (length notes) c@43: :initial-contents notes)))) c@43: c@43: #| c@43: (in-package :clim-user) c@43: c@43: (defvar *composition*) c@43: c@43: (define-command (com-set-amuse-composition c@43: :name t :command-table tabcode-syntax::tabcode-table) c@43: () c@43: (let* ((window (esa:current-window)) c@43: (buffer (drei-buffer:buffer window)) c@43: (syntax (climacs::syntax buffer)) c@43: (tabwords (slot-value syntax 'tabcode-syntax::tabwords))) c@43: (setq *composition* (amuse-tabcode::make-tabcode-composition tabwords)))) c@43: |#