0
$\begingroup$

I’m trying to build a very basic resampling pitch shifter which reads samples from disk. I only want to change -+6 semitones without keeping the original sample length. I already have all the classes for upsampling, downsampling, FIR and interpolation. What I don’t understand is the order in which I need to use any of them because I can’t get rid of aliasing. I would appreciate if someone could fill in the blanks in terms of instructions and parameters.

My starting point: I am working with a constant buffer size of 480 samples. So if I want to change +1 semitone I can simply grab 509 samples from disk and squeeze them into the buffer using truncation. This gives me the correct pitch shift along with aliasing zipper sound. I used interpolation instead of truncation and it reduced the noise but not completely.

Where and when should I now implement up/down sampling and FIR? And what parameters are reasonable to use considering the not-so-far target pitch?

$\endgroup$
4
  • 1
    $\begingroup$ For pitch shifting consider using the Phase Vocoder. There are existing implementations in MATLAB and Python easily found online to follow the algorithm. en.wikipedia.org/wiki/Phase_vocoder $\endgroup$ Commented Jul 1, 2021 at 14:59
  • 1
    $\begingroup$ I did consider it and got the impression that for low range pitch shifting of defined sounds (I am mostly working with piano notes) it is better to use resampling. $\endgroup$
    – David912
    Commented Jul 1, 2021 at 19:01
  • 1
    $\begingroup$ Ah yes if you don't need to stream a large file I would agree. (Meaning no block boundaries) otherwise the complexity/detail in the Phase Vocoder is combining those blocks properly which comes down to how the phase is combined in the adding of the blocks (very important). If you can do it all in one block however your suggestion is bettter. $\endgroup$ Commented Jul 1, 2021 at 19:17
  • 1
    $\begingroup$ if the pitch shifter is used for guitar or some other common musical instrument, the spectrum is already pretty much low frequency content. not alot above 5 kHz. linear interpolation might not be too bad at 48 or 96 kHz sample rate. i don't expect that you're getting nasty aliases merely from linear interpolation. how are you splicing the audio? how are you determining how many samples of displacement is your splice? and the of the time duration of the splice can sometimes be either too fast or too slow. $\endgroup$ Commented Jul 2, 2021 at 4:23

1 Answer 1

2
$\begingroup$

You may be using linear interpolation (which has a relatively poor frequency response). Instead try using windowed-Sinc interpolation, with a low-pass cut-off below the lowest of the two sample rates, and make sure to properly span the filter across all block boundaries.

You may have to experiment with the width of the windowed-Sinc FIR kernel to meet your aliasing noise requirements.

$\endgroup$
5
  • $\begingroup$ So the order of actions is: grab 509 samples, use FIR filter (experiment with parameters), and then use Sinc interpolation to produce 480 samples? No up/down sampling needed? $\endgroup$
    – David912
    Commented Jul 1, 2021 at 19:07
  • 1
    $\begingroup$ A finite-window Sinc interpolator is a FIR filter that can do up/down (re)sampling. You will have to grab somewhat outside just the 509 samples to account for the filter's tails or length of impulse response. $\endgroup$
    – hotpaw2
    Commented Jul 1, 2021 at 19:16
  • $\begingroup$ Good stuff! So the algorithm is just grab over 509 samples (on both sides or just beyond 509?) and interpolate index 0-509 to produce 480 samples? $\endgroup$
    – David912
    Commented Jul 1, 2021 at 19:24
  • 1
    $\begingroup$ sounded like he's using drop-sample interpolation, which is one order worse than linear. $\endgroup$ Commented Jul 2, 2021 at 4:26
  • $\begingroup$ Yes that was my initial solution. Later I switched to JUCE based classes found here: docs.juce.com/develop/… $\endgroup$
    – David912
    Commented Jul 2, 2021 at 9:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.