Forums > MaxMSP

Trouble with numbers

November 5, 2006 | 4:10 pm

Hello everyone.

New to the list, and to MaxMSP.
I’ve working on various elements of a larger instrument I plan to build, but I’ve come to a stumbling block.
Essentially, I am trying to build a ‘master clock’ patch that defines the length of phrases, delays, buffers, etc, based around a common BPM.
I’m taking the BPM and dividng it by different divisions of a minute to get fractions of a beat. The first problem I’m having is that when I divide the BPM by 30,000, then by 7500, to get two different beat lengths respectively. Assumedly, if I multiply the second figure (the one divided by 7500) by 4, I would get the same amount as the other figure (as 7500*4=30000)..It doesn’t happen though, it ends up being almost the same sumber, but not quite. This is illustrated on the right side fo the patch where I’ve labeled it "! BAR". I’ve included an audio rate version of the calculation as well, just for comparison.
The second problem is that when I use ANY of the figures to size a buffer (bottom middle of screen), the figure OFTEN comes out different than the number I’m using to seze the buffer…this sometimes takes a few tries, because sometimes (depending on the BPM setting)it IS the same…maddening. Mess with the BPM and query the buffer length using the info~, you’ll see what I mean.
Note: all numbers are floating point. You have to change the BPM to trigger the calculations the way I have it set up.
ANyway, sorry for the long post, but if anyone can take a look at the patch, I would be very happy.
thanks, Jeremy….patch follows

#P window setfont "Sans Serif" 9.;
#P flonum 665 529 97 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P button 584 484 15 0;
#P window linecount 1;
#P newex 587 510 105 196617 info~ gullet8;
#P message 584 440 43 196617 size $1;
#P newex 584 461 108 196617 buffer~ gullet8 100 2;
#P comment 856 444 100 196617 1bar;
#P comment 692 446 100 196617 1bar;
#P button 636 197 15 0;
#P comment 291 353 100 196617 32 note length;
#P message 808 257 20 196617 32;
#P message 851 136 14 196617 8;
#P user number~ 689 428 783 443 9 3 3 2 0. 0. 0 0. 250 0. 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 689 395 35 196617 *~ 1.;
#P newex 637 327 110 196617 receive~ looplength32;
#P newex 769 361 29 196617 sig~;
#P flonum 876 319 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 856 428 78 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P button 819 335 15 0;
#P newex 842 380 29 196617 * 1.;
#P newex 850 291 114 196617 receive looplength32nd;
#P flonum 851 180 35 9 1. 16. 3 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P flonum 669 299 78 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 626 246 29 196617 * 1.;
#P newex 589 158 112 196617 receive delayunitvalue;
#P user ezdac~ 117 279 161 312 0;
#P button 92 83 15 0;
#P newex 92 132 54 196617 dspstate~;
#P newex 390 283 29 196617 sig~;
#P newex 309 283 29 196617 sig~;
#P newex 273 103 222 196617 midi111;
#P flonum 525 370 69 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 468 338 27 196617 / 1.;
#P button 399 234 15 0;
#P flonum 264 195 35 9 4. 0 5 3 192 6 26 5 195 3 222 222 222 0 0 0;
#P flonum 164 381 73 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P newex 399 401 100 196617 send looplength32nd;
#N comlet Global clear (bang);
#P inlet 355 138 15 0;
#N comlet BPM (float/int);
#P inlet 298 138 15 0;
#P user number~ 300 369 373 384 9 3 3 2 0. 0. 0 0. 250 0. 0 0 0 221 221 221 222 222 222 0 0 0;
#P button 468 234 15 0;
#P newex 376 369 96 196617 send~ looplength32;
#P newex 393 458 43 196617 midiout;
#P message 342 262 37 196617 7500.;
#P newex 355 338 34 196617 /~ 1.;
#P newex 355 192 82 196617 send globalclear;
#P message 355 170 33 196617 clear;
#P newex 508 401 70 196617 s masterBPM;
#P newex 466 458 92 196617 send~ mastersync;
#P newex 279 409 40 196617 sync~;
#P button 277 248 15 0;
#P newex 292 389 95 196617 send delayunitvalue;
#P newex 204 195 45 196617 loadbang;
#P message 217 268 43 196617 30000.;
#P newex 239 304 27 196617 / 1.;
#P window linecount 2;
#P comment 230 164 71 196617 Set MASTER BPM value;
#P window linecount 1;
#P comment 521 347 100 196617 32 note length;
#P comment 173 367 100 196617 8th note length;
#P comment 676 285 100 196617 1bar;
#P fasten 39 0 54 0 847 418 589 418;
#P fasten 39 0 41 0 847 407 861 407;
#P fasten 42 0 43 0 881 355 774 355;
#P connect 42 0 40 0;
#P fasten 42 0 39 1 881 359 866 359;
#P fasten 38 0 40 0 855 321 824 321;
#P fasten 38 0 39 0 855 346 847 346;
#P fasten 56 0 55 0 589 504 592 504;
#P connect 55 6 57 0;
#P connect 54 0 53 0;
#P connect 32 0 31 0;
#P fasten 4 0 23 0 244 335 169 335;
#P fasten 6 0 5 0 209 231 222 231;
#P fasten 5 0 4 0 222 293 244 293;
#P fasten 8 0 4 0 282 287 244 287;
#P fasten 24 0 4 1 269 262 261 262;
#P fasten 20 0 24 0 303 191 269 191;
#P fasten 24 0 8 0 269 232 282 232;
#P fasten 24 0 9 0 269 359 284 359;
#P fasten 4 0 7 0 244 365 297 365;
#P fasten 14 0 19 0 360 364 305 364;
#P fasten 15 0 29 0 347 280 314 280;
#P fasten 6 0 15 0 209 242 347 242;
#P connect 21 0 12 0;
#P connect 12 0 13 0;
#P fasten 29 0 14 0 314 319 360 319;
#P fasten 14 0 17 0 360 364 381 364;
#P fasten 24 0 14 1 269 227 384 227;
#P fasten 30 0 14 1 395 323 384 323;
#P fasten 24 0 30 0 269 227 395 227;
#P fasten 9 2 16 0 314 431 398 431;
#P fasten 24 0 25 0 269 215 404 215;
#P fasten 26 0 22 0 473 395 404 395;
#P fasten 9 0 10 0 284 431 471 431;
#P fasten 24 0 18 0 269 221 473 221;
#P connect 18 0 26 0;
#P fasten 25 0 26 0 404 276 473 276;
#P fasten 15 0 26 0 347 330 473 330;
#P fasten 24 0 26 1 490 210;
#P fasten 24 0 11 0 269 304 513 304;
#P fasten 26 0 27 0 473 362 530 362;
#P fasten 50 0 35 0 641 229 631 229;
#P fasten 34 0 35 0 594 216 631 216;
#P fasten 37 0 50 0 856 196 641 196;
#P fasten 34 0 50 0 594 186 641 186;
#P fasten 37 0 35 1 856 245 650 245;
#P fasten 35 0 36 0 631 268 674 268;
#P fasten 44 0 45 0 642 369 694 369;
#P fasten 45 0 46 0 694 421 694 421;
#P fasten 43 0 45 1 774 385 719 385;
#P fasten 6 0 48 0 174 212 174 41 813 41;
#P fasten 40 0 39 0 824 361 847 361;
#P fasten 6 0 47 0 187 212 187 60 856 60;
#P connect 47 0 37 0;
#P fasten 48 0 42 0 813 311 881 311;
#P window clipboard copycount 58;


November 5, 2006 | 5:03 pm

hi,
i’ve just taken a quick look at your patch. watch out for your
patching style to have an explicit order of events. if you want to
devide two numbers, make sure to first set the right inlet
(denominator). take a look at the example below.
also, rather than relying on graphical layout of your patch (right
before left) you should better use [trigger] to sort out your data flow.
concerning the calculated buffer length, which seems to be incorrect
sometimes, i guess that a valid buffer length must be an integer
multiple of a sample duration, which itself is dependent on the
sampling rate. so you can’t have buffers of arbitrary length.
hope that helps.
volker.

#P window setfont "Sans Serif" 9.;
#P flonum 462 137 49 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P window linecount 1;
#P newex 462 103 55 196617 !/ 30000.;
#P flonum 154 51 35 9 4. 0 5 3 192 6 26 5 195 3 222 222 222 0 0 0;
#P flonum 54 237 73 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P button 167 104 15 0;
#P newex 182 245 95 196617 send delayunitvalue;
#P newex 94 51 45 196617 loadbang;
#P message 107 124 43 196617 30000.;
#P newex 129 160 27 196617 / 1.;
#P comment 63 223 100 196617 8th note length;
#P comment 185 105 183 196617 < -- oha , wrong order of events...;
#P comment 475 82 100 196617 better this way;
#P fasten 9 0 3 1 159 118 151 118;
#P fasten 9 0 7 0 159 88 172 88;
#P fasten 9 0 10 0 159 74 467 74;
#P connect 10 0 11 0;
#P fasten 3 0 8 0 134 191 59 191;
#P fasten 3 0 6 0 134 221 187 221;
#P fasten 4 0 3 0 112 149 134 149;
#P fasten 7 0 3 0 172 143 134 143;
#P fasten 5 0 4 0 99 87 112 87;
#P window clipboard copycount 12;

On 05 Nov 2006, at 16:10, Jeremy Keenan wrote:

>
> Hello everyone.
>
> New to the list, and to MaxMSP.
> I’ve working on various elements of a larger instrument I plan
> to build, but I’ve come to a stumbling block.
> Essentially, I am trying to build a ‘master clock’ patch that
> defines the length of phrases, delays, buffers, etc, based around a
> common BPM.
> I’m taking the BPM and dividng it by different divisions of a
> minute to get fractions of a beat. The first problem I’m having is
> that when I divide the BPM by 30,000, then by 7500, to get two
> different beat lengths respectively. Assumedly, if I multiply the
> second figure (the one divided by 7500) by 4, I would get the same
> amount as the other figure (as 7500*4=30000)..It doesn’t happen
> though, it ends up being almost the same sumber, but not quite.
> This is illustrated on the right side fo the patch where I’ve
> labeled it "! BAR". I’ve included an audio rate version of the
> calculation as well, just for comparison.
> The second problem is that when I use ANY of the figures to size
> a buffer (bottom middle of screen), the figure OFTEN comes out
> different than the number I’m using to seze the buffer…this
> sometimes takes a few tries, because sometimes (depending on the
> BPM setting)it IS the same…maddening. Mess with the BPM and query
> the buffer length using the info~, you’ll see what I mean.
> Note: all numbers are floating point. You have to change the BPM
> to trigger the calculations the way I have it set up.
> ANyway, sorry for the long post, but if anyone can take a look
> at the patch, I would be very happy.
> thanks, Jeremy….patch follows


November 5, 2006 | 5:13 pm

Thank you very much! I see what you are saying- I will try to set up my calculations in the way that you suggest and see if it get more consistent results…I am still a bit unsure about using the trigger…I just haven’t quite wrapped my head around it and it’s obviously essential palce in the MaxMSP universe.
So you’re saying I can’t define the buffer length by an aribitrary float because it is tied to the sampling rate, huh? Hmm…Bummer. I guess I’ll have to take a different approach to that one….
Thanks again, Jeremy


November 5, 2006 | 5:20 pm

you might want to go at it from the other direction

calculate a smallest unit (quanta)
1/24 – quarter note divided by 24
24 of these divisions would be a quarter note
12 of these divisions would be an 8th note
6 of these divisions would be a 16th note
3 of these divisions would be a 32nd note

could also use 1/96 or 1/960 (1/some multiple of 24)
like the old ppqn (pulses per quarter note)

then multiply by integers to get larger durations/periods


November 5, 2006 | 5:36 pm

I don’t know if this will help or not, but this is an object I wrote several years ago to do all my BPM calculations. It handles multiple time signatures as well. At one point in time, I checked it pretty rigorously against Logic Audio’s calculations (i.e. gave it a tempo and it’s output against the length of a bounced logic file). So I think its fairly accurate.

The patch takes in a list of a float and three integers. The first number (the float) is the tempo. The second number is the numerator of the time signature. The third is the denominator of the time signature. The fourth is a quasi-optional duration. I say quasi because if any of the numbers are zero, you’ll get a divide by zero error. The duration can be anything- 4 for a quarter note, 8 for an 8th note etc. Multiples of three will be triplets.

The output of the patch is the length of a measure at the given tempo/time signature in variousy units (ms, samples, Hz for phasor~). The duration (the fourth element of the input list) is given in the same units.

The patch also outputs the number of ticks in the measure based on 48 parts per quarter note. I’ve based all of the little sequencers I’ve written off of 48ppq and haven’t had any trouble. With 48ppq I get 192 ticks in a measure at 4/4. If you wanted to build a clock around this, you could take the length of a measure
in milliseconds and divide it by the number of ticks per measure to get the duration of one tick. This can be used to set a metro. I typically have the output of a metro connected to a counter who’s maximum count is the number of ticks in a measure – 1. Meaning at 192, the counter’s maximum would be 191 so it counts from 0 to 191 for a total of 192 ticks.

Anyways, here is the patch, maybe it will help.

#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P comment 313 84 43 196617 Duration;
#P comment 255 84 24 196617 TS2;
#P comment 195 84 24 196617 TS1;
#P newex 124 62 189 196617 unpack 80. 4 4 4;
#N comlet List: Tempo TimeSignature1 TimeSignature2 Duration;
#P inlet 124 28 15 0;
#P window linecount 2;
#P comment 419 248 141 196617 Time = (Beat Length) * (Meter/Duration);
#P window linecount 1;
#P newex 411 223 114 196617 expr $f1 * ($f2/$f3);
#P window linecount 2;
#P comment 407 377 46 196617 Duration in Hertz;
#P comment 463 377 57 196617 Duration in Samples;
#N comlet Duration in Hz;
#P outlet 411 362 15 0;
#N comlet Duration in Samples;
#P outlet 461 362 15 0;
#P window linecount 1;
#N vpatcher 15 55 295 239;
#N comlet ms to samps;
#P inlet 146 53 15 0;
#N comlet ms to Hertz;
#P inlet 24 52 15 0;
#P window setfont "Sans Serif" 9.;
#P newex 146 85 69 196617 mstosamps~;
#P newex 24 85 86 196617 expr 1/($f1/1000.);
#P outlet 205 109 15 0;
#P outlet 24 109 15 0;
#P comment 49 58 55 196617 ms to hertz;
#P connect 5 0 3 0;
#P connect 3 0 1 0;
#P connect 6 0 4 0;
#P connect 4 1 2 0;
#P pop;
#P newobj 411 322 60 196617 p convert;
#P window linecount 2;
#P comment 154 377 46 196617 Measure in Hertz;
#P comment 210 377 53 196617 Measure in samples;
#P window linecount 1;
#P newex 124 219 27 196617 * 4.;
#N comlet Measure in ms;
#P outlet 124 362 15 0;
#P comment 13 362 121 196617 Measure in miiliseconds;
#P newex 124 153 162 196617 expr (60000. * 4.)/($f1 * $f2);
#P number 557 328 35 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#N comlet Number of Ticks in Measure;
#P outlet 557 368 15 0;
#P newex 557 158 142 196617 expr ($f1 * 48) * (4./$f2);
#N comlet Measure in Hz;
#P outlet 158 362 15 0;
#N comlet Duration in ms;
#P outlet 385 362 15 0;
#N comlet Measure in Samples;
#P outlet 208 362 15 0;
#P comment 280 362 121 196617 Duration in miiliseconds;
#P comment 574 368 140 196617 Number of Ticks in Measure;
#N vpatcher 15 55 295 239;
#N comlet ms to samps;
#P inlet 146 53 15 0;
#N comlet ms to Hertz;
#P inlet 24 52 15 0;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 146 85 69 196617 mstosamps~;
#P newex 24 85 110 196617 expr 1/($f1/1000.);
#P outlet 205 109 15 0;
#P outlet 24 109 15 0;
#P window linecount 0;
#P comment 49 58 55 196617 ms to hertz;
#P connect 5 0 3 0;
#P connect 3 0 1 0;
#P connect 6 0 4 0;
#P connect 4 1 2 0;
#P pop;
#P newobj 158 322 60 196617 p convert;
#P comment 155 221 206 196617 1 Measure = (Beat Length) * (ts1);
#P window setfont "Arial Black" 12.;
#P window linecount 3;
#P comment 300 296 85 791478284 The Great Tempo Utility;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P comment 614 177 116 196617 (ts1 * 48) * (4./ts2);
#P comment 5 174 129 196617 (60k * 4)/(tempo * ts2);
#P comment 132 84 36 196617 Tempo;
#P comment 5 161 100 196617 Beat Length =;
#P comment 600 391 44 196617 (48 ppq);
#P fasten 30 2 16 1 247 116 281 116;
#P lcolor 5;
#P fasten 30 2 27 1 247 151 468 151;
#P lcolor 5;
#P fasten 30 2 13 1 247 118 694 118;
#P lcolor 5;
#P connect 15 0 14 0;
#P lcolor 9;
#P connect 13 0 15 0;
#P lcolor 9;
#P fasten 30 1 19 1 188 143 146 143;
#P lcolor 8;
#P fasten 30 1 13 0 188 143 562 143;
#P lcolor 8;
#P fasten 30 3 27 2 306 151 520 151;
#P lcolor 6;
#P fasten 22 1 23 0 466 354 466 354;
#P fasten 27 0 11 0 416 287 390 287;
#P lcolor 15;
#P connect 27 0 22 0;
#P lcolor 15;
#P fasten 27 0 22 1 416 287 466 287;
#P lcolor 15;
#P connect 22 0 24 0;
#P connect 16 0 19 0;
#P lcolor 15;
#P fasten 16 0 27 0 129 179 416 179;
#P lcolor 15;
#P fasten 7 1 10 0 213 350 213 350;
#P connect 19 0 18 0;
#P lcolor 15;
#P fasten 19 0 7 0 129 277 163 277;
#P lcolor 15;
#P fasten 19 0 7 1 129 277 213 277;
#P lcolor 15;
#P connect 7 0 12 0;
#P connect 30 0 16 0;
#P lcolor 7;
#P connect 29 0 30 0;
#P window clipboard copycount 34;


November 5, 2006 | 5:52 pm

Yes, I get it…that is very helpful indeed! It seems like a "bottom up" approach is be favored- Your seems like an elegant solution…I’ll have to study it in depth, I’m a bit shaky with using experssions, to be sure!
Thank you, Jeremy


November 5, 2006 | 5:55 pm

Yes, I think this is the approach I will take, perhaps caluclated from the sampling rate…Thank you for your help!
Best, Jeremy


Viewing 7 posts - 1 through 7 (of 7 total)