#N canvas 380 38 896 679 12;
#X declare -stdpath ./;
#X floatatom 229 200 8 0 0 0 - - - 0;
#X obj 116 507 -~;
#X obj 229 289 /~;
#X obj 247 261 clip~ 1 999999;
#X obj 134 250 phasor~;
#X obj 146 321 *~;
#X obj 146 358 clip~ -0.5 0.5;
#X floatatom 134 206 8 0 0 0 - - - 0;
#X floatatom 229 143 8 0 0 0 - - - 0;
#X obj 229 171 mtof;
#X text 290 105 band limit (MIDI units), f 13;
#X obj 229 75 loadbang;
#X obj 146 385 *~ 1000;
#X obj 146 412 +~ 501;
#X obj 134 278 -~ 0.5;
#X obj 134 153 samplerate~;
#X obj 134 180 / 512;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-fft 256 float 0;
#A color 0;
#A width 1;
#X coords 0 100 255 0 241 194 1 0 0;
#X restore 605 439 graph;
#X obj 116 591 output~;
#X obj 146 439 tabread4~ \$0-transition;
#X obj 229 229 * 0.4;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-out 960 float 0;
#A color 0;
#A width 1;
#X coords 0 1 959 -1 239 194 1 0 0;
#X restore 349 438 graph;
#N canvas 359 82 943 585 transition-table 0;
#X obj 761 173 cos~;
#X obj 668 173 cos~;
#X obj 620 173 cos~;
#X text 259 231 back the phase up one sample;
#X msg 735 69 -0.0005;
#X obj 668 144 *~ 3;
#X obj 761 144 *~ 5;
#X obj 668 203 *~ 0.33333;
#X obj 761 203 *~ -0.2;
#X obj 620 203 *~ -1;
#X obj 668 246 *~ 0.57692;
#X obj 241 353 cos~;
#X obj 193 348 cos~;
#X msg 259 262 -0.0005;
#X obj 241 327 *~ 3;
#X obj 241 379 *~ 0.33333;
#X obj 193 379 *~ -1;
#X obj 241 419 *~ 0.75;
#X obj 668 288 tabwrite~ \$0-transition;
#X obj 241 476 tabwrite~ \$0-transition;
#X obj 137 162 loadbang;
#X text 309 309 twice the table length;
#X text 297 286 period is 2000 samples \,;
#X text 117 514 This one is used - first and third harmonics only.;
#X text 550 322 This alternate one puts in harmonics 1 \, 3 \, and 5;
#N canvas 0 0 450 300 (subpatch) 0;
#X array \$0-transition 1002 float 0;
#A color 0;
#A width 1;
#X coords 0 1 1002 -1 200 140 1;
#X restore 582 390 graph;
#X text 596 537 ----- 1002 samples ----;
#X text 94 86 Logically the half-cycle is in samples 1 through 1000 samples 0 and 1001 are provided so that the 4-point interpolation will work everywhere., f 54;
#X obj 137 204 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 137 417 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 564 204 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X obj 564 30 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X text 95 49 This network puts a half cycle of a band-limited square wave into the table "\$0-transition.", f 54;
#X obj 192 287 phasor~ 24;
#X obj 668 95 phasor~ 24;
#X connect 0 0 8 0;
#X connect 1 0 7 0;
#X connect 2 0 9 0;
#X connect 4 0 34 1;
#X connect 5 0 1 0;
#X connect 6 0 0 0;
#X connect 7 0 10 0;
#X connect 8 0 10 0;
#X connect 9 0 10 0;
#X connect 10 0 18 0;
#X connect 11 0 15 0;
#X connect 12 0 16 0;
#X connect 13 0 33 1;
#X connect 14 0 11 0;
#X connect 15 0 17 0;
#X connect 16 0 17 0;
#X connect 17 0 19 0;
#X connect 20 0 28 0;
#X connect 28 0 13 0;
#X connect 28 0 29 0;
#X connect 29 0 19 0;
#X connect 30 0 18 0;
#X connect 31 0 4 0;
#X connect 31 0 30 0;
#X connect 33 0 12 0;
#X connect 33 0 14 0;
#X connect 34 0 2 0;
#X connect 34 0 5 0;
#X connect 34 0 6 0;
#X restore 270 327 pd transition-table;
#X text 434 317 The "band limit" controls how fast the transition table is read. If it is set to the Nyquist frequency the table is read at 0.4 times the Nyquist \, or five samples a cycle. Lowering the band limit cuts off the partials of the generated sawtooth wave at frequencies below the Nyquist., f 60;
#X obj 691 25 declare -stdpath ./;
#X obj 134 124 bng 19 250 50 0 empty empty empty 0 -6 0 8 #dfdfdf #000000 #000000;
#X text 433 73 A more sophisticated way to control foldover in sawtooth waves is to replace the once-a-cycle jump with a bandlimited transition. To get a band-limited transition we synthesize a band-limited square wave and harvest the transition from the middle of the top half to the middle of the bottom half. Here we use a square wave at SR/10 \, so that only partials 1 and 3 fit below the Nyquist. The transition should take 1/2 period \, or 5 samples. The table is calculated and stored in the "transition-table" subpatch.;
#X text 434 209 Now any time we wish to make a discontinuity in the output signal \, we make it look exactly like the bandlimited square wave looks. We do this by reading through the table we recorded \, carefully adding a "digital" \, non-band-limited \, sawtooth to "\$0-transition" so that the discontinuities in the two cancel out and what you have left is the transition in the table., f 60;
#X obj 43 19 cnv 5 5 25 empty empty Band-Limited\ Sawtooth\ Generator\ Using\ a\ Transition\ Table 15 13 0 16 #dfdfdf #202020 0;
#X obj 172 487 bng 19 250 50 0 empty empty empty 17 7 0 10 #dfdfdf #000000 #000000;
#X text 195 486 <-- graph once;
#X obj 199 514 tgl 19 0 empty empty empty 0 -10 0 12 #dfdfdf #000000 #000000 0 1;
#X text 223 513 <-- graph repeatedly, f 10;
#N canvas 146 130 450 300 graph 0;
#X obj 256 73 inlet;
#X obj 192 73 inlet;
#X obj 122 73 inlet~;
#X obj 192 206 tabwrite~ \$0-out;
#X obj 256 137 metro 200;
#N canvas 410 243 591 338 fft 0;
#X obj 43 40 inlet~;
#X obj 43 80 rfft~;
#X obj 43 113 *~;
#X obj 75 113 *~;
#X obj 75 156 sqrt~;
#X obj 75 190 expr~ 50 + 20 * log($v1)/log(10);
#X obj 75 224 max~ 0;
#X obj 176 102 block~ 512;
#X obj 75 258 tabsend~ \$0-fft;
#X floatatom 371 133 5 0 0 0 - - - 0;
#X floatatom 371 184 9 0 0 0 - - - 0;
#X obj 371 158 tabread \$0-fft;
#X connect 0 0 1 0;
#X connect 1 0 2 0;
#X connect 1 0 2 1;
#X connect 1 1 3 0;
#X connect 1 1 3 1;
#X connect 2 0 4 0;
#X connect 3 0 4 0;
#X connect 4 0 5 0;
#X connect 5 0 6 0;
#X connect 6 0 8 0;
#X connect 9 0 11 0;
#X connect 11 0 10 0;
#X restore 122 206 pd fft;
#X connect 0 0 4 0;
#X connect 1 0 3 0;
#X connect 2 0 3 0;
#X connect 2 0 5 0;
#X connect 4 0 3 0;
#X restore 146 547 pd graph;
#X msg 229 113 138.233;
#X connect 0 0 20 0;
#X connect 1 0 18 0;
#X connect 1 0 33 0;
#X connect 2 0 5 1;
#X connect 3 0 2 1;
#X connect 4 0 14 0;
#X connect 5 0 6 0;
#X connect 6 0 12 0;
#X connect 7 0 4 0;
#X connect 7 0 3 0;
#X connect 8 0 9 0;
#X connect 9 0 0 0;
#X connect 11 0 25 0;
#X connect 11 0 34 0;
#X connect 12 0 13 0;
#X connect 13 0 19 0;
#X connect 14 0 5 0;
#X connect 14 0 1 1;
#X connect 15 0 16 0;
#X connect 16 0 7 0;
#X connect 19 0 1 0;
#X connect 20 0 2 0;
#X connect 25 0 15 0;
#X connect 29 0 33 1;
#X connect 31 0 33 2;
#X connect 34 0 8 0;
