CCRMA

Digital Sound, Additive and Wavetable Synthesis


Lecture Slides


Digital Sound

Transducers change one type of energy into another...

A basic limitation on how things work is that we need to sample a given signal at least twice as fast as the highest frequency present in the signal. Otherwise we won't be able to reconstruct the signal from the samples.


DAC's and ADC's

ADC: converts an analog signal to a stream of samples. We filter the signal to make sure that no frequencies past half the sampling rate go through (to satisfy the Nyquist criteria). Then we sample it and quantize it to the word length we are using.

DAC

Here we see how sampling at less than 1/2 the highest frequency gives rise to "aliasing", where frequencies "reflect" around zero and create components in the reconstructed output that were not there to begin with...

How do we express a sine wave in the discrete digital domain?


Fourier Transform

With these pair of formulas we can move back and forth between a time represetation of our signal and a frequency domain representation. Pure magic...

Same thing but in the discrete digital domain...

N samples in time give us N samples in frequency and viceversa.


Additive Synthesis

In theory we add up a bunch of sine waves and get any complex arbitrary signal.

The simplest case is when all overtones are integer multiples of the fundamental frequency. In this simple case the waveform is periodic.

As the periodic waveform repeats over time we can implement additive synthesis by using a table to store the values of one cycle instead of adding the output of all the equivalent sine oscillators (it is a lot more efficient). Here's a simple clm instrument that implements additive synthesis by using the table-lookup unit generator

And the text version for it:

(definstrument dowave (startime duration frequency amplitude
                       harmonics)
  (multiple-value-bind (beg end) (get-beg-end startime duration)
    (let* ((waveform (load-synthesis-table harmonics (make-table)))
           (s (make-table-lookup :frequency frequency 
                                 :wave-table waveform))
           (amp-env (make-env :envelope '(0 0 0.5 1 1 0) 
                              :scaler amplitude)))
      (run
       (loop for i from beg to end do
	     (outa i (* (env amp-env) (table-lookup s))))))))
In Partial Synthesis the overtones are not integer multiples of a fundamental frequency. Thus we cannot resort to the shortcut of a table and have to really implement all oscillators (and thus use a lot of resources).

Here's a very simple instrument that implements additive synthesis with three partials.

And the text version:

(definstrument doadd (start-time duration frequency amplitude
		      &key (partial1 1.0)(amp1 0.3)
		           (partial2 2.0)(amp2 0.3)
		           (partial3 3.0)(amp3 0.3)
		           (env '(0 0 0.5 1 1 0)))
  (multiple-value-bind (beg end) (get-beg-end start-time duration)
    (let* ((sine1 (make-oscil :frequency (* partial1 frequency)))
	        (sine2 (make-oscil :frequency (* partial2 frequency)))
	        (sine3 (make-oscil :frequency (* partial3 frequency)))
	   (amp-env (make-env :envelope env :scaler amplitude 
                         :start-time start-time :duration duration)))
      (Run
       (loop for i from beg to end do
	     (outa i (* (env amp-env)
			(+ (* amp1 (oscil sine1))
			   (* amp2 (oscil sine2))
			   (* amp3 (oscil sine3))))))))))
In the most general case all parameters of each sine wave are also a function of time (that is, they are controlled by envelopes). This is the most interesting case but also the most expensive computationally and the most difficult to control.

The problem is: "how do we create ot generate the enormous amount of data that we need to accurately represent hundreds of points in the envelopes or all partials?"


©1997 Fernando Lopez-Lezcano. All Rights Reserved.
nando@ccrma.stanford.edu