creating a hanning window

Jan 22, 2009 at 11:56pm

creating a hanning window

i’ve been trying to make a hanning window the hard way, without using an expression and without simply loading an existing hanning-array into a buffer…

i thought i could record one period of a sine wave, with the frequency of 44100/512 into a buffer of 12 ms using count~ & poke~. before the sine wave is sent to the buffer it’s multiplied with 0.5 and then 0.5 is added to the signal. that would prevent any value from being below zero.

the buffer seems to receive the signal fine from poke and records it perfectly BUT it is for some reason delayed by approximately 12 ms. the buffer has to have the size of 24 ms to see the hann window…

why isn’t it recorded instantly? any thoughts? i need a perfect hanning window preferably of 12 ms!

here’s the patch

max v2;
#N vpatcher 175 146 713 706;
#P window setfont “Sans Serif” 9.;
#P window linecount 1;
#P newex 241 296 49 196617 vectral~;
#P newex 58 47 48 196617 loadbang;
#P number 225 112 44 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
#P message 177 65 26 196617 512;
#P newex 178 85 66 196617 mstosamps~;
#P window linecount 2;
#P message 396 172 51 196617 ; dsp set 0;
#P message 330 167 51 196617 ; dsp set 1;
#P user number~ 141 238 231 253 9 3 3 2 0. 0. 0 0. 20 0. 0 0 0 221 221 221 222 222 222 0 0 0;
#P window linecount 1;
#P newex 54 194 61 196617 count~ 512;
#P newex 42 269 59 196617 poke~ hann;
#P newex 85 173 40 196617 +~ 0.5;
#P newex 85 151 46 196617 *~ -0.5;
#P message 136 92 14 196617 0;
#P newex 85 130 49 196617 cycle~;
#P newex 85 110 37 196617 / 512;
#P button 74 67 15 0;
#P message 85 91 40 196617 44100;
#P newex 401 88 82 196617 buffer~ hann 24;
#P connect 7 0 8 0;
#P connect 2 0 9 0;
#P connect 9 0 8 1;
#P connect 16 0 2 0;
#P connect 2 0 1 0;
#P connect 1 0 3 0;
#P connect 3 0 4 0;
#P connect 4 0 6 0;
#P connect 6 0 7 0;
#P connect 5 0 4 1;
#P connect 2 0 5 0;
#P connect 9 0 10 0;
#P connect 14 0 13 0;
#P connect 13 1 15 0;
#P pop;

#41893
Jan 23, 2009 at 12:30am

check out this: http://www.fredrikolofsson.com/pages/code-max.html

and search “hanning” here: http://www.maxobjects.com

cheers,

Carey

On Thu, Jan 22, 2009 at 6:56 PM, klive

wrote:

>
> i’ve been trying to make a hanning window the hard way, without using an
> expression and without simply loading an existing hanning-array into a
> buffer…
>
> i thought i could record one period of a sine wave, with the frequency of
> 44100/512 into a buffer of 12 ms using count~ & poke~. before the sine wave
> is sent to the buffer it’s multiplied with 0.5 and then 0.5 is added to the
> signal. that would prevent any value from being below zero.
>
> the buffer seems to receive the signal fine from poke and records it
> perfectly BUT it is for some reason delayed by approximately 12 ms. the
> buffer has to have the size of 24 ms to see the hann window…
>
> why isn’t it recorded instantly? any thoughts? i need a perfect hanning
> window preferably of 12 ms!
>
> here’s the patch
>
> max v2;
> #N vpatcher 175 146 713 706;
> #P window setfont “Sans Serif” 9.;
> #P window linecount 1;
> #P newex 241 296 49 196617 vectral~;
> #P newex 58 47 48 196617 loadbang;
> #P number 225 112 44 9 0 0 0 3 0 0 0 221 221 221 222 222 222 0 0 0;
> #P message 177 65 26 196617 512;
> #P newex 178 85 66 196617 mstosamps~;
> #P window linecount 2;
> #P message 396 172 51 196617 ; dsp set 0;
> #P message 330 167 51 196617 ; dsp set 1;
> #P user number~ 141 238 231 253 9 3 3 2 0. 0. 0 0. 20 0. 0 0 0 221 221 221
> 222 222 222 0 0 0;
> #P window linecount 1;
> #P newex 54 194 61 196617 count~ 512;
> #P newex 42 269 59 196617 poke~ hann;
> #P newex 85 173 40 196617 +~ 0.5;
> #P newex 85 151 46 196617 *~ -0.5;
> #P message 136 92 14 196617 0;
> #P newex 85 130 49 196617 cycle~;
> #P newex 85 110 37 196617 / 512;
> #P button 74 67 15 0;
> #P message 85 91 40 196617 44100;
> #P newex 401 88 82 196617 buffer~ hann 24;
> #P connect 7 0 8 0;
> #P connect 2 0 9 0;
> #P connect 9 0 8 1;
> #P connect 16 0 2 0;
> #P connect 2 0 1 0;
> #P connect 1 0 3 0;
> #P connect 3 0 4 0;
> #P connect 4 0 6 0;
> #P connect 6 0 7 0;
> #P connect 5 0 4 1;
> #P connect 2 0 5 0;
> #P connect 9 0 10 0;
> #P connect 14 0 13 0;
> #P connect 13 1 15 0;
> #P pop;
>
>

#149500
Jan 23, 2009 at 12:45am

thanks!

but i really want to make this method work, as i’m pretty close to getting there and i want to understand what i’m doing wrong… if i’d download an external i’d never understand the workings behind them!

i’m sure i’m simply making a simple mistake somewhere…

#149501
Jan 23, 2009 at 1:22am

1:
cycle~ outputs a cosine wave not a sine wave. cosine waves start at 1 not zero. so that’s why it’s half the buffer out. set the phase to 0.5 instead of 0. [whoops, that's not true! sorry, didn't notice you'd multiplied it by -0.5, that clears it up too. ahem]

2:
when you do that it’s still not perfect because you always get some processing delay when you do things in Max rather than in MSP (scheduler rate rather than sample rate – slower).

3: is there a reason you need to record it to a buffer? you can use a phasor~ or similar to read through a cycle~ by connecting it to the phase inlet – so whatever you’ll eventually be using to read your recorded buffer you could just link to a cycle~, scaling the output accordingly as you have done. Here’s the patch for that solution plus a fix of your original…

max v2;
#N vpatcher 542 63 1208 594;
#P user scope~ 442 313 572 443 256 3 128 -1. 1. 0 0. 0 0. 102 255 51 135 135 135 0;
#P user scope~ 265 313 395 443 256 3 128 -1. 1. 0 0. 0 0. 102 255 51 135 135 135 0;
#P window setfont “Sans Serif” 9.;
#P newex 442 287 40 196617 +~ 0.5;
#P newex 442 262 46 196617 *~ -0.5;
#P newex 442 234 40 196617 cycle~;
#P newex 265 260 63 196617 wave~ hann;
#P newex 351 185 64 196617 phasor~ 0.6;
#P window linecount 2;
#P message 232 110 51 196617 ; dsp set 0;
#P message 232 76 51 196617 ; dsp set 1;
#P window linecount 1;
#P newex 82 269 40 196617 +~ 0.5;
#P newex 82 244 46 196617 *~ -0.5;
#P newex 82 216 40 196617 cycle~;
#P newex 40 306 59 196617 poke~ hann;
#P newex 37 332 82 196617 buffer~ hann 24;
#P newex 98 168 58 196617 /~ 1058.4;
#P newex 27 131 40 196617 count~;
#P button 31 93 15 0;
#P newex 27 57 48 196617 loadbang;
#P comment 161 197 100 196617 24 ms in samples;
#P connect 2 0 3 0;
#P connect 1 0 2 0;
#P connect 9 0 6 0;
#P connect 3 0 6 1;
#P connect 7 0 8 0;
#P connect 8 0 9 0;
#P connect 3 0 4 0;
#P connect 4 0 7 1;
#P connect 12 0 13 0;
#P connect 13 0 17 0;
#P connect 14 0 15 0;
#P connect 15 0 16 0;
#P connect 16 0 18 0;
#P connect 12 0 14 1;
#P pop;

#149502
Jan 23, 2009 at 1:57am

thank you so much, i understand a lot better now .

awesome!

#149503
Feb 7, 2009 at 10:10pm

Hi,

I wrote a helpful abstraction to generate a whole host of different
famous windows into buffer~ data, because these formulae aren’t so
easy to roll off the tips of fingers. This has turned out to be quite
useful…

You can create a window buffer~ like this: [window win 512 kaiser].
‘window’ is the name of the abstraction, ‘win’ is the name of the
buffer~ it will create, 512 is the length (in samples), and ‘kaiser’
is the window function. There are a bunch of functions possible,
including: rect/dirichlet, inc, dec, expodec, rexpodec, cosine,
bartlett/triangle, blackman, hamming, hann, gauss, sinc, lanczos,
nutall, blackman-harris, blackman-nutall, flattop, kaiser-bessel,
kaiser and tukey. Or, you can specifiy the window function as an expr
(valid for jit.expr). An extra numeric argument is used for some of
these, e.g. for expodec it specifies the curvature power.

I should put this on a website soon, but in the meantime… save this
as window.maxpat (a help patcher follows after):

– Pasted Max Patch, click to expand. –

Save this as window.maxhelp:

– Pasted Max Patch, click to expand. –
#149504
Feb 8, 2009 at 3:07am

Very useful patch Graham, thanks a lot. I especially like the hanning setting ;) You missed a great opportunity to call it “the windowmaker” though!

lh

#149505
Feb 8, 2009 at 12:38pm

really really useful!!!

thanks a mega lot!

#149506
Feb 8, 2009 at 4:43pm

I’ve got a window-making abstraction on my website, help yourself if it’s useful.

http://pubweb.csf.edu/~smill/software.html

Best,

Steven

#149507
Feb 20, 2009 at 12:31am

there is also an abstraction by Les Stuck within the example patches that come with max, it is in the granular example, hanning window is used to create the grain envelope.

#149508
Feb 20, 2009 at 8:48am

Dear Klive,
Probably a useless answer coming one month later. The basic answer to your original question is: 512 as an argument for count~ doesn’t set the max count, but its minimum. Make a “count~ 0 512″ is what you’re looking for – although it doesn’t solve the whole problem… Zoe

#149509
Feb 20, 2009 at 9:03am

thank you!
you guys really cleared things out for me, and i’m sure the other windows will prove useful in the future :)

#149510
Mar 18, 2009 at 7:36am

not sure how i missed this one, guess i’m a bit late but, just in case it helps, here’s my version of doing it the ‘hard-way’(which is actually a ‘CPU-efficient way’ compared to storing in a buffer~). Target the last quarter of cycle~ to get the ramp-up and ramp-down(ramp-up reads the last quarter of the cosine-wave forward and ramp-down reads the last quarter in reverse). To do this, scale the ramp between 0 and 0.25 in order to target just a quarter of the cosine-wave and then add an offset of 0.75 to only work with the last quarter of the cosine-wave. This is actually the same thing Zh explained(right on) but this patch is applying it without any buffer~ and directly to a groove~ sync-outlet so that you can see it in application. hope it helps:

– Pasted Max Patch, click to expand. –
#149511

You must be logged in to reply to this topic.