

(define frequency-envelopes (make-vector 20))

(define amplitude-envelopes (make-vector 20))

;; second, we load the arrays with data

(let ((frequency-envelopes (make-vector 20))
      (amplitude-envelopes (make-vector 20)))
  (do ((counter 0 (+ counter 1)))
      ((>= counter 20))
    (vector-set! frequency-envelopes counter
                 (list 0 (* (+ counter 1) 1)
                       1 (* (+ counter 1) 3)))
    (vector-set! amplitude-envelopes counter
                 (list 0 0 
                       0.5 (/ 0.5 (+ counter 1))
                       1 0))))


;; third, we create an instrument which can parse these arrays
;; and render the resulting additive synthesis
(define (additive-compl start-time duration frequencies amplitudes partials fundamental amplitude)
  (let* ((start-sample (* start-time *srate*))
         (end-sample (+ start-sample (* duration *srate*)))
         (number-oscillators (or partials (min (vector-length frequencies) (+ 1 (vector-length amplitudes)))))
         (oscillators (make-vector number-oscillators))
         (freq-envs (make-vector number-oscillators))
         (amp-envs (make-vector number-oscillators))
         (output-sample 0.0))
    (do ((counter 0 (+ counter 1)))
        ((>= counter number-oscillators))
      (vector-set! oscillators counter (make-oscil :frequency 0.0))
      (vector-set! freq-envs counter (make-env :duration duration
                                                :scaler (hz->radians fundamental)
                                                :envelope (vector-ref frequencies counter)))
      (vector-set! amp-envs counter (make-env :duration duration
                                               :scaler amplitude
                                               :envelope (vector-ref amplitudes counter))))
    
     (do ((sample-number start-sample (+ sample-number 1)))
         ((>= sample-number end-sample))
       (set! output-sample 0.0)
       (do ((counter 0 (+ counter 1)))
           ((>= counter number-oscillators))
         (set! output-sample (+ output-sample
                                 (* (env (vector-ref amp-envs counter))
                                    (oscil (vector-ref oscillators counter)
                                           (env (vector-ref freq-envs counter)))))))
       (outa sample-number output-sample))))



#|
Now use (with-sound) to combine the data arrays we created with the instrument and render some output:

(with-sound (:srate 44100 :statistics #t) 
  (additive-compl 0 12 frequency-envelopes amplitude-envelopes 20 110))
|#
