-
Notifications
You must be signed in to change notification settings - Fork 0
/
Auto.py
56 lines (44 loc) · 1.85 KB
/
Auto.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import librosa
import Notes
import numpy as np
class Autotune:
def __init__(self, y, sr, scale):
self.INPUT_WAVE = y
self.INPUT_SR = sr
self.SCALE = scale
self._note = Notes.Notes(scale)
self.NOTES = self._note.getScale()
self.OUTPUT_WAVE = np.empty(shape=self.INPUT_WAVE.shape)
def correct(self):
step = int(self.INPUT_SR/8)
print('Detected fq\tCorrected fq\tCorrection factor')
print('--------------------------------------------')
for x in range(0,len(self.INPUT_WAVE),step):
# find STFT
# Match to closest frequency
# transpose
# Append to self.OUTPUT_WAVE
# Return output wave
y = self.INPUT_WAVE[x:x+step]
f = self._findStft(y)
diff_array = [ np.abs(note - f) for note in self.NOTES ]
note = np.argmin(diff_array)
print(f,end='\t')
print(self.NOTES[note],end='\t')
self.OUTPUT_WAVE[x:x+step] = self._transpose(y, f, self.NOTES[note])
#self.OUTPUT_WAVE = np.concatenate(self.OUTPUT_WAVE,self._transpose(y, f, self.NOTES[note]))
print('-------------------------------------------')
return librosa.util.normalize(self.OUTPUT_WAVE)
def _findStft(self,y):
# Find stft, use argmax, find mean if req
# Return max amp frequency in the interval
yD = librosa.stft(y,n_fft=self.INPUT_SR)
arr = np.argmax(yD,axis=0)
fq = np.mean(arr)
return self._note.normalize(fq)
def _transpose(self, y, fold, fnew):
# Calculate the steps to be transposed based on the old and new frequencies.
steps = self._note.getStep(fold,fnew)
print(steps)
yT = librosa.effects.pitch_shift(y,self.INPUT_SR,steps)
return yT