Skip to content

Commit d7d8d7d

Browse files
authored
Merge pull request #5 from nimaiji/sound-module
Sound module
2 parents 30a80aa + c970f44 commit d7d8d7d

11 files changed

+317
-0
lines changed

1980s-Casio-Piano-C5.wav

191 KB
Binary file not shown.
556 KB
Binary file not shown.

Hn.txt

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
-0.0001
2+
0.0000
3+
0.0004
4+
0.0013
5+
0.0028
6+
0.0047
7+
0.0068
8+
0.0085
9+
0.0090
10+
0.0078
11+
0.0050
12+
0.0008
13+
-0.0036
14+
-0.0067
15+
-0.0075
16+
-0.0053
17+
-0.0007
18+
0.0048
19+
0.0091
20+
0.0101
21+
0.0069
22+
0.0002
23+
-0.0077
24+
-0.0137
25+
-0.0147
26+
-0.0094
27+
0.0010
28+
0.0131
29+
0.0219
30+
0.0228
31+
0.0135
32+
-0.0043
33+
-0.0250
34+
-0.0402
35+
-0.0414
36+
-0.0229
37+
0.0158
38+
0.0692
39+
0.1265
40+
0.1748
41+
0.2024
42+
0.2024
43+
0.1748
44+
0.1265
45+
0.0692
46+
0.0158
47+
-0.0229
48+
-0.0414
49+
-0.0402
50+
-0.0250
51+
-0.0043
52+
0.0135
53+
0.0228
54+
0.0219
55+
0.0131
56+
0.0010
57+
-0.0094
58+
-0.0147
59+
-0.0137
60+
-0.0077
61+
0.0002
62+
0.0069
63+
0.0101
64+
0.0091
65+
0.0048
66+
-0.0007
67+
-0.0053
68+
-0.0075
69+
-0.0067
70+
-0.0036
71+
0.0008
72+
0.0050
73+
0.0078
74+
0.0090
75+
0.0085
76+
0.0068
77+
0.0047
78+
0.0028
79+
0.0013
80+
0.0004
81+
0.0000
82+
-0.0001

M1.wav

688 KB
Binary file not shown.

M2.wav

688 KB
Binary file not shown.

M3.wav

688 KB
Binary file not shown.

main.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from sound import Noise,Hn
2+
#
3+
# s1 = Noise(path='./M1.wav', name='M1')
4+
# s1.draw()
5+
# s1.draw_fft()
6+
#
7+
# s2 = Noise(path='./M2.wav', name='M2')
8+
# s2.draw()
9+
# s2.draw_fft()
10+
# #
11+
# s3 = Noise(path='./M3.wav', name='M3')
12+
# s3.draw()
13+
# s3.draw()
14+
# s3.hear_noise()
15+
# print(s3.when_max())
16+
# Reading Hn
17+
# hn = Hn(path='./Hn.txt')
18+
# hn.draw()
19+
# hn.draw_phase()
20+
21+
import numpy as np
22+
23+
# conv = s3 * hn
24+
# shifted = conv.shift_right(0.001)
25+
26+
# print(conv.get_duration())
27+
# slc = conv.get_slice(float(0.2))
28+
# print(slc.get_duration())
29+
# slc_conv = slc.convolve(conv)
30+
# slc_conv.draw()
31+
32+

new_sound_draw.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import matplotlib.pyplot as plt
2+
3+
from scipy.io import wavfile
4+
5+
samplerate,date = wavfile.read('1980s-Casio-Piano-C5.wav','r')
6+
print(samplerate)

sampleSound.py

Whitespace-only changes.

sound.py

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import matplotlib.pyplot as plt
2+
import numpy as np
3+
from IPython.lib.display import Audio
4+
from scipy.io import wavfile
5+
from scipy.fftpack import fft, fftfreq
6+
import logging
7+
from tempfile import mkdtemp
8+
import os.path as path
9+
import sys
10+
11+
logging.basicConfig(level=logging.DEBUG, filename='app.log', filemode='w',
12+
format='%(levelname)s - %(name)s: %(message)s')
13+
14+
class Hn:
15+
def __init__(self, **kwargs):
16+
self.data = []
17+
self.name = 'H[n]'
18+
self.path = None
19+
self.points = [[], []]
20+
if kwargs['path'] != '':
21+
self.path = kwargs['path']
22+
file = open(self.path, 'r')
23+
for line in file:
24+
self.data += [float(line)]
25+
elif kwargs['data']:
26+
self.data = kwargs['data']
27+
elif kwargs['path'] != '' and kwargs['data']:
28+
logging.debug('please insert a path or array of data')
29+
raise AttributeError('please insert a path or array of data')
30+
else:
31+
logging.debug('please insert a path or array of data')
32+
raise AttributeError('please insert a path or array of data')
33+
logging.info('Hn = {}'.format(str(self.data)))
34+
35+
for i in range(len(self.data)):
36+
self.points[0] += [i]
37+
self.points[1] += [self.data[i]]
38+
39+
def draw(self):
40+
plt.title(self.name)
41+
plt.plot(self.points[0], self.points[1])
42+
plt.xlabel('Time (s)')
43+
plt.ylabel('Amplitude')
44+
plt.savefig('{}'.format(self.name))
45+
plt.grid(True)
46+
plt.show()
47+
48+
def draw_phase(self):
49+
plt.title(self.name + 'Phase spectrum')
50+
plt.phase_spectrum(self.points[1])
51+
plt.savefig('{} Phase spectrum'.format(self.name))
52+
plt.grid(True)
53+
plt.show()
54+
55+
def __str__(self):
56+
return self.data
57+
58+
59+
class Noise:
60+
def __init__(self, **kwargs):
61+
self.data = []
62+
self.sample_rate = 0
63+
self.fft = []
64+
self.frame = 0
65+
self.path = None
66+
67+
if kwargs['path']:
68+
self.path = kwargs['path']
69+
self.parse_wav()
70+
elif kwargs['data'] is not None:
71+
self.data = kwargs['data']
72+
self.sample_rate = 32000
73+
logging.info('noise data = {}'.format(self.data))
74+
elif kwargs['path'] != '' and kwargs['data']:
75+
logging.debug('please insert a path or array of data')
76+
raise AttributeError('please insert a path or array of data')
77+
else:
78+
logging.debug('please insert a path or array of data')
79+
raise AttributeError('please insert a path or array of data')
80+
81+
try:
82+
self.name = kwargs['name']
83+
except:
84+
self.name = 'Unknown' if self.path is None else self.path
85+
86+
logging.info('{} noise created.'.format(self.name))
87+
88+
def parse_wav(self):
89+
sample_rate, data = wavfile.read(self.path, 'r')
90+
self.data = data
91+
self.sample_rate = sample_rate
92+
logging.info('noise sample rate = {}'.format(self.sample_rate))
93+
logging.info('noise data = {}'.format(self.data))
94+
return self.data
95+
96+
def init_fft(self):
97+
self.fft = fft(self.data)
98+
99+
def get_fft(self):
100+
self.init_fft()
101+
return self.fft
102+
103+
def get_energy(self):
104+
return np.sum((np.abs(self.data) ** 2)) / len(self.data)
105+
106+
def get_duration(self):
107+
return len(self.data) / float(self.sample_rate)
108+
109+
def get_slice(self, slc):
110+
length = len(self.data)
111+
mul = (slc / self.get_duration()) * length
112+
index = int(mul)
113+
return Noise(name='{}s of {}'.format(slc, self.name), data=self.data[0:index], path='')
114+
115+
def get_max(self):
116+
return np.amax(self.data)
117+
118+
def when_max(self):
119+
length = len(self.data)
120+
index = np.where(self.data == self.get_max())
121+
when = ((index[0] * self.get_duration()) / length)[0]
122+
logging.info('{} at {}s is max'.format(self.name, when))
123+
return when
124+
125+
def shift_right(self, slc):
126+
if slc < 0:
127+
return self.shift_left(abs(slc))
128+
amount = int(slc * self.sample_rate)
129+
filename = path.join(mkdtemp(), 'newfile.dat')
130+
fpath = np.memmap(filename, dtype='float64', mode='w+', shape=len(self.data))
131+
fpath[amount:] = self.data[:-amount]
132+
logging.info('{} {} shifted right'.format(self.name, amount))
133+
return Noise(name='{} time shifted right {}'.format(amount, self.name),
134+
data=fpath, path='')
135+
136+
def shift_left(self, slc):
137+
if slc < 0:
138+
return self.shift_right(abs(slc))
139+
amount = int(slc * self.sample_rate)
140+
filename = path.join(mkdtemp(), 'newfile.dat')
141+
fpath = np.memmap(filename, dtype='float64', mode='w+', shape=len(self.data))
142+
fpath[:-amount] = self.data[amount:]
143+
logging.info('{} {} shifted left'.format(self.name, amount))
144+
return Noise(name='{} time shifted left {}'.format(amount, self.name),
145+
data=fpath, path='')
146+
147+
def reverse(self):
148+
self.data = [ele for ele in reversed(self.data)]
149+
150+
def draw(self):
151+
plt.figure(self.name, figsize=(12, 5))
152+
plt.title(self.name + ' Noise')
153+
time = np.arange(0, self.get_duration(), 1 / self.sample_rate) # time vector
154+
plt.plot(time, self.data)
155+
plt.xlabel('Time (s)')
156+
plt.ylabel('Amplitude')
157+
plt.grid(True)
158+
plt.show()
159+
160+
def draw_fft(self):
161+
self.init_fft()
162+
plt.figure(self.name + ' FFT')
163+
plt.plot(self.fft)
164+
plt.xlim([10, self.sample_rate / 2])
165+
plt.xscale('log')
166+
plt.grid(True)
167+
plt.xlabel('Frequency (Hz)')
168+
plt.show()
169+
170+
def draw_all(self):
171+
plt.figure(self.name)
172+
plt.plot(self.data)
173+
plt.grid(True)
174+
plt.figure(self.name + ' FFT')
175+
plt.plot(self.fft)
176+
plt.xlim([10, self.sample_rate / 2])
177+
plt.xscale('log')
178+
plt.grid(True)
179+
plt.xlabel('Frequency (Hz)')
180+
plt.show()
181+
182+
def draw_phase(self):
183+
plt.title(self.name + 'Phase spectrum')
184+
plt.phase_spectrum(self.data)
185+
plt.show()
186+
187+
def convolve(self, other):
188+
return Noise(name='{} * {}'.format(self.name, other.name), data=np.convolve(self.data, other.data), path='')
189+
190+
def hear_noise(self):
191+
return Audio(data=self.data, rate=self.sample_rate)
192+
193+
def __mul__(self, other):
194+
return self.convolve(other)
195+
196+
def __str__(self):
197+
return self.data

0 commit comments

Comments
 (0)