Convert PD table feedback patch to MSP table feedback patch

Apr 4, 2010 at 2:22pm

Convert PD table feedback patch to MSP table feedback patch

Hi

Trying to convert a simple pd patch into a max patch and I can usually do this but there are enough differences (and my knowledge of msp is poor) for this one to confuse me. The mechanism of writing the sine wave to the table seems to be quite different in msp, should I be using a table or a buffer – it seems both might work but I can’t get anything which sounds even similar to the PD patch below?

Any ideas or suggestions much appreciated.
Garrett

#N canvas 0 0 697 521 10;
#X text 15 7 Table Feedback Tutorial;
#X text 15 497 2008 (GPL) Claude Heiland-Allen
;
#X obj 17 390 table $0-table 515;
#X obj 17 280 tabosc4~ $0-table;
#X obj 17 360 tabwrite~ $0-table;
#X obj 187 320 metro 100;
#X obj 187 300 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X floatatom 17 260 5 0 0 0 – - -;
#X obj 37 320 dac~;
#X msg 97 178 sinesum 512 1;
#X obj 97 198 s $0-table;
#X obj 17 159 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
#X msg 17 183 ; pd dsp $1;
#X obj 97 158 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
#N canvas 0 0 450 300 $0-hz 0;
#X obj 68 129 outlet;
#X obj 68 49 bang~;
#X obj 68 69 samplerate~;
#X obj 68 89 change;
#X obj 68 109 / 512;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X connect 3 0 4 0;
#X connect 4 0 0 0;
#X restore 17 235 pd $0-hz;
#X text 15 27 Part 5: Blocks And Phase;
#X msg 131 257 0;
#X text 15 67 Here’s how to fix the ugliness of the previous example:
simply connect the [metro] to reset the phase of the oscillator to
“0″.;
#X text 15 117 This works because both [tabwrite~] and [tabosc4~] phase
inlet only respond on exact block boundaries.;
#X text 189 157 1 , 2: turn DSP on and initialise table;
#X text 189 277 4: start feedback process;
#X text 189 227 3: calculate playback frequency;
#X text 15 427 Some ugliness remains , however: bashing the phase
to 0 creates discontinuities , which sound like horrible rhythmic
clicking noises. We can fix that using double buffering.;
#X connect 3 0 4 0;
#X connect 3 0 8 0;
#X connect 3 0 8 1;
#X connect 5 0 4 0;
#X connect 5 0 16 0;
#X connect 6 0 5 0;
#X connect 7 0 3 0;
#X connect 9 0 10 0;
#X connect 11 0 12 0;
#X connect 13 0 9 0;
#X connect 14 0 7 0;
#X connect 16 0 3 1;

#49528
Apr 8, 2010 at 4:00pm

hi, ok so here’s what I have so far. If I use the cycle without the reference to the buffer I get the exact same tone I get in pd but without the interesting clicks. If I reference the buffer I get something click to the clicks but it’s too constant/the same and I lose the tone – how do I get these to work together? I’m sure this is very simple but my understanding of everything msp is not great.

Garrett

max v2;
#N vpatcher 407 60 957 687;
#P origin 0 -33;
#P toggle 460 261 15 0;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P newex 460 285 58 196617 metro 100;
#P flonum 459 316 44 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 466 347 29 196617 1 $1;
#P newex 152 64 50 196617 loadbang;
#N vpatcher 50 40 202 305;
#P window setfont “Sans Serif” 9.;
#P newex 80 145 28 196617 – 2.;
#P newex 80 120 28 196617 * 2.;
#P newex 22 119 28 196617 * 2.;
#P newex 22 95 68 196617 split 0. 0.5;
#P newex 22 59 38 196617 / 512.;
#P outlet 22 208 15 0;
#P inlet 22 33 15 0;
#P connect 0 0 2 0;
#P connect 2 0 3 0;
#P connect 3 0 4 0;
#P connect 4 0 1 0;
#P connect 6 0 1 0;
#P connect 3 1 5 0;
#P connect 5 0 6 0;
#P pop;
#P newobj 192 152 55 196617 p sawtooth;
#P newex 152 175 50 196617 pack 0 0.;
#P newex 152 130 50 196617 t i i;
#P newex 152 108 50 196617 line 0 1;
#P message 152 88 63 196617 0 , 512 512;
#P newex 152 200 81 196617 peek~ mybuffer;
#P newex 152 226 119 196617 buffer~ mybuffer 11.61;
#P flonum 166 385 35 9 0. 1. 3 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 137 333 49 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P number 137 273 49 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P user umenu 56 273 78 196647 1 64 289 0;
#X add 96000;
#X add 88200;
#X add 48000;
#X add 44100;
#P button 56 229 15 0;
#P newex 56 251 59 196617 adstatus sr;
#B color 5;
#P newex 137 292 40 196617 change;
#P newex 137 312 37 196617 / 512;
#P message 257 454 27 196617 stop;
#P message 186 454 65 196617 startwindow;
#P newex 137 490 29 196617 dac~;
#P newex 137 404 39 196617 *~ 0.2;
#P newex 137 358 85 196617 cycle~ mybuffer;
#B color 5;
#P comment 186 439 65 196617 • start audio;
#P window linecount 4;
#P comment 230 348 167 196617 Symbol argument sets name of buffer~ to play from. Additional int argument after that sets sample offset into the buffer~ (default 0);
#P user panel 173 434 123 43;
#X brgb 255 255 255;
#X frgb 100 202 30;
#X border 2;
#X rounded 0;
#X shadow 0;
#X done;
#P fasten 12 0 10 0 61 293 43 293 43 247 61 247;
#P connect 11 0 10 0;
#P connect 10 0 12 0;
#P fasten 10 1 13 0 110 270 142 270;
#P connect 13 0 9 0;
#P connect 9 0 8 0;
#P connect 8 0 14 0;
#P connect 14 0 3 0;
#P connect 3 0 4 0;
#P connect 4 0 5 0;
#P connect 7 0 5 0;
#P connect 6 0 5 0;
#P connect 23 0 18 0;
#P connect 18 0 19 0;
#P connect 19 0 20 0;
#P connect 20 0 21 0;
#P connect 21 0 17 0;
#P connect 4 0 5 1;
#P connect 15 0 4 1;
#P connect 20 1 22 0;
#P connect 22 0 21 1;
#P connect 26 0 25 0;
#P connect 27 0 26 0;
#P pop;

#177982
Apr 8, 2010 at 9:35pm

So I took a shot at this but couldn’t get it to work. I’ll go ahead and post the patch though so that you can compare it to the solution you have now and maybe get yourself closer to what you want. I feel like the design is more accurate to the original.

A few things I noted in your original patch that I tried to correct here:

1) Your playback frequency is an integer when in the original it is a float. I changed the math to [/ 512.] to prevent rounding.

2) You borrowed the waveform generator from the [cycle~] help patch except it is for a sawtooth and the original generates a sine. I found an equation to generate sine waves from a past thread though there may be an error in it. It doesn’t seem to generate a sine wave that begins and ends at 0. and I couldn’t find a better equation for 512 samples. This might not be an issue with my solution and could be all in my head.

3) Originally I tried to replace tabwrite~ with record~ by sending a 1 everytime metro outputs a bang but that didn’t work correctly. poke~ appears to be closer in functionality to tabwrite~ and looks like it is working right, it just doesn’t sound the same.

Hopefully this patch should be 99% there. Hopefully someone can step in or you can see where the flaw is to get it to completion. I’d recommend finding a better equation for the waveform or looking into how poke~ functions.

#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P message 65 231 31 196617 0;
#P newex 125 322 70 196617 count~ 0 512;
#P newex 8 351 61 196617 poke~ table;
#P newex 8 381 99 196617 buffer~ table 11.61;
#N vpatcher 631 194 1231 594;
#P window setfont “Sans Serif” 9.;
#P newex 19 177 61 196617 peek~ table;
#P window linecount 1;
#P newex 19 117 60 196617 t i i b;
#P window linecount 0;
#P newex 44 147 208 196617 expr (sin(($f1/512. )* (2. * 3.1415926)));
#N comlet Initialise Table;
#P inlet 19 29 15 0;
#N counter 0 0 511;
#X flags 0 0;
#P newobj 19 87 83 196617 counter 0 0 511;
#P newex 19 57 44 196617 uzi 512;
#P connect 2 0 0 0;
#P connect 0 0 1 0;
#P connect 1 0 4 0;
#P connect 4 0 5 0;
#P connect 4 1 3 0;
#P connect 3 0 5 1;
#P pop;
#P newobj 86 171 77 196617 p sinesum-512;
#P button 86 144 15 0;
#P hidden newex 24 291 61 196617 r dspstatus;
#P toggle 8 143 15 0;
#P newex 8 171 61 196617 s dspstatus;
#P flonum 8 231 40 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#N vpatcher 469 219 1069 619;
#P window setfont “Sans Serif” 9.;
#P newex 13 33 54 196617 dspstate~;
#N comlet Playback Frequency;
#P outlet 27 135 15 0;
#P newex 27 101 40 196617 / 512.;
#P newex 27 67 40 196617 change;
#P connect 3 1 0 0;
#P connect 0 0 1 0;
#P connect 1 0 2 0;
#P pop;
#P newobj 8 201 70 196617 p playback.hz;
#P newex 125 261 58 196617 metro 100;
#P toggle 125 231 15 0;
#P newex 8 261 67 196617 cycle~ table;
#P newex 24 321 31 196617 dac~;
#P comment 8 23 111 196617 Table Feedback Tutorial;
#P comment 8 37 120 196617 Part 5: Blocks And Phase;
#P window linecount 3;
#P comment 8 67 260 196617 Here’s how to fix the ugliness of the previous example: simply connect the [metro] to reset the phase of the oscillator to “0″.;
#P window linecount 2;
#P comment 8 105 270 196617 This works because both [tabwrite~] and [tabosc4~] phase inlet only respond on exact block boundaries.;
#P window linecount 1;
#P comment 178 144 170 196617 1 , 2: turn DSP on and initialise table;
#P comment 178 201 150 196617 3: calculate playback frequency;
#P comment 178 231 125 196617 4: start feedback process;
#P connect 21 0 8 1;
#P fasten 10 0 21 0 130 286 109 286 109 222 70 222;
#P connect 10 0 20 0;
#P connect 8 0 19 0;
#P fasten 8 0 7 0 13 314 29 314;
#P fasten 8 0 7 1 13 314 50 314;
#P fasten 20 0 19 1 130 345 38 345;
#P connect 9 0 10 0;
#P connect 16 0 17 0;
#P hidden connect 15 0 7 0;
#P connect 12 0 8 0;
#P connect 11 0 12 0;
#P connect 14 0 13 0;
#P window clipboard copycount 22;

#177983
Apr 9, 2010 at 12:40pm

haydeeho :)

here’s some i found:
• max’s cycle~’s float phase inlet behaves different than one might expect:
It doesn’t set the absolute phase but rather a phase relative to a “global” one common to all cycle~ objects.
• cycle~ doesn’t seem to work properly with constantly modified buffers (at least in my 4.6 version !??)
So maybe a phasor~ / wave~ combo would come close.
Still a minor difference: wave~ does 2-point interpolation, tabosc~ does 4-point. I think play~ uses 4-point, but doesn’t seem to work in this patch…??)
• when count has a limit value it keeps on counting forever, where as tabwrite~ only writes once.

here’s what i’ve come up with:
#P window setfont “Sans Serif” 9.;
#P number 221 225 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P button 11 196 15 0;
#P flonum 125 212 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P user waveform~ 328 454 380 214 3 9;
#W mode draw;
#W mouseoutput continuous;
#W unit ms;
#W grid 1000.;
#W ticks 0;
#W labels 1;
#W vlabels 0;
#W vticks 1;
#W bpm 120. 4.;
#W frgb 33 0 0;
#W brgb 60 178 173;
#W rgb2 0 95 255;
#W rgb3 0 0 0;
#W rgb4 0 0 0;
#W rgb5 190 137 255;
#W rgb6 100 100 100;
#W rgb7 100 100 100;
#P window linecount 1;
#P message 78 244 17 196617 0.;
#P newex 165 355 49 196617 count~ 0;
#P newex 6 422 61 196617 poke~ table;
#P newex 5 443 99 196617 buffer~ table 11.61;
#N vpatcher 631 194 1231 594;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P newex 19 180 61 196617 peek~ table;
#P newex 19 117 60 196617 t i i b;
#P newex 44 147 244 196617 expr (sin(($f1/512. )* (2. * 3.1415926535898)));
#N comlet Initialise Table;
#P inlet 19 29 15 0;
#N counter 0 0 511;
#X flags 0 0;
#P newobj 19 87 83 196617 counter 0 0 511;
#P newex 19 57 44 196617 uzi 512;
#P connect 2 0 0 0;
#P connect 0 0 1 0;
#P connect 1 0 4 0;
#P connect 4 0 5 0;
#P connect 4 1 3 0;
#P connect 3 0 5 1;
#P pop 1;
#P newobj 86 171 77 196617 p sinesum-512;
#P button 86 144 15 0;
#P hidden newex 25 333 61 196617 r dspstatus;
#P toggle 8 143 15 0;
#P newex 8 171 61 196617 s dspstatus;
#P flonum 11 243 59 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#N vpatcher 469 219 1069 619;
#P inlet 98 31 15 0;
#P window setfont “Sans Serif” 9.;
#P newex 13 33 54 196617 dspstate~;
#N comlet Playback Frequency;
#P outlet 27 135 15 0;
#P newex 27 101 40 196617 / 512.;
#P newex 27 69 40 196617 change;
#P connect 3 1 0 0;
#P connect 4 0 1 0;
#P connect 0 0 1 0;
#P connect 1 0 2 0;
#P pop;
#P newobj 11 216 70 196617 p playback.hz;
#P newex 165 249 58 196617 metro 100;
#P toggle 165 213 15 0;
#P newex 23 361 31 196617 dac~;
#P comment 8 23 111 196617 Table Feedback Tutorial;
#P comment 8 37 120 196617 Part 5: Blocks And Phase;
#P window linecount 3;
#P comment 8 67 260 196617 Here’s how to fix the ugliness of the previous example: simply connect the [metro] to reset the phase of the oscillator to “0″.;
#P window linecount 2;
#P comment 8 105 270 196617 This works because both [tabwrite~] and [tabosc4~] phase inlet only respond on exact block boundaries.;
#P window linecount 1;
#P comment 270 151 170 196617 1 , 2: turn DSP on and initialise table;
#P comment 270 208 150 196617 3: calculate playback frequency;
#P comment 270 238 125 196617 4: start feedback process;
#P message 328 433 49 196617 set table;
#P newex 11 267 46 196617 phasor~;
#P newex 328 407 48 196617 loadbang;
#P newex 11 304 107 196617 wave~ table 0. 11.61;
#P connect 27 0 14 0;
#P fasten 13 0 24 0 170 286 109 286 109 234 83 234;
#P connect 13 0 23 0;
#P connect 2 0 0 0;
#P connect 3 0 25 0;
#P connect 1 0 3 0;
#P connect 28 0 13 1;
#P connect 12 0 13 0;
#P connect 19 0 20 0;
#P connect 24 0 2 1;
#P connect 0 0 22 0;
#P connect 0 0 11 0;
#P connect 0 0 11 1;
#P connect 23 0 22 1;
#P hidden connect 18 0 11 0;
#P connect 15 0 2 0;
#P connect 14 0 15 0;
#P connect 17 0 16 0;
#P window clipboard copycount 29;

#177984
Apr 10, 2010 at 2:57pm

hi cudnylon and mudang, many thanks for both your suggestions, the expression for the sine wave was something I would never have figured out. I think mudang, moving away from cycle is probably a good idea. I’ve worked on it some more and (not saying it’s anywhere near as efficient as the original pd patch) now looks like it’s doing the same thing (in the waveform) but as cudnylon mentioned on the previous version, it just doesn’t sound the same as the original pd version. I’m reasonably happy with it now, it’s given me several ideas and examples as to how I can generate signals and constantly change them as I go but if you think of anything else to get it closer in sound let me know.

Again many thanks for both of your help.
Garrett

max v2;
#N vpatcher 380 44 1310 537;
#P origin 0 -9;
#P window setfont “Sans Serif” 9.;
#P comment 148 74 170 196617 2: re-initialise table (if you need to);
#P comment 22 175 153 196617 3: calculate playback frequency;
#P newex 165 88 48 196617 loadbang;
#P newex 22 189 48 196617 loadbang;
#P newex 202 255 46 196617 select 1;
#P newex 148 255 44 196617 uzi 512;
#P flonum 446 321 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 446 300 47 196617 * 0.001;
#N counter 0 0 511;
#X flags 0 0;
#P newobj 148 276 83 196617 counter 0 0 511;
#P newex 148 360 61 196617 peek~ table;
#P newex 148 320 60 196617 t i i b;
#P newex 173 340 283 196617 expr (sin((($f1/512. ) + $f2) * (2. * 3.1415926535898)));
#P number 196 215 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P user waveform~ 508 229 380 214 3 9;
#W mode draw;
#W mouseoutput continuous;
#W unit ms;
#W grid 1000.;
#W ticks 0;
#W labels 1;
#W vlabels 0;
#W vticks 1;
#W bpm 120. 4.;
#W frgb 33 0 0;
#W brgb 60 178 173;
#W rgb2 0 95 255;
#W rgb3 0 0 0;
#W rgb4 0 0 0;
#W rgb5 190 137 255;
#W rgb6 100 100 100;
#W rgb7 100 100 100;
#P message 58 279 17 196617 0.;
#P newex 22 405 61 196617 poke~ table;
#P newex 21 426 99 196617 buffer~ table 11.61;
#N vpatcher 771 184 1118 433;
#P window setfont “Sans Serif” 9.;
#P newex 19 180 61 196617 peek~ table;
#P newex 19 117 60 196617 t i i b;
#P newex 44 147 244 196617 expr (sin(($f1/512. )* (2. * 3.1415926535898)));
#N comlet Initialise Table;
#P inlet 19 29 15 0;
#N counter 0 0 511;
#X flags 0 0;
#P newobj 19 87 83 196617 counter 0 0 511;
#P newex 19 57 44 196617 uzi 512;
#P connect 2 0 0 0;
#P connect 0 0 1 0;
#P connect 1 0 4 0;
#P connect 4 0 5 0;
#P connect 4 1 3 0;
#P connect 3 0 5 1;
#P pop;
#P newobj 148 111 77 196617 p sinesum-512;
#P button 148 89 15 0;
#P hidden newex 70 346 64 196617 r mspstatus;
#P toggle 20 89 15 0;
#P newex 20 110 64 196617 s mspstatus;
#P flonum 22 229 59 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#N vpatcher 469 219 621 399;
#P inlet 98 31 15 0;
#P window setfont “Sans Serif” 9.;
#P newex 13 56 54 196617 dspstate~;
#N comlet Playback Frequency;
#P outlet 27 135 15 0;
#P newex 27 102 40 196617 / 512.;
#P newex 27 77 40 196617 change;
#P connect 3 1 0 0;
#P fasten 4 0 1 0 103 98 32 98;
#P connect 0 0 1 0;
#P connect 1 0 2 0;
#P pop;
#P newobj 22 209 70 196617 p playback.hz;
#P newex 148 233 58 196617 metro 100;
#P toggle 148 192 15 0;
#P newex 70 377 31 196617 dac~;
#P window setfont “Sans Serif” 14.;
#P comment 19 35 125 196622 Buffer Feedback;
#P window setfont “Sans Serif” 9.;
#P comment 20 75 78 196617 1: turn MSP on;
#P comment 164 193 125 196617 4: start feedback process;
#P message 508 210 49 196617 set table;
#P newex 22 298 46 196617 phasor~;
#P newex 508 189 48 196617 loadbang;
#P newex 22 320 107 196617 wave~ table 0. 11.61;
#P connect 13 0 12 0;
#P connect 30 0 10 0;
#P connect 10 0 11 0;
#P connect 11 0 2 0;
#P connect 2 0 0 0;
#P connect 0 0 18 0;
#P fasten 9 0 19 0 153 253 63 253;
#P connect 19 0 2 1;
#P fasten 0 0 7 0 27 372 75 372;
#P hidden connect 14 0 7 0;
#P fasten 0 0 7 1 27 367 96 367;
#P connect 15 0 16 0;
#P fasten 31 0 16 0 170 108 153 108;
#P connect 8 0 9 0;
#P connect 9 0 28 0;
#P connect 28 0 25 0;
#P connect 25 0 23 0;
#P connect 23 0 24 0;
#P connect 23 1 22 0;
#P connect 22 0 24 1;
#P connect 21 0 9 1;
#P fasten 8 0 29 0 153 210 239 210 239 251 207 251;
#P connect 29 0 25 3;
#P fasten 25 3 26 0 225 296 451 296;
#P connect 26 0 27 0;
#P connect 27 0 22 1;
#P connect 1 0 3 0;
#P connect 3 0 20 0;
#P pop;

#177985
Apr 10, 2010 at 6:31pm

I’m interested in these differing results between PD and Max/MSP. How do I open the PD patch in your 1st post in PD? I can’t find an option to open as text like in max.

Cheers

#177986
Apr 10, 2010 at 9:25pm

I had to paste it in a text file then rename the extension to .pd

The difference in functionality for basic objects causes direct porting to be difficult, or at least requires creative solutions. I’ve worked on a few “PD/Reaktor to Max” ports and it’s been quite challenging.

#177987
Apr 11, 2010 at 12:45am

Hmm, tried the renaming and PD just shows me loads of errors. Is there a link I can download the .pd from? I’ve only ported a couple pretty simple synth patches from PD to Max, but it would be interesting to see if I can help out with this one.

#177988
Apr 11, 2010 at 1:02am

See if this works…

Attachments:
  1. tablefeedback.pd
#177989
Apr 11, 2010 at 1:14pm

Cheers that text worked.

I’ve given it a go, not 100% successful. My Max version sounds very similar at most extreme frequency settings, but doesn’t have the obvious phase reset clicking when at normal frequency (86.13…whatever at 44.1k).

I don’t have time atm to mess with it any more, but as it is now it does do very similar feedback to the PD patch with different frequencies and “metro” times.

Also included is a port of the PD sinesum object by Chris Rolfe that I grabbed off the forum a while ago.

Attachments:
  1. pd_port_test1.zip
#177990
Apr 11, 2010 at 2:24pm

this sinsum abstraction is fantastic. i think it solves an issue i was having in my own patch (re: wavetables with variable sample length)

thanks tim (and chris, of course)

#177991

You must be logged in to reply to this topic.