Page 1 of 1
Pitch Snapping
Posted: Fri Feb 27, 2015 8:04 am
by Perfect Human Interface
Sometimes I get to checking back here regularly and I get a little bummed that there often aren't many new posts to look at. But thankfully, I can always come up with questions to ask.
Current problem to figure out is pitch snapping. This is taking a raw frequency value and adjusting it to the nearest note pitch at sample rate. First thing's first, I need to figure out the nearest note pitch based on the input. Then I can work out any more complex behaviors.
So how do we do that? Just do some maths to convert to a linear, integer-based standard like MIDI note numbers, do a little roundint, then convert back from MIDI to Hz. No problem.

- MIDI to Freq.PNG (3.45 KiB) Viewed 15956 times
...obviously not going to work so hot at sample rate. So how can I do this faster?
I could pile all the standard Hz values of MIDI notes into an array and start doing comparisons/sorts. But with 127 notes that could be a lot of comparisons (and no, I don't remember from high school how to calculate how expensive these operations actually are but I know they're not free), and it also doesn't account for the logarithmic scaling of note frequency values.
I know there are "fast" versions of power and log that do approximations. "Reasonably accurate" should definitely be good enough in this case. But really this efficiency stuff is beyond me. So if anyone has some direction they could lend that would be really appreciated!
Re: Pitch Snapping
Posted: Fri Feb 27, 2015 7:32 pm
by martinvicanek
There is a pitch manager post
here. The schematic has a pitch quantizer that may give you some inspiration.
Optimized pith/frequency converters can be found in the
stream functions pack at flowstone guru. You don't need to update the pitch at sample rate, I have found hop(32) sufficient.
Hope that helps!
Re: Pitch Snapping
Posted: Fri Feb 27, 2015 11:11 pm
by tulamide
martinvicanek wrote:I have found hop(32) sufficient.
If this was pitching audio generated from midi, would it be sufficient to just calculate once per midi note, using that result until next note?
If this was just pitching any audio, would it be sufficient to calculate once? Assume a voice recording and 440 Hz should be pitched to 493.88 Hz (A4 to B4), would it be sufficient to calculate both at the beginning, then never again?
Re: Pitch Snapping
Posted: Sat Feb 28, 2015 12:22 am
by Perfect Human Interface
martinvicanek wrote:You don't need to update the pitch at sample rate, I have found hop(32) sufficient.
Actually yeah, I'm not sure why these things don't occur to me.

These forums and you folks are a godsend. If this place ever properly died I wouldn't be able to use Flowstone at all haha.
I will definitely check out the stream functions stuff, and I'm of course quite familiar with your pitch manager work, although I assumed quantizing to specific notes would be different from finding the nearest notes. Thanks!
tulamide wrote:If this was pitching audio generated from midi, would it be sufficient to just calculate once per midi note, using that result until next note?
If this was just pitching any audio, would it be sufficient to calculate once? Assume a voice recording and 440 Hz should be pitched to 493.88 Hz (A4 to B4), would it be sufficient to calculate both at the beginning, then never again?
If you're using MIDI, you already have your pitch data built in there so I don't see the need to do any detection and analysis.
If you mean audio from another plugin triggered by MIDI, then A) your Flowstone plugin wouldn't know if it were MIDI triggered or not, B) it would entirely depend on the kind of output (the pitch may not be static, MIDI triggered or not), and C) you can't know the actual note on and off points so "beginning" and "end" are abstractions unavailable to you in your design.
Re: Pitch Snapping
Posted: Sat Feb 28, 2015 1:52 am
by RJHollins
... and from a previous thread ....
a Shout out to Uncle Martin !

Re: Pitch Snapping
Posted: Tue Mar 03, 2015 11:22 pm
by Perfect Human Interface
So Martin's fast stream functions worked easy-peasy as shown here.

- Snap.PNG (27.18 KiB) Viewed 15870 times
But I also wanted to try a hop as suggested. Unfortunately I don't know a lick of ASM so pic above also shows how far I got with that.
Is this just a matter of pasting this stuff in the right places or is it more complicated than that? Haha
Re: Pitch Snapping
Posted: Sat Mar 07, 2015 12:43 am
by KG_is_back
Perfect Human Interface wrote:But I also wanted to try a hop as suggested. Unfortunately I don't know a lick of ASM so pic above also shows how far I got with that.
Is this just a matter of pasting this stuff in the right places or is it more complicated than that? Haha
In this particular case it is as simple as that. Copy the code between "jnz end0;" and "end0:"
Also make sure that there is no "end0:" in the original code, or there will be doubled label and code will crash (to prevent it, simply rename it).
To explain how hop works:
Code: Select all
mov eax,ecx; //copy ecx to eax register
// ecx holds the index of the sample (each sample it increases by 1 )
and eax,7; //this is basically eax % 8 (a binary trick for fast modulo of powers of two)
cmp eax,0; //compare with zero
jnz end0; //if the result was not equal, jump to "end0:"
//here should be the code you want to hop
end0: //this label marks the spot, where the (to be) hopped code ends.
Theoretically it should work as expected, except for obvious reasons when using code in hop (for example filters will be messed up if used in hop)
Re: Pitch Snapping
Posted: Sat Mar 07, 2015 11:41 am
by Perfect Human Interface
Thanks KG! One more thing for the meager bag o' tricks.
