I am attempting to create a pitch correction algorithm. I started by performing a test. The test goes as such:
- Get WAV file
- Split it into bins of size n (512 in my case)
- Shift each bin by 2 semitones (using a high level pitch shifting algorithm)
- Aggregate all shifted bins together to recreate audio file
However, when I do this, a large amount of noise relative to the size of "n" is generated (spectral leakage maybe?) The smaller the size n, the larger the amount of noise
How do I implement the pitch shifting on a bin by bin basis while minimizing the noise, and how should I adjust for the phase shifting that the individual pitch shifts create?
Audio clips and code here (last clip in notebook is the one with all the added noise): https://colab.research.google.com/drive/1cpRhPpvXY_9XZidjOLKk_wW15EnkqLEX?usp=sharing
My code that attempted to fix the problem, but failed:
def win_taper(N, a):
R = int(N * a / 2)
r = np.arange(0, R) / float(R)
win = np.r_[r, np.ones(N - 2*R), r[::-1]]
stride = N - R - 1
return win, stride
def pshift(key, x, f, G, overlap=0):
notes = frequencies(key)
N = len(x)
y = np.zeros(N)
win, stride = win_taper(G, overlap)
for n in range(0, len(x) - G, stride):
w = manipulate(x[n:n+G] * win, sr, f)
y[n:n+G] += w
return y
Tapered function taken from here: https://lcav.gitbook.io/dsp-labs/granular-synthesis/effect_description