#N canvas 343 49 918 651 12;
#X declare -stdpath ./;
#X obj 231 164 *~;
#X floatatom 231 107 4 0 0 0 - \$0-mod - 0;
#X obj 319 144 line~;
#X floatatom 135 121 4 0 0 0 - \$0-carrier - 0;
#X obj 135 247 cos~;
#X obj 135 191 +~;
#X obj 319 118 pack 0 50;
#X floatatom 319 65 4 0 0 0 - \$0-index - 0;
#X obj 319 92 / 100;
#X text 61 132 carrier;
#X text 42 230 output;
#X text 56 417 Most implementations of "FM" actually use phase \, not frequency \, modulation \, because it extends in a more natural way to "multi-operator FM" with three or more oscillators., f 60;
#X obj 135 148 phasor~;
#X obj 341 599 cos~;
#X obj 341 571 phasor~;
#X text 284 581 this:;
#X text 443 574 is the same;
#X text 444 593 as this:;
#X obj 559 586 osc~;
#N canvas 0 0 450 300 (subpatch) 0;
#X array cos-out 441 float 0;
#X coords 0 1 440 -1 317 134 1 0 0;
#X restore 537 228 graph;
#X obj 135 335 output~;
#X text 541 412 The "modulation" index \, which in true FM is in units of Hertz \, is dimensionless for phase modulation. "Good" values tend to be between 0 and 1... in this patch the index is in hundredths., f 45;
#N canvas 0 0 450 300 (subpatch) 0;
#X array phase-out 441 float 0;
#X coords 0 1 440 0 317 139 1 0 0;
#X restore 537 63 graph;
#X obj 187 233 wrap~;
#X text 283 175 (the index is ramped to avoid clicks.), f 20;
#X text 518 191 0;
#X text 521 56 1;
#X text 522 223 1;
#X text 513 355 -1;
#X text 63 147 phase -->;
#X text 40 246 waveform -->;
#X text 56 473 To do phase modulation \, we split the "carrier oscillator" into its phase calculation ([phasor~]) and its waveform lookup ([cos~]). These together would be equivalent to an [osc~] object \, but the [+~] between them adds the modulating oscillator's output to the phase.;
#X text 540 496 We also have to use a [line~] object to smooth changes in the modulation index \, which wasn't necessary in the previous patch., f 46;
#X text 51 189 phase ---> modulation, f 10;
#X obj 46 20 cnv 5 5 25 empty empty Phase\ Modulation 15 13 0 16 #dfdfdf #202020 0;
#X obj 206 265 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 245 294 tgl 19 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000 0 1;
#X text 266 293 <-- repeatedly;
#X text 228 265 <-- graph once;
#N canvas 455 72 538 384 graph 0;
#X obj 62 86 inlet~;
#X obj 251 237 inlet;
#X obj 263 259 inlet;
#X obj 148 131 inlet~;
#X obj 62 320 tabwrite~ cos-out;
#X obj 251 320 tabwrite~ phase-out;
#X obj 263 282 metro 250;
#X connect 0 0 4 0;
#X connect 1 0 4 0;
#X connect 1 0 5 0;
#X connect 2 0 6 0;
#X connect 3 0 5 0;
#X connect 6 0 4 0;
#X connect 6 0 5 0;
#X restore 171 293 pd graph;
#N canvas 951 219 362 391 init 0;
#X text 85 44 This subpatch initializes the patch and loads values into number boxes., f 30;
#X obj 105 304 declare -stdpath ./;
#X obj 113 117 loadbang;
#X msg 113 209 \; \$1-carrier 220 \; \$1-mod 110 \; \$1-index 50;
#X obj 113 179 f \$0;
#X obj 113 148 bng 19 250 50 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000;
#X connect 2 0 5 0;
#X connect 4 0 3 0;
#X connect 5 0 4 0;
#X restore 308 353 pd init;
#X text 217 66 modulation frequency, f 10;
#X text 122 77 carrier frequency, f 9;
#X text 293 27 modulation index in hundredths, f 16;
#X obj 231 132 osc~;
#X connect 0 0 5 1;
#X connect 1 0 44 0;
#X connect 2 0 0 1;
#X connect 3 0 12 0;
#X connect 4 0 20 0;
#X connect 4 0 39 0;
#X connect 5 0 4 0;
#X connect 5 0 23 0;
#X connect 6 0 2 0;
#X connect 7 0 8 0;
#X connect 8 0 6 0;
#X connect 12 0 5 0;
#X connect 14 0 13 0;
#X connect 23 0 39 1;
#X connect 35 0 39 2;
#X connect 36 0 39 3;
#X connect 44 0 0 0;
