scheme-score

Check-in [e20a90b201]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Implement music-simul and some supporting procs. compile-simul is still TODO.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:e20a90b2018a1964cef5e7dbfde683f94a28e677a9bf7df2c01773f0dea72d23
User & Date: wcm 2019-05-08 19:48:03
Context
2019-05-08
19:56
Add a duration slot to simuls. This gives a faster way of finding simul-duration than recursing on one of the component parts, and comes at little cost--we were already computing it in music-simul. check-in: 2090269de2 user: wcm tags: trunk
19:48
Implement music-simul and some supporting procs. compile-simul is still TODO. check-in: e20a90b201 user: wcm tags: trunk
17:52
Get rid of helpers for case-lambda functions check-in: f9f84f6085 user: wcm tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SPEC.

79
80
81
82
83
84
85






86
87
88
89
90
91
92
Short values are padded with rests.

music-duration : music -> number
(music-duration m)

Returns the total (relative) duration of a music value.








### Music modifiers

Modifiers are music values that wrap a music value with a key, value
environment affecting the interpretation of that music.

music-modify : ilist[symbol,*] music -> modifier







>
>
>
>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Short values are padded with rests.

music-duration : music -> number
(music-duration m)

Returns the total (relative) duration of a music value.

music-pad-end : duration music -> music
(music-pad-end dur m)

If the duration of ‘m’ is less than ‘dur’, return a sequence of
duration ‘dur’ formed from ‘m’ and a trailing rest.


### Music modifiers

Modifiers are music values that wrap a music value with a key, value
environment affecting the interpretation of that music.

music-modify : ilist[symbol,*] music -> modifier

Changes to score.scm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
50
51
52
53
54
55
56








































57
58
59
60
61
62
63
..
79
80
81
82
83
84
85

86
87
88
89
90
91
92
...
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
;;; This is free software. See LICENSE for copyright information.
(load "ialist.scm")
(load "control.state-module.scm")

(import (ialist)
        (control state)
        (fmt)
        (only (srfi 1) fold-right)
        (srfi 116))

;; Argument-checking procedure from SRFI-1.
(define (check-arg pred val caller)
  (let lp ((val val))
    (if (pred val) val (lp (error "Bad argument" val pred caller)))))

................................................................................
;; sequenced musics, we need to be able to traverse the component
;; music values.
(define-record-type simul
  (make-simul part1 part2)
  simul?
  (part1 simul-part1)   ; TODO: better names for these slots
  (part2 simul-part2))









































;;; Modifiers

(define-record-type modifier
  (music-modify context music)
  modifier?
  (context modifier-context)
................................................................................

;; Return the total (relative) duration of a music value.
(define (music-duration m)
  (cond ((note? m) (note-duration m))
        ((rest? m) (rest-duration m))
        ((sequence? m) (sum (imap music-duration m)))
        ((modifier? m) (music-duration (modifier-music m)))

        (else (error "Not a music" m music-duration))))


;; An event is a (i)list representation of a Csound score entry.
(define (event? x) (ipair? x))
(define (event-instrument e) (icar e))
(define (event-pfields e) (icdr e))
................................................................................
;; Main compilation entrypoint.  All compile- procedures take a
;; music and return a state transformer.
(define (compile-mval m)
  (cond ((note? m) (compile-note m))
        ((rest? m) (compile-rest m))
        ((sequence? m) (compile-sequence m))
        ((modifier? m) (compile-modifier m))
        (else (error "Bad argument" m music? compile-mval))))


(define (compile-note m)
  (state-letM* ((c state-get))
    (let ((e (note->event m (cstate-context c) (cstate-seconds c))))
      (state-and-then
       (state-put (cstate-seconds-inc c (event-duration e)))
       (state-pure e)))))







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







 







|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
..
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
;;; This is free software. See LICENSE for copyright information.
(load "ialist.scm")
(load "control.state-module.scm")

(import (ialist)
        (control state)
        (fmt)
        (only (srfi 1) fold fold-right)
        (srfi 116))

;; Argument-checking procedure from SRFI-1.
(define (check-arg pred val caller)
  (let lp ((val val))
    (if (pred val) val (lp (error "Bad argument" val pred caller)))))

................................................................................
;; sequenced musics, we need to be able to traverse the component
;; music values.
(define-record-type simul
  (make-simul part1 part2)
  simul?
  (part1 simul-part1)   ; TODO: better names for these slots
  (part2 simul-part2))

;; Combine musics into a simul.  If any part is short, it is
;; padded out with trailing rests.
;;
;; FIXMEs:
;; Currently quite inefficient for large argument lists.
;;
;; When handling arglists of length > 2 in which later arguments have
;; longer durations than their predecessors, padding is applied to the
;; simul being accumulated and _not_ the component parts.  e.g. for i
;; from 1 to 4 in m1 ... m4, if each mi is shorter than m(i+1), then
;; we get
;;
;;               m4 ------------------|
;;            // m3 ------|___________|
;;            |\ m2 --|___|
;;            \  m1 __|
;;
;; where --- are the extent of a music and ___ indicate padding
;; rests.  A more complex (but possibly better?) approach is to
;; pad all the music values out first, then accumulate them.  At the
;; moment, I can't say whether this matters.
;;
;; The amplitude of simultaneous notes is a very tricky issue.
;; Should we attempt some basic mixing, or leave it to the caller?
(define (music-simul . ms)
  (if (null? ms) (error "Bad argument count" ms music-simul))
  (fold (lambda (ma mb)  ; inefficient
          (make-simul (music-pad-end (music-duration mb) ma)
                      (music-pad-end (music-duration ma) mb)))
        (car ms)
        (cdr ms)))

;; Pad a music value out to a given duration with a trailing rest.
(define (music-pad-end dur m)
  (let ((md (music-duration m)))
    (if (>= md dur)
        m
        (music-append m (make-rest (- dur md))))))


;;; Modifiers

(define-record-type modifier
  (music-modify context music)
  modifier?
  (context modifier-context)
................................................................................

;; Return the total (relative) duration of a music value.
(define (music-duration m)
  (cond ((note? m) (note-duration m))
        ((rest? m) (rest-duration m))
        ((sequence? m) (sum (imap music-duration m)))
        ((modifier? m) (music-duration (modifier-music m)))
        ((simul? m) (music-duration (simul-part1 m)))
        (else (error "Not a music" m music-duration))))


;; An event is a (i)list representation of a Csound score entry.
(define (event? x) (ipair? x))
(define (event-instrument e) (icar e))
(define (event-pfields e) (icdr e))
................................................................................
;; Main compilation entrypoint.  All compile- procedures take a
;; music and return a state transformer.
(define (compile-mval m)
  (cond ((note? m) (compile-note m))
        ((rest? m) (compile-rest m))
        ((sequence? m) (compile-sequence m))
        ((modifier? m) (compile-modifier m))
 ;       ((simul? m) (compile-simul m))
        (else (error "Not a music value" m compile-mval))))

(define (compile-note m)
  (state-letM* ((c state-get))
    (let ((e (note->event m (cstate-context c) (cstate-seconds c))))
      (state-and-then
       (state-put (cstate-seconds-inc c (event-duration e)))
       (state-pure e)))))