2012-03-19 4 views
2

J'ai besoin de lire les données à partir d'un fichier wav au format pcm 24 bits, et convertir en flottant. J'utilise Python 2.7.2.Un moyen plus rapide de convertir le format wav pcm 24 bits en flottant?

Le paquet d'onde lit les données sous forme de chaîne, donc ce que j'ai essayé est:

import wave 
import numpy as np 
import array 
import struct 

f = wave.open('filename.wav') 
# read in entire wav file 
wdata = f.readframes(nFrames) 
f.close() 

# unpack into signed integers and convert to float  
data = array.array('f') 
for i in range(0,nFrames*3,3): 
    data.append(float(struct.unpack('<i', '\x00'+ wdata[i:i+3])[0])) 

# normalize sample values 
data = np.array(data) 
data = data/0x800000 

Ceci est un peu plus rapide que mes approches antérieures, mais encore assez lent. Quelqu'un peut-il suggérer une méthode plus efficace?

+1

Il est clair que vous avez NumPy. Pourquoi ne pas l'utiliser tout au long? –

Répondre

1

Cela semble être assez rapide, il gère les valeurs 24 bits, et il fait la normalisation:

from scikits.audiolab import Sndfile 
import numpy as np 

f = Sndfile(fname, 'r') 
data = np.array(f.read_frames(f.nframes), dtype=np.float64) 
f.close() 
return data 
+0

Vous n'avez pas besoin de convertir en 'np.array', car' read_frames() 'retourne déjà un' np.array '. Vous pouvez même spécifier un argument 'dtype', mais sachez qu'il existe actuellement (version 0.11.0) un bug si vous utilisez un type autre que' np.float64': https://github.com/cournape/audiolab/ Problèmes/3 – Matthias

+0

'scikits.audiolab' semble ne plus être maintenu. En tant qu'alternative (très probablement aussi rapide), vous pouvez essayer [PySoundFile] (http://pysoundfile.readthedocs.org/). – Matthias

0
import sndhdr, wave, struct 
if sndhdr.what(fname)[0] != 'wav' 
    raise StandardError("file doesn't have wav header") 
try: 
    wav = wave.open(fname) 
    params = (nchannels,sampwidth,rate,nframes,comp,compname) = wav.getparams() 
    frames = wav.readframes(nframes*nchannels) 
finally: 
    wav.close() 
out = struct.unpack_from ("%dh" % nframes*nchannels, frames) 
+1

Cela convertit deux octets de données en un entier, mais les données ont une largeur de trois octets. FWIW, pour le format wav pcm avec samplewidth> 2, sndhdr reconnaît le format officiel alors que wave ne le reconnaît pas, donc une autre condition d'erreur est possible. – LMO

+0

Cela semble assez rapide: – LMO

+0

comment convertir ce 'out' dans un tableau numérique bidimensionnel? ('np.array (out)' ne donne qu'un seul tableau, donc nous ne pouvons pas traiter 2 canaux) – Basj

Questions connexes