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[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'))
		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>


More information about the Python-list mailing list