gen issue clarified and restated

    Feb 17 2013 | 4:28 pm
    perhaps a double post; but then again perhaps not, I think clarification and simplification is needed - it always helps.
    I now understand how and when to correctly implement a sah operation inside gen. But, the use of a delay offset appears to be messing up my timing for control signals to sah. If you have used gen successfully in your work, or have a deeper understanding of audio DSP than I, please have a look at the tiny example patch below, and thanks. No matter what algorithm I use, it always comes down to "no pitch modulation" or "no clicks" never both }: (
    thinking of changing my handle from n00bmeister to genSlave....

    • Feb 18 2013 | 1:05 pm
      ...fwiw, bypassing the sah (size into *0.5 into mstosamps) appears to place the discontinuities at the top of the window; returning to sah places them at the bottom...? I realize that scope~ is ill-suited to observing stuff at the sample level though.
    • Feb 19 2013 | 12:23 am
      Hi - I'm definitely no gen expert but I took a stab at it as a learning exercise. I ended up duplicating the unshifted voice to see what the differences were. I could be wrong but it seems like using the same sah for both phase-shifted and unshifted ramps is where the clicks and the pitch problems lie... maybe this will be helpful!
    • Feb 19 2013 | 8:26 am
      Hi David
      thanks for taking a look at this - this appears to work exactly as I need. You've saved me many sleepless nights mate, cheers, I've really been stuck on this for weeks,
      all the best
    • Feb 19 2013 | 3:26 pm
      Still some overlap problems though, the phase shift is now tied to both ramp duration and mute duration, it should just be a function of ramp duration; apologies for not being clearer, but I'll try your suggestion and see if I can tweak it
      thanks again
      that may have sounded dismissive, apologies. What I found is that the trick of changing the min/max values of the second [accum] object is clever, but that offset is fixed or rigid. What I hope to do is allow that offset to always be 50% of grain ramp size, irrespective of interonset value. I'll hack away at this today and return later.
      Thanks again mate
    • Feb 19 2013 | 4:33 pm
      Didn't find that to be dismissive at all!
      I realized this am that the min max values was a problem. If both the accums were reset at the same time the phase relationship would change.
      Changing the accum to a + .05 -> modulo 1. works, and you can reference the unshifted ramp from it's output. (or from the mute ramp which is resetting the 'phase' of the main ramp).
      Hope this helps! it seems like its on the right track anyway..
    • Feb 19 2013 | 6:08 pm
      Hi David, yes, % is another solution. Sadly, as I was putting together an annotated description of the issue as I see it and my anticipated goal, I revealed a fundamental flaw in the algorithm I'm using (mine, not leafcutter's or Peter's or etc) - it is that, when using a central phasor to drive everything in this way, pitch modulation in the shifted grain is unavoidable. Unavoidable. The patch below demonstrates this:
      Thanks for your input everyone; apologies for not clarifying this before posting :(
      Depressed. Whiskey. Failed PhD
    • Feb 19 2013 | 6:46 pm
      maybe stick to just the whiskey!
      man i don't know if im fundamentally missing something, or just not hearing the artifacts, but I tried just duplicating the entire voice with ONLY the + modulo shift and it seems to be ok. If that works, maybe u could just make an unshifted voice and poly~ that with only the + object changing.
      here u go:
    • Feb 19 2013 | 7:16 pm
      :( that one just doesn't work, but shouldn't it? giving up for now...
    • Feb 19 2013 | 8:20 pm
      Hey thanks for taking part - some welcome insights!
      As I demonstrated above, pitch modulation in the shifted window is unavoidable in a simple MSP version - the frequency calculation is done at the inlet to phasor ONLY, and that ramp is then shifted, so there's no opportunity to sah the offset freq via the new ramp. I think.
      Compromise. It is only rapid fluctuation in ramp duration signal that exhibits clicks in the shifted window (pitch mod here is sorted); so I just threw a lowpass filter at the signal input. Do rightly!
    • Feb 19 2013 | 9:25 pm
      Not sure if/why you are avoiding gen~ but I think this may do what you need?
      Don't let the duration hit 0 or it will stall!
      This is quite a fun patch:
    • Feb 19 2013 | 10:10 pm
      hi leafcutter
      I have definitely caught the gen~ bug, thanks to you!
      The patch at the top of this thread should describe the following: I'm shifting the mutable phasor to generate an overlap fixed at 50% of the ramp duration, regardless of mute duration, this much is done. The problem presents itself as clicks or pitch mod in the shifted grain (no such artefacts in the unshifted grain). I've tried every combination of sah and history, triggered by both/either ramp to no avail.
      I'm looking forward to deciphering your new patches (in the morning) and I'm hoping, with the info already given by yourself, David, Peter and Graham
      that I can finally put this to bed.
      Lessons learned:
      [1] don't split one problem between two threads
      [2] define the problem in the simple terms possible
      [3] buy every single book on music-and-maths
      Best regards
    • Feb 19 2013 | 10:26 pm
      Ok, I may have slightly misunderstood your question. Still I'm enjoying playing with my second patch!
    • Feb 19 2013 | 10:51 pm
      Do you think the first patch in your example above be easier to adapt to my stated needs? I'm always going to run into the problem of unwanted pitch modulation when varying the frequency of a shifted ramp. This much is clear. And the only solution to that problem is to use two phasors, as in David's suggestion above, but that still leaves me with the challenge of correct application of sah and feedback triggers.
      Thanks also for the demonstration patch using [sample]. I guess ultimately I'd like to run as much of this inside gen~ as possible, to avoid timing issues between gen~ and MSP vector size.
    • Feb 21 2013 | 7:29 am
      I was thinking about this some more, and it occurred to me there's another problem. Say there are two ramps A & B which are 50% out of phase. Avoiding pitch wobbles is done by only sampling the duration at the start (or end) of the ramp. But if the duration changes between when A starts and when B starts, then they might drift out of 50% phase with each other. Or if B is always slaved to A, then B might get the pitch wobble/spike problem.
      So I figured a solution would be that B only starts (and samples the duration input) when A passes 50% phase, and A only starts (and samples the duration input) when B passes 50% phase. They effectively ping-pong each other, with neither master or slave (which appeals to my sense of balance). A & B end up looking pretty much the same, and there'll be a history feedback going each way between them.
      I'm on a cellphone currently so I can't patch this up now, but I suspect this could be the solution you're looking for.
    • Feb 21 2013 | 11:19 am
      Hi Graham
      you have precisely described the problem I have been struggling to even vaguely communicate: in a master-slave algorithm, with the sah storing the frequency value of the master, the slave will exhibit unwanted pitch variation during frequency changes. [+ 0.5]--->[% 1] is the usual phase-shift trick, but as I am using an interonset signal as well, it seems that [delay] (and gen~) is my only recourse - which is where my woes begin. If you can be arsed tracing this thread, Peter McCulloch provided a solution to the clicks, and David Stevens also provided one solution. And I'm hoping that the original author of the gen code (leafcutter) is also scratching his head over this one.
    • Feb 21 2013 | 12:01 pm
      Allow me to approach this problem from a completely different angle.
      This idea is based on a grain-generator triggered by pulse, which, when busy, hands this pulse to the next instance. Generating pulses at a rate of 250 ms and setting grain duration to 500 ms will automatically create two grains out of sync by half the grain size. Does this work for you?
    • Feb 21 2013 | 1:11 pm
      This works pretty well there are still a few things to iron out but I got to get on with my own work now!
    • Feb 21 2013 | 7:17 pm
      a new approach to a stagnant problem is always welcome; I had thought of train~ in the early stages of this project and I knew gen~ would have to be involved which is why I didn't go there (gen~ n00bness). I'll have to ensure that I completely understand how/why your patch is doing specific things before I try to dissect and adapt it - thanks
      this does work better than my/our previous efforts - David's adaptation of your original works well too, via + 0.5 ---> % 1.
      Clicks persist though. I'm going to use the most stable iteration of your original and then polyphonize it instead of shifting and shifting and headaches and headaches. I need to move forward too ;)
    • Feb 21 2013 | 7:40 pm
      Hi again - I haven't had time to look @ the other patches posted but i *think* I've managed to get a clickless and immutably shifted cycle going.
      Part of the problem (in this version anyway) was that changing the mute amount caused the mute ramp to retrigger only when the change was happening from 0-1 but not if changing from large to small (i.e.. 1 to 0). This is where the clicks happened...
      I'm not sure how to implement the play~ portion and I'm running out the door but here's what I have so far.
      Sorry if this has been covered in previous posts
    • Feb 21 2013 | 10:57 pm
      your input has been invaluable and I really appreciate your work on this. I have something REALLY nice here now and I'll investigate your latest patch to see if it surpasses your other excellent suggestions. If so, it will make this granulator I'm working on even sexier.
      Guys, i consider myself the average Maxer, and I've been sweating over this problem for at least a week now, so I appreciate that solutions aren't just assembled in ten minutes, so thanks everyone - citations logged!!
    • Feb 21 2013 | 11:00 pm
      ps reading my previous entry, does "gen + n00bness" = "g00bness"