-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathvocoder.py
74 lines (43 loc) · 1.59 KB
/
vocoder.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import numpy as np
def wrap(x):
return (x + np.pi) % (2 * np.pi) - np.pi
def encode(frames, framesize, hopsize, samplerate):
M, N = frames.shape
analysis_framesize = np.ravel(framesize)[0]
synthesis_framesize = np.ravel(framesize)[-1]
freqinc = samplerate / analysis_framesize
phaseinc = 2 * np.pi * hopsize / analysis_framesize
buffer = np.zeros(N)
data = np.zeros((M, N), complex)
for m, frame in enumerate(frames):
abs = np.abs(frame)
arg = np.angle(frame)
delta = arg - buffer
buffer = arg
i = np.arange(N)
j = wrap(delta - i * phaseinc) / phaseinc
freq = (i + j) * freqinc
data[m] = abs + 1j * freq
return data
def decode(frames, framesize, hopsize, samplerate):
M, N = frames.shape
analysis_framesize = np.ravel(framesize)[0]
synthesis_framesize = np.ravel(framesize)[-1]
freqinc = samplerate / analysis_framesize
phaseinc = 2 * np.pi * hopsize / analysis_framesize
# compensate asymmetric synthesis window by virtual time shifting #38
timeshift = 2 * np.pi * synthesis_framesize * np.arange(N) / N \
if synthesis_framesize != analysis_framesize else 0
buffer = np.zeros(N)
data = np.zeros((M, N), complex)
for m, frame in enumerate(frames):
abs = np.real(frame)
freq = np.imag(frame)
i = np.arange(N)
j = (freq - i * freqinc) / freqinc
delta = (i + j) * phaseinc
buffer += delta
arg = buffer.copy()
arg -= timeshift #38
data[m] = abs * np.exp(1j * arg)
return data