[gsharp-cvs] CVS gsharp
mjonsson
mjonsson at common-lisp.net
Sat Oct 27 02:10:55 UTC 2007
Update of /project/gsharp/cvsroot/gsharp
In directory clnet:/tmp/cvs-serv24656
Modified Files:
gui.lisp play.lisp
Log Message:
Implemented play-buffer and made play-layer available in play menu
--- /project/gsharp/cvsroot/gsharp/gui.lisp 2007/09/18 21:19:03 1.87
+++ /project/gsharp/cvsroot/gsharp/gui.lisp 2007/10/27 02:10:55 1.88
@@ -534,7 +534,11 @@
'play-command-table
:errorp nil
:menu '(("Buffer" :command com-play-buffer)
- ("Segment" :command com-play-segment)))
+ ("Segment" :command com-play-segment)
+ ("Layer" :command com-play-layer)))
+
+(define-gsharp-command (com-play-buffer :name t) ()
+ (play-buffer (buffer (current-cursor))))
(define-gsharp-command (com-play-segment :name t) ()
(play-segment (segment (current-cursor))))
--- /project/gsharp/cvsroot/gsharp/play.lisp 2007/10/20 18:41:25 1.10
+++ /project/gsharp/cvsroot/gsharp/play.lisp 2007/10/27 02:10:55 1.11
@@ -19,12 +19,12 @@
(defun measure-durations (slices)
(let ((durations (mapcar (lambda (slice)
- (mapcar #'duration
- (bars slice)))
- slices)))
+ (mapcar #'duration
+ (bars slice)))
+ slices)))
(loop while durations
- collect (reduce #'max durations :key #'car)
- do (setf durations (remove nil (mapcar #'cdr durations))))))
+ collect (reduce #'max durations :key #'car)
+ do (setf durations (remove nil (mapcar #'cdr durations))))))
(defun average (list &key (key #'identity))
(let ((sum 0)
@@ -68,14 +68,14 @@
(incf time (* *tempo* (duration element)))))
(elements bar)))
-(defun track-from-slice (slice channel durations)
- (cons (make-instance 'program-change-message
- :time 0 :status (+ #xc0 channel) :program 0)
- (let ((time 0))
- (mapcan (lambda (bar duration)
- (prog1 (events-from-bar bar time channel)
- (incf time (* *tempo* duration))))
- (bars slice) durations))))
+(defun track-from-slice (slice channel durations &key (start-time 0))
+ (let ((time start-time))
+ (cons (make-instance 'program-change-message
+ :time time :status (+ #xc0 channel) :program 0)
+ (mapcan (lambda (bar duration)
+ (prog1 (events-from-bar bar time channel)
+ (incf time (* *tempo* duration))))
+ (bars slice) durations))))
(define-condition midi-player-failed (gsharp-condition)
((midi-player :initarg :midi-player)
@@ -115,20 +115,57 @@
#-(or cmu sbcl clisp)
(error "write compatibility layer for RUN-PROGRAM")))
-(defun play-segment (segment)
- (let* ((slices (mapcar #'body (layers segment)))
- (durations (measure-durations slices))
- (*tempo* (tempo segment))
- (*tuning* (gsharp-buffer:tuning segment))
- (tracks (loop for slice in slices
- for i from 0
- collect (track-from-slice slice i durations))))
- (play-tracks tracks)))
-
(defun play-layer (layer)
(let* ((slice (body layer))
- (durations (measure-durations (list slice)))
+ (durations (measure-durations (list slice)))
(*tempo* (tempo (segment layer)))
(*tuning* (gsharp-buffer:tuning (segment layer)))
- (tracks (list (track-from-slice slice 0 durations))))
- (play-tracks tracks)))
\ No newline at end of file
+ (tracks (list (track-from-slice slice 0 durations))))
+ (play-tracks tracks)))
+
+(defun segment-tracks (segment &key (start-time 0))
+ (let* ((slices (mapcar #'body (layers segment)))
+ (durations (measure-durations slices))
+ (*tempo* (tempo segment))
+ (*tuning* (gsharp-buffer:tuning segment)))
+ (values (loop
+ for slice in slices
+ for i from 0
+ collect (track-from-slice slice i durations :start-time start-time))
+ (reduce #'+ durations))))
+
+(defun play-segment (segment)
+ (play-tracks (segment-tracks segment)))
+
+; TODO: There is a short pause between segments?
+(defun play-buffer (buffer)
+ (let* ((time 0)
+ (num-tracks (loop :for segment :in (segments buffer)
+ :maximize (length (layers segment))))
+ (tracks (loop :for i :from 0 :below num-tracks :collect nil)))
+
+ ; Collect snippets from each segment that should go to different tracks
+ (dolist (segment (segments buffer))
+ (let ((*tempo* (tempo segment))
+ (*tuning* (tuning segment)))
+ (multiple-value-bind (track-addendums segment-duration)
+ (segment-tracks segment :start-time time)
+ (format t "~S" segment-duration)
+
+ (incf time segment-duration)
+
+ (loop :for track-addendum :in track-addendums
+ :for tracks-tail :on tracks
+ :do (push track-addendum (car tracks-tail))))))
+
+ ; Concatenate each track's snippets
+ (loop :for tracks-tail :on tracks
+ :do (setf (car tracks-tail)
+ (reduce (lambda (result snippet)
+ (nconc snippet result))
+ (car tracks-tail)
+ :from-end t)))
+
+ (play-tracks tracks)))
+
+
More information about the Gsharp-cvs
mailing list