[SciPy-User] parsing a wave file
Thu Feb 23 08:08:04 CST 2012
Am 23.02.2012 um 12:04 schrieb David Hutto <firstname.lastname@example.org>:
> f = Sndfile(r'c:\Users\david\test01.wav', 'r')
Sorry for the probably dumb question, but where does "Sndfile" originate from? A quick search in the Python 2.6.5 docs and in the online scipy docs yields nothing.
> fs = f.samplerate
> nc = f.channels
> enc = f.encoding
> data = f.read_frames(1000)
> frame_amount = 1000
> data_float = f.read_frames(frame_amount, dtype=np.float32)
> for i in range(0,frame_amount,1):
> print data_float[i]
> returns data_float[i] in the form:
It looks to me as if the "Sndfile" instance already decomposes into channels. In the wave file, the channels are intermingled, one frame per channel for each time instance (I'm not fully sure if "frame" denotes the full chunk for one time instance or only one datum for one channel, part of the chunk).
> Any suggestions as to what I'm parsing in the wrong way, or better
> solutions than the above?
I could imagine that the Sndfile class you're using takes the sampling width (i.e., the number of bytes per sample) from the dtype you're handing over, interpreting the originally possible integer-valued frames as float32's. This could also alter the alignment, so that full garbage would result, possibly explaining the apparently highly variable output (as far as I can judge from the two chunks you provided). But notice, this is only guessing, speculation so to speak.
I've made positive experience with using the wave module from the standard library. I wrote a module (part of a larger sound analysis suite) to read arbitrary wave files as long as they are integer-valued. The module reads the file into a numpy array with sufficient speed (a few seconds for a 3' piece), and separates the channels. I guess it could be easily adapted to your use case (currently the channels are averaged in the end; you would just have to leave that step out). I would give it to you as a public domain module.
For the scipy.io.wavfile module, that should work too, although I don't know if it already separates the channels or not—I never used it so far.
More information about the SciPy-User