|
@@ -23,15 +23,10 @@
|
23
|
23
|
|
24
|
24
|
import sys
|
25
|
25
|
import wave
|
|
26
|
+import argparse
|
26
|
27
|
from svgpathtools import svg2paths
|
27
|
28
|
|
28
|
|
-samplerate = 44100 #192000
|
29
|
|
-volume_percent = 70
|
30
|
|
-path_steps = 10
|
31
|
|
-default_duration = 5.0
|
32
|
|
-default_outfile = "out.wav"
|
33
|
|
-
|
34
|
|
-def read_image(filename):
|
|
29
|
+def read_image(filename, path_steps, volume_percent):
|
35
|
30
|
paths, attributes = svg2paths(filename)
|
36
|
31
|
path = paths[0]
|
37
|
32
|
if len(paths) > 1:
|
|
@@ -72,16 +67,25 @@ def read_image(filename):
|
72
|
67
|
p.append(v)
|
73
|
68
|
return p
|
74
|
69
|
|
|
70
|
+ def add_segment(p1, p2, f):
|
|
71
|
+ p = interpolate(p1, p2, f)
|
|
72
|
+ add_point(p)
|
|
73
|
+
|
75
|
74
|
for n in range(0, len(points) - 1):
|
76
|
|
- p1 = points[n]
|
77
|
|
- p2 = points[n + 1]
|
78
|
75
|
for step in range(0, path_steps):
|
79
|
|
- p = interpolate(p1, p2, step / path_steps)
|
80
|
|
- add_point(p)
|
81
|
|
- add_point(points[len(points) - 1])
|
|
76
|
+ add_segment(points[n], points[n + 1], step / path_steps)
|
|
77
|
+
|
|
78
|
+ #add_point(points[len(points) - 1])
|
|
79
|
+
|
|
80
|
+ for n in range(len(points) - 2, -1, -1):
|
|
81
|
+ for step in range(0, path_steps):
|
|
82
|
+ add_segment(points[n + 1], points[n], step / path_steps)
|
|
83
|
+
|
|
84
|
+ add_point(points[0])
|
|
85
|
+
|
82
|
86
|
return data
|
83
|
87
|
|
84
|
|
-def write_waveform(data, filename):
|
|
88
|
+def write_waveform(data, filename, samplerate):
|
85
|
89
|
with wave.open(filename, "w") as f:
|
86
|
90
|
f.setnchannels(2)
|
87
|
91
|
f.setsampwidth(2)
|
|
@@ -89,26 +93,31 @@ def write_waveform(data, filename):
|
89
|
93
|
f.writeframes(data)
|
90
|
94
|
|
91
|
95
|
def main():
|
92
|
|
- if len(sys.argv) <= 1:
|
93
|
|
- print("Usage:")
|
94
|
|
- print("\t" + sys.argv[0] + " image.png [out.wav] [seconds]")
|
95
|
|
- sys.exit(1)
|
96
|
|
-
|
97
|
|
- if len(sys.argv) == 3:
|
98
|
|
- duration = float(sys.argv[2])
|
99
|
|
- outfile = default_outfile
|
100
|
|
- if len(sys.argv) >= 4:
|
101
|
|
- duration = float(sys.argv[2])
|
102
|
|
- outfile = sys.argv[3]
|
103
|
|
- else:
|
104
|
|
- duration = default_duration
|
105
|
|
- outfile = default_outfile
|
106
|
|
-
|
107
|
|
- wave = read_image(sys.argv[1])
|
|
96
|
+ parser = argparse.ArgumentParser(
|
|
97
|
+ prog=sys.argv[0],
|
|
98
|
+ description='Render SVG path to vector XY audio file',
|
|
99
|
+ epilog='Made by Thomas Buck <thomas@xythobuz.de>. Licensed as GPLv3.')
|
|
100
|
+
|
|
101
|
+ parser.add_argument("input", help="Input SVG image file path.")
|
|
102
|
+ parser.add_argument("-o", "--output", dest="output", default="out.wav",
|
|
103
|
+ help="Output wav sound file path. Defaults to 'out.wav'.")
|
|
104
|
+ parser.add_argument("-t", "--time", dest="time", default=5.0, type=float,
|
|
105
|
+ help="Length of sound file in seconds. Defaults to 5s.")
|
|
106
|
+ parser.add_argument("-s", "--samplerate", dest="samplerate", default=44100, type=int,
|
|
107
|
+ help="Samplerate of output file in Hz. Defaults to 44.1kHz.")
|
|
108
|
+ parser.add_argument("-v", "--volume", dest="volume", default=100.0, type=float,
|
|
109
|
+ help="Volume of output file in percent. Defaults to 100%%.")
|
|
110
|
+ parser.add_argument("-i", "--interpolate", dest="interpolate", default=10, type=int,
|
|
111
|
+ help="Steps on interpolated paths. Defaults to 10.")
|
|
112
|
+
|
|
113
|
+ args = parser.parse_args()
|
|
114
|
+ print(args)
|
|
115
|
+
|
|
116
|
+ wave = read_image(args.input, args.interpolate, args.volume)
|
108
|
117
|
|
109
|
118
|
samplecount = int(len(wave) / 2 / 2) # stereo, int16
|
110
|
|
- drawrate = samplerate / samplecount
|
111
|
|
- drawcount = drawrate * duration
|
|
119
|
+ drawrate = args.samplerate / samplecount
|
|
120
|
+ drawcount = drawrate * args.time
|
112
|
121
|
print("len={} samples={} drawrate={:.2f} count={:.2f}".format(len(wave), samplecount, drawrate, drawcount))
|
113
|
122
|
|
114
|
123
|
data = bytearray()
|
|
@@ -116,7 +125,7 @@ def main():
|
116
|
125
|
data.extend(wave)
|
117
|
126
|
print("len={}".format(len(data)))
|
118
|
127
|
|
119
|
|
- write_waveform(bytes(data), outfile)
|
|
128
|
+ write_waveform(bytes(data), args.output, args.samplerate)
|
120
|
129
|
|
121
|
130
|
if __name__ == "__main__":
|
122
|
131
|
main()
|