AudioResearchBlog

Covering all audio related stuff with special focus on programming and digital signal processing

Funciones para trabajar con wav’s vectorialmente en python

Posted by hordia on December 27th, 2006

A raíz de que desde hace un tiempo me puse en campaña para intentar reemplazar matlab con python (en realidad usar python para lo que hasta ahora usaba matlab) es que me vi obligado a implementar las siguientes funciones para poder trabajar con archivos wavs como si fueran vectores.

Serían las equivalentes a las funciones wavread y wavwrite de matlab.

wavread: recibe un wav y devuelve un vector normalizado entre -1 y 1, su frecuencia de muestreo y la cantidad de bits por muestra.

# Example: [ y, Fs, bits ] = wavread( 'filename' )
def wavread( name ):
	file = wave.open( name, 'r' )
	[Channels,Bytes,Fs,Frames,Compress,CompressName] = file.getparams() # (nchannels, sampwidth in bytes, sampling frequency, nframes, comptype, compname)
	Bits = Bytes*8 # 16 bits per sample
	Data = file.readframes( Frames )
	Data = fromstring( Data, Int16 ) / 32767.0 # -1..1 values, Int16 because Bits=2x8=16
	print "Fs: ",Fs,"\nBits: ",Bits,"\nChannels: ",Channels
	file.close()
	return Data, Fs, Bits
 
# Example: wavwrite( y, Fs, filename )
def wavwrite( data_array, Fs, name ):
	file = wave.open( name, 'w' )
	file.setframerate( Fs ) # sets sampling frequency
	file.setnchannels( 1 ) # sets number of channels
	file.setsampwidth( 2 ) # number of bytes: 16bits/8=2, 16 bits per sample
 
	clipped = False
	block_size = 1024*10 # write block size: 10k
	a_max = 32767 # max amp
	a_min = -32767 # min amp
	n = 0
	len_data_array = len( data_array ) # 2 bytes (int16) data
	while n < len_data_array :
		frame = '' # string frame of 'block_size'
		for i in range( block_size ) :
			if n < len_data_array :
				twodatabytes = int( data_array[n] * a_max )
				if twodatabytes > a_max or twodatabytes < a_min : clipped = True
				twodatabytes = min( max(twodatabytes,a_min), a_max ) # normalization, -32767..32767
				#twodatabytes.clip( min=a_min, max=a_max ) # normalization, -32767..32767
				frame += chr( twodatabytes & 0xFF ) # takes first byte, converts it to char and adds it to the frame
				frame += chr( (twodatabytes >> 8) & 0xFF ) # takes the second byte
				n += 1
		file.writeframes( frame )
	if clipped == True : print "Warning: Some values were clipped"
	print "Final length:", len_data_array/512,"kb" # n*2/1024 (bytes size/1024) = n/512
	file.close()

Nota: recomiendo bajar este archivo wav_array.py y no copiar directamente el código desde aca ya que debido al plugin para syntax highlight, el código puede no haber quedado correctamente indentado y tal vez no funcione bien al ser interpretado por python

Update: Aprovechando estas funciones y a manera de ejemplo también escribí el equivalente al post “Convolución circular rápida (aplicación en reverbs)” pero en python. El código es este: fast_conv.py.

Update 2: Para wavs de 8 bits ver: “Trabajar con wavs de 8 bits en python


, , , , , ,


WordPress database error: [Incorrect file format 'wp_comments']
SELECT * FROM wp_comments WHERE comment_post_ID = '83' AND comment_approved = '1' ORDER BY comment_date

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

 
Cerrar
Enviar por Correo