[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