[CM] Re: Snd strategy?

Richard Liston liston@cc.gatech.edu
Sun, 21 Mar 2004 20:34:53 -0500

> I'm making headway with Snd, but there may be a better way for me
> to proceed than what I'm currently doing. What I would like to do
> is to build up a complex stereo sound one piece at a time. My
> current strategy is to work with three channels. The first two
> channels are the two channels of the stereo sound I'm working on.
> The third channel is my "working" channel. I'll start with some
> waveform in the third channel - right now just a sine wave - then
> modify it until I'm happy with it. Then I'll mix it into either
> channel 0 or 1 of the sound. Finally, I will delete the third
> channel and the sound that remains is my finished sound. All along
> the way I want to easily and quickly play any channel separately or
> the first two channels together.

Along these lines here are some steps I've taken.

Define two instruments:

;;; sine-channel creates a sine wave in the indicated channel
(define (sine-channel start duration frequency amplitude channel)
  (let* ((beg (inexact->exact (floor (* start (mus-srate)))))
         (dur (inexact->exact (floor (* duration (mus-srate)))))
         (v (make-vct dur))
         (s (make-oscil :frequency frequency)))
      (lambda ()
           (vct-map! v (lambda () (oscil s)))
           (mix-vct (vct-scale! v amplitude) beg 0 channel #f))))))

;;; zeroes defines a dummy instrument
(definstrument (zeroes start-time duration outfn)
  (let* ((beg (inexact->exact (floor (* start-time (mus-srate)))))
         (dur (inexact->exact (floor (* duration (mus-srate))))))
      (lambda ()
        (do ((i 0 (1+ i)))
            ((= i dur))
          (outfn (+ i beg) 0 *output*))))))

Define a function to delete a channel:

;;; deletes the data in the indicated channel
(define (delete-channel chan)
    (select-channel chan)

Now create a sound with three channels using two dummy instruments:

    (with-sound (:channels 3)
      (zeroes 0 1 outa)
      (zeroes 0 1 outb))

Unsync the channels and delete the data in the first two channels:

    (set! (sync) 0)
    (delete-channel 0)
    (delete-channel 1)

Add a sine wave to the third channel:

    (sine-channel 0 2 440 .5 2)

Define a function to move the data from the working channel to
a specified channel:

;;; moves the data from the working channel a specified channel, dst-chan
(define* (move-working-chan dst-chan #:optional (src-chan 2) (beg 0) (snd 0))
    (select-channel src-chan)
    (mix-selection beg snd dst-chan)

Now move the channel:

    (move-working-chan 0)


This all seems fine, but now when I just try to play the sound I
don't get any output. I do, however, get output if I define and
call this function:

(define* (play-working-chan #:optional (chan 2))
    (select-channel chan)

I call (play-working-chan 0) and hear it fine.  (play) alone, however,
doesn't work. Any ideas why?