How to get glitchy (Whammy pedal style) pitch shifting?
So I've been using a delay-based gen pitch shifter as my main pitch shifter and although it sounds great, it's not glitchy like a real hardware pitch shifter.
Basically the sound I'm after is the digitech whammy pedal pitch shifting. It's monophonic, but when you play it anything polyphonic it does some interesting glitching.
Jump to about 12 minutes in this video to hear what I'm talking about:
There's definitely more than just straight pitch shifting going on. Anyone seen/heard something like this built in Max?
Here's the gen-based pitch shifter I'm using:
I don't actually know much about how this works but it sounds similar to when an monophonic octaver gets a polyphonic signal. I think what happens is the pitch tracking gets confused and kind of slides between the notes because this digitech is presumably digital then you get more of a glitchy electronic effect. How to achieve this is another thing entirely.... :P
Yeah that's it, it's failing to track it, and it sounds awesome.
It's a digital effect. There's emulations of it in most of the guitar-centric plugins (guitar rig etc...), but I've never heard it outside of that context. The Guitar Rig version sounds pretty good although it does seem to have quite a bit more latency than the hardware version.
When I used pitch shifters, I was always under the impression that they actually synthesise a new signal. I'm not totally sure how it is they do the synthesis/resynthesis though. I have an octave pedal right now that can output the octave to a different amp, and the signal that comes out doesn't really sound like a guitar at all.
Interesting read.
So according to that post, the whammy is a kind of SOLA pitch shifter:
"Higher quality pitch shifters, starting with some of the Eventide models, used a technique where autocorrelation would be used to try to get a better phase match between crossfaded segments of audio, to reduce the amount of comb filtering. This sounds MUCH better, but has the side effect that the algorithm has to be tweaked to work with different types of program material - i.e. one algorithm may be optimized for monophonic signals, another for drums. Plus, as the autocorrelation can be viewed as a form of pitch detection, the complexity of the algorithm is greatly increased. This is often called SOLA (Synchronous Overlap and Add)."
"My guess is that the Whammy uses a type of SOLA, with larger grain sizes than the PSOLA algorithms. The Whammy can get warbly with certain intervals, which is found in algorithms that are trying to track the period of the signal (pitch detectors, octave dividers, etc.). However, the artifacts are not as bad as running chords into a PSOLA pitch shifter."
So if I understand right, at it's core it's a delay-based pitch shifter at work, but with some pitch detection to determine window size on the fly?
Yeah, I think so.
The idea of SOLA is that you make sure the window size is always an exact multiple of the input frequency.
That way you get continuous waves.
But I don't how to change the window size in my pitchshift patches without glitches,
but I guess Gen is perfect for that.
That one I posted above is gen-based and doesn't seem to glitch/click when you change it. Although with a whammy type sound, 'glitching' is desirable.
So would it just be a matter of having pitch detection and using that to control window size? Just need a formula for pitch to window size.
Also wondering how many delay taps would be suitable for this. (The example above is 4 delays).
Well, if you have a pitch detecter. (maybe fzero~)
I think the whammy uses more than 2 delays. That should give you more of the ringing, comb filter artefacts.
Maybe 4 or 8 is about right.
Hmm, this is getting in the ballpark. Here it is using Alex Harker's descriptorsrt~ for pitch tracking
The 'hiccup' on sound attacks is way extreme at the moment (and not in a good way), so I've got to figure out a way flatten that a bit. I'm guessing there is compression involved too, but maybe just for analysis purposes?
I tried something with [fiddle~].
I can already hear some whammy-like glitches, but it seems to me that you have to have a really stable pitch tracker. To get the least possible glitches actually.
Maybe you could make max ignore huge jumps in the frequency output of the pitch tracker.
You can also use onsets or set an amplitude threshold to gate the pitch.
You need these kind of things to get reliable results with pitch tracking.
Also you have a problem in your gen subpatch, I think.
Right now, the windowsize is updated continuously for the phasor rate, but the multiplication that comes after is only updated at the start of each phasor ramp with [sah].
I think you need to make sure you only update the phasor rate at the start of the ramp too.
So I want to just change window size when everything else is changed then? So another [sah 0] just above the phasor, but still being driven by the delta object?I did make the gen patch, I grabbed it from the 'monophonic pitch shift' thread a few months ago.
It's sounding pretty nice but most of the glitches appear to be in the attack portion rather than the sustain. I'll mess about trying to get a good pitch tracker to see how that fits, but the rub is that I don't want it to be that good, I want it to be a bad pitch tracker, but in the right way...
Here's a version that compares between fiddle~, sigmund~ and descriptorsrt~.
sigmund produces the most glitchiness, but I think descriptorsrt might sound the best, particularly with fine tuning of it's threshold. I haven't tried changing the gen subpatcher yet though. I did also include some generic compression before the pitch tracker.
I think the designers for the whammy wanted the pitch tracking to be as good as possible. But you'll always get some glitches. Especially when using polyphonic input.
I'm thinking about this grainsize update thingy. I don't know if I just offered you a solution, but I'll explain the problem. The phasor rate is related to the grainsize and ramps up from 0. to 1. Then later on this ramp gets multiplied by the grainsize. If you change the phasor rate without changing the multiplication you'll slide the pitch up or down. The phasor rate and multiplication should always be linked to keep a stable pitchshift factor. This is probably also a reason for the attack portion to glitch so much. Just for a moment the phasor and the duration are not linked, 'causing a short pitch slide.
That makes sense. I'm wrestling with it now, but not sure where to stick that sah in the gen. It won't let me connect it above the phasor, which is where it seems to want to go (but then again, I don't know what I'm (gen) doing).
You can also ditch the sah for the multiplications.
Maybe that's even better.
I was excited for a second as that would be easier. But that turns gen into a clicking machine...
What it is is the old 'old refresh phasor at 0 crossing' problem. Outside of gen I know how to do that (only recently) by using tapin/tapout, but it uses a click~ to get it started. No clue on doing that in gen.
Hey, Rodrigo, here's what I've come up with. Although, I think the pitch tracker doesn't change the sound very much, just a little. The windowsize isn't updated with sah here, but runs continuously. It's just smoothed with line~.
Save this like poly4whammy:
And this is the main patcher
Sounds good. Quite different, engine wise, from the other one. Lots of bits to play with though. For my money sigmund produced the best sounding 'glitches'. Fiddle was too many glitches and descriptorsrt seemed to 'vibrato' more.
Ah, nevermind. I forgot about the midi to frequency conversion in the pitch tracker. Now it sounds bad again. Let us know when you get it working. I'll give up for now.
Thanks a ton for your help in this, I think its 90% of the way there, and sounds great and usable already.
(I've incorporated the last version I posted using sigmund~ into my main performance patch).
So lately I've been trying to get a cleaner 'bypass' signal out of this patch. As in, when there is zero transposition, but the effect is still on. It seems to vary wildly in terms of cleanliness depending on what direction you come from and how long you leave it running. It's most obvious with a drum loop as you can hear phase and flamming more readily.
I tried messing with the multiplier but nothing useful.
Has anyone managed a 'clean' zero transposition pitch shifter?
Hi Rodrigo
have you tried Timo's grainstretch~ external; mighty smooth and clean. He maintains that all parameter changes are smooth, suggesting perhaps a sah workaround - as an external it's closed and unhackable, but it is based on Kneppers' granular stretching algorithm (poly subpatch below) which uses a n algorithm I'm not 100% clear about, but appears to avoid the use of sah, while still allowing click-free AND smooth parameter changes; maybe you could hack?
HTH
Brendan
edit
yeah, I thought it might be too good to be true - Kneppers' example uses the CNMAT pitch~ external. Sigh.
Well for this particular application, 'smooth' is not desirable. Part of the sound of the whammy style pitch shifting is the glitch-ness in tracking when it changes the window while tracking. That I want to keep, and granular pitch shifting would lose that, and be 'smooth'. The thing that I'm losing is when I fade to zero transposition it still sounds 'delay-y', due to the add/overlap transposition. That's what I want to reduce/minimize.
[note to self]
read entire thread, including topic title !
Hehe. It's is a peculiar type of shifting, but I think it sounds great.
So it looks like what's causing the weird problems at zero transposition was that the phasor inside gen completely stops when it's at zero transposition, so it doesn't update windows or do anything, leaving whatever flammy thing was happening. Window changes don't do anything while this is happening too.
I guess the lack of window changes while at zero transposition is desirable, but it would be nice if the window could be set to something agreeable for a more natural non transposed sound. I found 80ms sounds ok enough for this.
Now I can solve this problem in max, but since everything is gen, it would be ideal if it happened with sample accuracy too, but I don't know gen enough to apply logic/conditional/bang.
Basically when phasor speed = 0., the window size should be reset to a set value. I can do the 'if' bit, but not sure how to 'bang' the window size in gen.
The phasor does indeed stop at zero transposition. But you have to reset the phase of the phasor to zero.
You can see this in the transposer patch in the examples folder.
Mine is literally the same thing (back from when that gen patch was posted in the forum). The example version doesn't reset the phasor either.
the cheap hack in me is thinking "why not just add 0.00000000001 to that zero to make it non-zero?", but I'm sure you've already been down such desperate avenues.
I thought about doing that, but figured if it's gone so far, why not do it 'right'. Just sucks when you don't know what right is!
Also that wouldn't reset the phasor, just keep it moving where it was at, which is better than nothing, but not ideal.
the whammy is a granular pitch shifter with a feedback loop.
from what i have understood.
Hmm. It sounds like add/overlap stuff, as it's more jumpy/jittery than grainy/smooth, but I don't really know the sound of pitch shifting algorithms that well. All I know is that the code above sounds pretty damn close.
I seem to recall reading a paper some time back to the effect that it's using the time-domain pitch-synchronous overlap-add (TD-PSOLA) technique. There are plenty of hits on Google if you do a search.
Hope this helps.
This came up. I'll give it a look through when I'm not about to go to bed.
There's also this: http://dsp-book.narod.ru/Pitch_shifting.pdf
hey rodrigo, have you tried to add a feedback to your patch? take the output from your gen~ and put it in his input, use a very low value for the feedback such as 0.1 or 0.01, or put a limiter in the feedback loop. i think you will be satisfied. the main difference between add/overlap and granular is just synchronous vs asynchronous but it is in fact granular also the first case.
I have not, but I'll give it a try.
I finally got around to trying feedback and couldn't really notice too much of a difference with feedback. I only really noticed something happening when I really cranked the feedback. Maybe that's working as intended and just tracks a bit better.
I didn't try it with a live instrument input so I can't comment on how it 'feels', but with an assortment of files, it was hard to tell the difference.
I also messed around with the 'phasor at 0' problem.
A bit of logic now makes it so the phasor is never at zero:
But, this still leaves the phasor suuuper slow, which means no window changes work until phasor wraps around zero.
I tried resetting the phase of phasor whenever a new window values come in, but since it's audio rate stuff, it means I was resetting the phasor every sample, which is equally useless.
I guess I need the equivalent of a 'bang' in the gen world. Basically, how can I reset the phasor's phase ONLY when a new 'window' value comes in?
Here's the whole patch (with feedback in there now too).
Aha!
Figured it out.
Phasor gets reset with any non zero value, meaning when it's being fed a zero, it won't reset. So taking a [change] from the window param resets the phasor when a new window is set, and the +0.00001 logic means the phasor never stops anyways.
Super sweet.
Ugh, nevermind...
Resetting the phasor on window changes clicks like a mothertrucker.....
So unless there's something I'm overlooking, is it impossible to have a really slow phasor but being able to change the window size, without clicking?