[CM] SND docs example: FM synthesis vs. additive synthesis

Bill Schottstaedt bil at ccrma.Stanford.EDU
Tue Jun 9 14:16:18 PDT 2015


I was comparing the FM-generated case versus the same magnitude
spectrum generated by a sum of cosines -- this is not really fair,
but see below. (That is, ignore the signs in the Jn expansion).

fm.html has comments that contain most of the code (CLM and Maxima)
that I used.  For that example, I think the FM case is:

(with-sound ("test1.snd")
  (let* ((cgen (make-oscil 1000))
         (mgen (make-oscil 100))
	 (index (hz->radians (* 3 100))))
    (do ((i 0 (+ i 1)))
	((= i 44100))
      (outa i (oscil cgen (* index (oscil mgen)))))))

and the additive synthesis:

(let ((freq 100)
      (index 3.0)
      (amp .3439)) ; so maxamp is 1.0
  (with-sound (:channels 1 :clipped #f)
    (let* ((angle 0.0)
	   (incr (hz->radians 1.0))
	   (n (ceiling (+ index 5)))
	   (cur-phases (make-float-vector (* (+ n 1) 3 2))))

      (do ((i 0 (+ i 1))
	   (j 0 (+ j 3)))
	  ((> i n))
	(set! (cur-phases j) (+ 10 i))
	(set! (cur-phases (+ j 1)) (abs (bes-jn i index)))
	(set! (cur-phases (+ j 2)) (/ pi 2)))

      (do ((i 1 (+ i 1))
	   (j (* (+ n 1) 3) (+ j 3)))
	  ((> i n))
	(set! (cur-phases j) (- 10 i))
	(set! (cur-phases (+ j 1)) (abs (bes-jn i index)))
	(set! (cur-phases (+ j 2)) (/ pi 2)))

      (let ((gen (make-polyoid freq cur-phases)))
	 (do ((i 0 (+ i 1)))
	     ((= i 88200))
	   (outa i (* amp (polyoid gen 0.0))))))))

polyoid here is a sort of additive synthesis generator.
I was looking at this originally trying to find a richer
FM sound.

Actually there's a much better example of this effect
in sndclm.html (it's not actually FM vs additive, but
minimum peak initial phase vs maximum peak):

(let ((98-phases #(0.000000 -0.183194 0.674802 1.163820 -0.147489 1.666302 0.367236 
0.494059 0.191339 
                   0.714980 1.719816 0.382307 1.017937 0.548019 0.342322 1.541035 0.966484 
0.936993 
                   -0.115147 1.638513 1.644277 0.036575 1.852586 1.211701 1.300475 1.231282 
0.026079 
 		   0.393108 1.208123 1.645585 -0.152499 0.274978 1.281084 1.674451 1.147440 
0.906901 
		   1.137155 1.467770 0.851985 0.437992 0.762219 -0.417594 1.884062 1.725160 
-0.230688 
		   0.764342 0.565472 0.612443 0.222826 -0.016453 1.527577 -0.045196 0.585089 
0.031829 
		   0.486579 0.557276 -0.040985 1.257633 1.345950 0.061737 0.281650 -0.231535 
0.620583 
		   0.504202 0.817304 -0.010580 0.584809 1.234045 0.840674 1.222939 0.685333 
1.651765 
		   0.299738 1.890117 0.740013 0.044764 1.547307 0.169892 1.452239 0.352220 
0.122254 
		   1.524772 1.183705 0.507801 1.419950 0.851259 0.008092 1.483245 0.608598 
0.212267	
		   0.545906 0.255277 1.784889 0.270552 1.164997 -0.083981 0.200818 1.204088)))
  (let ((freq 10.0)
	(dur 5.0)
	(n 98))
    (with-sound ()
      (let ((samps (floor (* dur 44100)))
	    (1/n (/ 1.0 n))
	    (freqs (make-float-vector n))
	    (phases (make-float-vector n (* pi 0.5))))
	(do ((i 0 (+ i 1)))
	    ((= i n))
	  (let ((off (/ (* pi (- 0.5 (98-phases i))) (* dur 44100)))
		(h (hz->radians (* freq (+ i 1)))))
	    (set! (freqs i) (+ h off))))
	(let ((ob (make-oscil-bank freqs phases)))
	  (do ((i 0 (+ i 1))) ; get rid of the distracting initial click
	      ((= i 1000))
	    (oscil-bank ob))
	  (do ((k 0 (+ k 1)))
	      ((= k samps))
	    (outa k (* 1/n (oscil-bank ob)))))))))

but this case is showing more of the reverb effect of the difference.
Now the question Andy Moorer mentioned to me in the 70's: given
equal amplitude sinusoids, what set of initial phases gives the 
global minimum peak?  




More information about the Cmdist mailing list