[PlanetCCRMA] sound programming

Fernando Pablo Lopez-Lezcano nando@ccrma.Stanford.EDU
Sun Feb 1 15:49:01 2004


> I need to synthesize/generate simple sinus tones, which last for a certain time 
> (e.g. 100ms) and have a fade-in and a fade-out of each e.g. 5ms. Lot many of 
> such pieces I need to append to each other
> 
> I can do this very simple with goldwave (well a lot of manual tasks),
> but since I work with linux (well goldwave runs with wine, but not
> excellent): what tool, would you recommend (audacity is quite close but
> not mature enough...)?
> 
> Or if I would like to program the sounds manually , is there any tool
> you can recommend (just generating such sounds, inclusive fade-ins and
> -outs and write the resulting .wav data into a file): would you take c++
> (with which library?) or can I do it with easier languages (python?)..

I would suggest any of the existing "synthesis languages" as the best
way to solve this particular problem, although with a non-trivial
learning curve (IMHO proportional to the expressive power of the
environment - please no flame wars about which one is the best :-).
Csound is one of them, it has its own instrument and score languages as
described previously in this thread. 

If you are comfortable with Common Lisp then Common Lisp Music (CLM)
would be the one to use. The same building blocks ("unit generators")
that are part of the Common Lisp based CLM are also available for Scheme
(another dialect of lisp), Ruby and just plain C through snd and the
sndlib library. 

For C++ I'd probably use the STK library, you can write your own
instruments in C++. 

-- Fernando

(*) although a tutorial on CLM / Common Lisp is way beyond the scope of
a single email this would be a simple instrument that generates a sine
wave with an envelope (takes four mandatory parameters: starting time in
seconds, duration in seconds, frequency in hertz and amplitude in the
range 0 to 1, and one optional key argument, the amplitude envelope):

(definstrument simp (start-time duration frequency amplitude 
		     &key (amp-env '(0 0 50 1 100 0)))
  (multiple-value-bind (beg end) (times->samples start-time duration)
    (let ((s (make-oscil :frequency frequency))
	  (amp (make-env :envelope amp-env 
			 :scaler amplitude 
			 :duration duration)))
      (run 
       (loop for i from beg below end do
	 (outa i (* (env amp) (oscil s))))))))


This has to be compiled and loaded into a running lisp interpreter
(CMUCL and Clisp based versions are part of the Planet CCRMA
repository). After that, generating tones is simple (by typing this into
the lisp interpreter):

A 1 second long 440Hz with the default triangular envelope:

(with-sound(:srate 44100)(simp 0 1 440 0.1))

0.1 seconds long note, 10msec attack and decay...

(with-sound(:srate 44100)
   (simp 0 0.1 440 0.1 :amp-env '(0 0 0.01 1 0.09 1 0.1 0)))

More than one note:

(with-sound(:srate 44100)
   (simp 0 1 440 0.1)
   (simp 0.5 2 880 0.1))

Using a simple loop to generate notes automatically:

(with-sound(:srate 44100)
   ;; ten notes
   (loop repeat 10
      ;; spaced by 0.1 seconds
      for time from 0 by 0.1
      ;; with frequencies starting at 100Hz and incremented by 50Hz
      for freq from 100 by 50
      do
      (simp time 0.2 freq 0.1)))