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.signal[0] = 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'))
		print "done\n"
  Hope it helps.



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>

More information about the Python-list mailing list