Easy Way of Windowing A Buffer

    Apr 29 2009 | 7:45 pm
    Hi All, I'm chopping up an audio file in to specific sections which are then stored and used in the grain.bang object.
    As the segmenting is based on pitch i am getting clicks at either end of the edit. This is happening with the windowing of the grain bang also.
    I wanted to know if there's an easy way performing an operation on a buffer that fades in and out?

    • Apr 29 2009 | 9:08 pm
      first thing that comes to mind is a [function] object in combination with [line~] and a [*~]
    • Apr 29 2009 | 9:08 pm
      If you want to do this directly to the buffer then it's real easy to do if you don't need to do it while audio is running.
      you can read a buffer sample by sample with peek (or poke, i forget) and then use the sample index as the argument to a windowing function (eg triangle: 1 - 2/sampleLength*abs(index-sampleLength/2). multiply the sample by the windowing function and peek it into a new buffer.
      If you want to do this dynamically to new buffers, then you might be better off not manipulating actual buffers and instead add a windowing function separately. one solution is to write your windowing function to a buffer. Read your grain with wave~ and use the same ramp driving the wave~ to read the window and *~ them together.
      ramp -> A
      A-> wave~ grain -> B
      A-> wave~ window -> C
      B * C = windowed grain
      here's a schematic with a really simple grain scheduler. This would be improved by putting everything after the sel object inside a poly~ so that you don't interrupt one grain to start another. (also, scheduling grains via control path has given me lots of problems. )
      #P outlet 133 344 15 0;
      #P window setfont "Sans Serif" 9.;
      #P window linecount 1;
      #P comment 231 105 100 9109513 set grain length;
      #P flonum 189 104 35 9 0 0 0 139 0 0 0 221 221 221 222 222 222 0 0 0;
      #P newex 189 128 57 9109513 prepend set;
      #P flonum 129 152 35 9 0 0 0 139 0 0 0 221 221 221 222 222 222 0 0 0;
      #P message 129 172 37 9109513 0 , 1 $1;
      #P window linecount 2;
      #P comment 197 163 100 9109513 create ramp in response to bang;
      #P window linecount 1;
      #P newex 129 193 27 9109513 line~;
      #P newex 129 127 28 9109513 sel 1;
      #P window linecount 2;
      #P comment 197 59 100 9109513 generate bangs at random intervals;
      #P window linecount 1;
      #P newex 129 103 31 9109513 > 990;
      #P newex 129 79 62 9109513 random 1000;
      #P toggle 129 30 15 0;
      #P newex 129 57 45 9109513 metro 10;
      #P newex 132 314 27 9109513 *~;
      #P newex 170 261 67 9109513 wave~ window;
      #P newex 103 261 58 9109513 wave~ grain;
      #P connect 2 0 16 0;
      #P connect 9 0 0 0;
      #P connect 9 0 1 0;
      #P connect 11 0 9 0;
      #P connect 12 0 11 0;
      #P connect 13 0 12 0;
      #P connect 14 0 13 0;
      #P connect 8 0 12 0;
      #P connect 6 0 8 0;
      #P connect 5 0 6 0;
      #P connect 3 0 5 0;
      #P connect 4 0 3 0;
      #P connect 0 0 2 0;
      #P connect 1 0 2 1;
      #P window clipboard copycount 17;
      hope this helps
    • Apr 30 2009 | 12:50 pm
      look into trapezoid~ fed by the position oulet... Can't get much easier...
    • Apr 30 2009 | 4:00 pm
      thanks for the replies everyone
      i am now working on with peek and poke to do the windowing
      as my samples will vary in size, ideally i'd like the shorter ones to be windowed completely, but for the longer samples i'd prefer if it didn't window the entire thing, just the start and end points of it.
      is there a way to do this by altering the patch below?
    • Apr 30 2009 | 8:47 pm
      I can't open your patch cuz i'm still on max 4.6
      this is one of those cases where doing it in javascript would be way easier IMHO, but i've solved the problem for you with max. (since i have important other work to do, i spent some time doing this for you. i'm logical that way.)
      the basic idea is that you have a windowing function, in this case a gaussian/bell curve, and you read through it, pausing at the maximum if your buffer is long enough.
      I tried to make all the steps clear inside the patch, but let me know if you have any questions.
    • Apr 30 2009 | 9:19 pm
      hi flies
      thanks for the help, there seems to be a lot of connections in that patch that i'll have to hunt down
      i know it's pushing it a bit but is there perhaps a more elegant(read simple) way of doing this
      attached is my patch posted above
    • Apr 30 2009 | 11:19 pm
      there's surely a more elegant way of doing it.
      the difficulty is that you're complicating the problem by requiring a conditional response. Whereas before you just had to elongate the triangle to the length of the buffer, now you want to have two different kinds of responses depending on the buffer length.
      Rather than giving you a cleaner fish, i'm going to attempt to fashion a pole for you. Basically, you just break the problem down into parts and then create the parts you need and fit them together.
      i'll scheme out what you want your patch to do, and hopefully you'll how my solution works a little better, or find your own solution.
      1) determine if the buffer length L is less than the minimum M
      2.a) if yes, use old windowing procedure
      if no:
      2) create a ramp up of fixed length M/2
      3) followed by a flat region of length L-M
      4) followed by a ramp down of length M/2
      You could implement steps 2-4 in several ways. one would be to write three window segments (ramp up, flat, ramp down) and trigger them at the appropriate times (which is to say, route your index to the right function). Another would be to multiply your triangle function so that it goes up above one and then clip it at one to get a trapezoid. with a teensy bit of algebra, you could make it so that it hits one at the right place coming up and down. Since you already wrote the triangle expr i'm guessing you can do this without too much trouble.
      The way i implemented steps 2-4 is as follows: use a windowing function of length M W(x). my window is nice and smooth and fancy-pants, but a triangle works just as well. for xM/2 it ramps down, W(M/2) is exactly 1. Now, you're reading through the buffer from positions 1 to L, let the position you're reading be called i. When reading the buffer from indices 1 to M/2 (i
      just think clearly and break the problem down into parts you can solve.
      i'm sorry this is so mathematical, i'm in the middle of writing a paper on mathematical ecology.
    • May 01 2009 | 6:09 am
      hey, not sure what you mean by windowing a buffer~, storing a window into a buffer? or taking the audio stored in a buffer~, windowing it, and then writing it back into the buffer~?....
      in any case, just in case it helps, this is a pseudo-hanning window(a hanning window with variable attack-release defined in milliseconds). Doesn't require a buffer~ and is pretty simple. I came up with this because I wanted short grains to be windowed nicely, while longer beat-cutting could also be windowed(for clicks) without reducing the impact of a percussive hit, if you like this, let me know as I've just coded an external that does it all with one single object and I can pass this on to you. but if I'm completely misunderstanding what you want, i wish you the best of luck in finding the right solution for you:
    • May 03 2009 | 9:15 pm
      > I wanted to know if there's an easy way
      > performing an operation on a buffer that fades in and out?
      You could try the "fadein" and "fadeout" messages of my object buffet~.