# Drawing sound

andrea valle andrea.valle at unito.it
Sat Sep 25 09:01:42 CEST 2004

```It can be done in a lot of languages. Tipically musicDSP is in C or C++.
Anycase, as I was posting, I'm working an audio manipulation in non
real time, which seems to be your interest. It's absolutely easy.
A signal is a 1 D array (or just a list). Make the DSP math you want on
it, then write it to wave object. Works perfectly.
It's better to use numpy (or numarray), so you have a faster way to
access arrays and you gain some useful methods (convolution).

In case of drawing sound , you have to build a GUI with just a frame
and the pass values to the array.  It can mean:

a) making a sonogram and resynthesizing.Vertical axis control a bank of
oscillators, horizontal one time. Each point is a couple (time,
frequency). time is the index for the array. Here  your problem is not
Python, it's implementation of the synthesis method. You could also use
a bank of filters.
b) drawing a curve in a amplitude/time canvas. This seems really not
complex. Each point is a couple (time, amplitude). Time is the index
and amplitude the value to be set.

Then you can also:
a) use python to generate scores for Csound, i.e. control instructions
foa dedicated synthesi language (the most powerful for NRT)
b) try the csound wrapper for python in csound 5 which is experimental.
From python you invoke something like csound.perfom(). That's great.
c) use python for real time. There's hypersonic package for python but
I haven't tried yet.

Following an excerpt of my two roughly made classes SoundObject and
SoundFile using numpy.
They work in this way:

a = SoundObject(1)	 # a SoundObject of 1sec
a.sine(440)		# fill with a sine of 440Hz
f = SoundFile(a.signal)	# a SoundFile passed with the signal of a
f.write()			# write it to file

class SoundObject:

#________________________
# initialization

def __init__(self, dur):
self.dur = dur
self.sr = 44100
self.len = self.sr*self.dur
self.signal = self.create()

def create(self):
self.len = int(44100*self.dur)
signal =   zeros(self.len, Float)
return signal

def reset(self):
self.signal =   zeros(self.len, Float)

#________________________
# generators

def whiteNoise (self):
"-1,1 random"
self.signal = uniform(-1, 1, (len(self.signal),))

def sine (self, freq):
"sinusoidal wave with frequency freq"
for index in range(len(self.signal)):
sample = sin(2*pi*freq*(float(index)/44100))
self.signal[index] = sample

def impulse(self):
"a single one-sample pulse, rest 0"
self.reset()
self.signal = 1

def square (self, freq):
"square wave with frequency freq"
halfPeriod = int((1.0/freq * self.sr)/2)
firstHalf = ones(halfPeriod, Float)
secondHalf = ones(halfPeriod, Float)*-1
wave = concatenate((firstHalf, secondHalf))
signal = array([], Float)
while len(signal) <= self.len:
signal = concatenate((signal, wave))
self.signal = signal

class SoundFile:
def  __init__(self, signal):
self.file = wave.open('/test.wav', 'w')
self.signal = signal
self.sr = 44100

def write(self):
print "\nwriting to wavefile"
self.file.setparams((1, 2, self.sr, 6, 'NONE', 'noncompressed'))
self.file.writeframes(self.signal.tolist())
print "done\n"

Hope it helps.

ciao

-a-

Andrea Valle
Laboratorio multimediale "G. Quazza"
Facoltà di Scienze della Formazione
Università degli Studi di Torino
andrea.valle at unito.it

> Chris wrote:
>>
>> I want a program that can "draw" sound.
>>
>> Imagine drawing a graph of frequency against time -
>> and then being able to play it over the computer speakers.
>>
>> Can this be done in Python?
>>
>> As a start, consider this simple QBASIC program that
>> generates random frequencies:
>>
>> 10 frequency = 40 + 400 * RND
>> 20 SOUND frequency, 7
>> 30 GOTO 10
>>
>> That's fine - except that it plays over the PC speaker -
>> the one that's just there for the happy beep - and not
>> through the sound card and proper speakers.
>>
>> Can that be done in Python?
>> Or in any other language?
>> --
>> Chris
> --
> http://mail.python.org/mailman/listinfo/python-list
>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: text/enriched
Size: 4469 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20040925/e1a979d9/attachment.bin>
```