I'll start sonifying real sand grains only after I've explored all the theoretical possibilities. Have patience with me, I still have these possibilities to explore: (1) spectral components, (2) curvature and (3) mapping into "real" space using time differences between the ears of the listener and his distance from the sound source. And (4) I could use the filters of Nsound and try to map 2-D shapes into filtered white noise. Next time I'll do: (1) spectral components.
But I have sonified a few more of my test shapes:
Warning and disclaimer - These sounds could harm your sound system and could startle your pets. Turn the volume down before playing them.
I will stop exploring the X- and Y-shape components for the moment. Next time I'll try to sonify the 2-D spectral components of the shape. Just a few pictures:
The spectrum of the star shape signal: X = top, Y = bottom.
The waveform of the star shape signal: X = top, Y = bottom.
from Nsound import *
import math
debug1 = False
debug2 = False
debug3 = True
def convert_chaincode_to_x(c,x):
if c == 1 or c == 0 or c == 7: x = x + 1; return (x)
elif ( c == 2 or c == 6): x = x; return (x)
else: x = x - 1; return (x)
def convert_chaincode_to_y(c,y):
if c == 1 or c == 2 or c == 3: y = y + 1; return(y)
elif c == 4 or c == 0: y = y; return(y)
else: y = y - 1; return(y)
# read a chaincode .chc file that has been generated by SHAPE
def read_chc_file_to_xy_buffers(filename):
infile = open(filename)
instr = infile.read()
infile.close()
if debug1: print instr
# parse the input file - split it into words
inwords = instr.split(' ')
if debug1: print inwords
# delete anything except the chain code
i = 0
for str in inwords:
if str.find('0E+0') > -1 :
break
i = i + 1
inwords = inwords[i+2:len(inwords)-1]
if debug1: print inwords
# fill the x and y buffers with the chaincode values
b_x_chaincode = Buffer()
b_y_chaincode = Buffer()
x = 0; y = 0
for str in inwords:
c = int(str)
x = convert_chaincode_to_x(c,x)
b_x_chaincode << x
y = convert_chaincode_to_y(c,y)
b_y_chaincode << y
b_x_chaincode = b_x_chaincode - b_x_chaincode.getMean()
b_y_chaincode = b_y_chaincode - b_y_chaincode.getMean()
if debug2:
b_x_chaincode.plot("x value from chaincode")
Plotter.show()
b_y_chaincode.plot("y value from chaincode")
Plotter.show()
return(b_x_chaincode, b_y_chaincode)
def convert_xy_frequency(xy, minxy, maxxy, minf, maxf):
r = float(maxf - minf)/float(maxxy - minxy)
f = (xy - minxy)*r + minf
return (f)
def resample_list_frequency_duration(shape_list, list_freq, samp_freq, duration):
res_buf = Buffer()
real_duration = int(math.ceil(duration * list_freq)) / list_freq
res_len = int(math.ceil(real_duration * samp_freq))
t_samp_freq = 1.0 / samp_freq
t_list_freq = 1.0 / (list_freq * len(shape_list))
for i in range(res_len):
res_buf << shape_list[int(round(i * t_samp_freq / t_list_freq))%len(shape_list)]
return(res_buf)
# ==============================
# read file into buffers
b_x_chaincode, b_y_chaincode = read_chc_file_to_xy_buffers("C:\\Users\\user\\Documents\\shape\\shape\\04 star.chc")
# copy buffer to list so we can point to it by index
list_x = b_x_chaincode.toList()
list_y = b_y_chaincode.toList()
# generate a frequency modulated x and y signal
b_x_long = Buffer()
b_y_long = Buffer()
min_f = 40.0
max_f = 2000.0
sampling_rate = 44100.0
sound_pixel_duration = 0.01
min_x = b_x_chaincode.getMin()
max_x = b_x_chaincode.getMax()
if debug3: i=0
for x in b_x_chaincode:
frequency = convert_xy_frequency(x, min_x, max_x, min_f, max_f)
b_x_long << resample_list_frequency_duration(list_x, frequency, sampling_rate, sound_pixel_duration)
if debug3:
i = i+1
p = int(len(b_x_chaincode)/5)
if i%p == 0:
b = Buffer()
b = resample_list_frequency_duration(list_x, frequency, sampling_rate, sound_pixel_duration)
b.plot(frequency)
Plotter.show()
b_x_long.normalize()
min_y = b_y_chaincode.getMin()
max_y = b_y_chaincode.getMax()
for y in b_y_chaincode:
frequency = convert_xy_frequency(y, min_y, max_y, min_f, max_f)
b_y_long << resample_list_frequency_duration(list_y, frequency, sampling_rate, sound_pixel_duration)
b_y_long.normalize()
# code the x and y signal into the left and right channel of an audio stream
# write the audio stream into a .wav file
a = AudioStream(sampling_rate, 2)
a[0] = b_x_long
a[1] = b_y_long
a.writeWavefile("C:\\Users\\user\\Documents\\shape\\shape\\04 star xy_freq_shape2.wav")
No comments:
Post a Comment