|
@@ -20,49 +20,45 @@
|
20
|
20
|
|
21
|
21
|
import sys
|
22
|
22
|
import wave
|
23
|
|
-
|
24
|
|
-import pyaudio
|
25
|
|
-from PIL import Image
|
|
23
|
+from svgpathtools import svg2paths
|
26
|
24
|
|
27
|
25
|
samplerate = 44100 #192000
|
28
|
26
|
default_duration = 5.0
|
29
|
|
-
|
30
|
|
-def read_image(image):
|
31
|
|
- print("image: width={} height={} total={}".format(image.width, image.height, image.width * image.height))
|
32
|
|
-
|
33
|
|
- # resize coordinates for conversion to amplitude values
|
34
|
|
- max_len = max(image.width, image.height)
|
35
|
|
- fact = 32767 / max_len
|
36
|
|
- sw, sh = int(image.width * fact), int(image.height * fact)
|
37
|
|
- print("amplitude: width={} height={}".format(sw, sh))
|
|
27
|
+default_outfile = "out.wav"
|
|
28
|
+
|
|
29
|
+def read_image(filename):
|
|
30
|
+ paths, attributes = svg2paths(filename)
|
|
31
|
+ path = paths[0]
|
|
32
|
+ if len(paths) > 1:
|
|
33
|
+ print("WARNING: multiple paths in file. will just draw first one.")
|
|
34
|
+
|
|
35
|
+ print("paths={} segments={}".format(len(paths), len(path)))
|
|
36
|
+
|
|
37
|
+ points = [[path[0].start.real, path[0].start.imag]]
|
|
38
|
+ p_min = [points[0][0], points[0][1]]
|
|
39
|
+ p_max = [points[0][0], points[0][1]]
|
|
40
|
+ for segment in path:
|
|
41
|
+ p = [segment.end.real, segment.end.imag]
|
|
42
|
+ for i in range(0, 2):
|
|
43
|
+ if p[i] < p_min[i]:
|
|
44
|
+ p_min[i] = p[i]
|
|
45
|
+ if p[i] > p_max[i]:
|
|
46
|
+ p_max[i] = p[i]
|
|
47
|
+ points.append(p)
|
|
48
|
+ print("min={} max={}".format(p_min, p_max))
|
38
|
49
|
|
39
|
50
|
data = bytearray()
|
40
|
|
- for x in range(0, image.width):
|
41
|
|
- for y in range(0, image.height):
|
42
|
|
- if image.getpixel((x, y))[3] > 127:
|
43
|
|
- xc, yc = int((x - (image.width / 2)) * fact), int((y - (image.height / 2)) * fact)
|
44
|
|
- data.extend(yc.to_bytes(2, byteorder="little", signed=True))
|
45
|
|
- data.extend(xc.to_bytes(2, byteorder="little", signed=True))
|
|
51
|
+ for n in range(0, len(points)):
|
|
52
|
+ for i in range(0, 2):
|
|
53
|
+ v = points[n][i]
|
|
54
|
+ v -= p_min[i]
|
|
55
|
+ v /= p_max[i] - p_min[i]
|
|
56
|
+ c = int((v * 2 - 1) * (32767 / 100 * 70))
|
|
57
|
+ data.extend(c.to_bytes(2, byteorder="little", signed=True))
|
46
|
58
|
return data
|
47
|
59
|
|
48
|
|
-def play_waveform(data):
|
49
|
|
- pa = pyaudio.PyAudio()
|
50
|
|
-
|
51
|
|
- # int16
|
52
|
|
- stream = pa.open(format=pa.get_format_from_width(2),
|
53
|
|
- channels=2,
|
54
|
|
- rate=samplerate,
|
55
|
|
- output=True)
|
56
|
|
-
|
57
|
|
- stream.write(data, int(len(data) / 4), True)
|
58
|
|
-
|
59
|
|
- stream.stop_stream()
|
60
|
|
- stream.close()
|
61
|
|
-
|
62
|
|
- pa.terminate()
|
63
|
|
-
|
64
|
|
-def write_waveform(data):
|
65
|
|
- with wave.open("out.wav", "w") as f:
|
|
60
|
+def write_waveform(data, filename):
|
|
61
|
+ with wave.open(filename, "w") as f:
|
66
|
62
|
f.setnchannels(2)
|
67
|
63
|
f.setsampwidth(2)
|
68
|
64
|
f.setframerate(samplerate)
|
|
@@ -71,16 +67,20 @@ def write_waveform(data):
|
71
|
67
|
def main():
|
72
|
68
|
if len(sys.argv) <= 1:
|
73
|
69
|
print("Usage:")
|
74
|
|
- print("\t" + sys.argv[0] + " image.png [seconds]")
|
|
70
|
+ print("\t" + sys.argv[0] + " image.png [out.wav] [seconds]")
|
75
|
71
|
sys.exit(1)
|
76
|
72
|
|
77
|
|
- if len(sys.argv) >= 3:
|
|
73
|
+ if len(sys.argv) == 3:
|
|
74
|
+ duration = float(sys.argv[2])
|
|
75
|
+ outfile = default_outfile
|
|
76
|
+ if len(sys.argv) >= 4:
|
78
|
77
|
duration = float(sys.argv[2])
|
|
78
|
+ outfile = sys.argv[3]
|
79
|
79
|
else:
|
80
|
80
|
duration = default_duration
|
|
81
|
+ outfile = default_outfile
|
81
|
82
|
|
82
|
|
- with Image.open(sys.argv[1]) as image:
|
83
|
|
- wave = read_image(image)
|
|
83
|
+ wave = read_image(sys.argv[1])
|
84
|
84
|
|
85
|
85
|
samplecount = int(len(wave) / 2 / 2) # stereo, int16
|
86
|
86
|
drawrate = samplerate / samplecount
|
|
@@ -92,8 +92,7 @@ def main():
|
92
|
92
|
data.extend(wave)
|
93
|
93
|
print("len={}".format(len(data)))
|
94
|
94
|
|
95
|
|
- #play_waveform(bytes(data))
|
96
|
|
- write_waveform(bytes(data))
|
|
95
|
+ write_waveform(bytes(data), outfile)
|
97
|
96
|
|
98
|
97
|
if __name__ == "__main__":
|
99
|
98
|
main()
|