tags:

views:

56

answers:

2

i want to know how to get wav samples out of a wav file for performing windowed join of two wave files.

can any one please tell how to do this???

A: 

You can use the wave module. First you should read the metadata, such us sample size or the number of channels. Using the readframes() method, you can read samples, but only as a byte string. Based on the sample format, you have to convert them to samples using struct.unpack().

Alternatively, if you want the samples as an array of floating-point numbers, you can use SciPy's io.wavfile module.

Lukáš Lalinský
can u tell me how to get sample as an array of floatinf point numbers without using scipy
kaki
+5  A: 

The wave module of the standard library is the key: after of course import wave at the top of your code, wave.open('the.wav', 'r') returns a "wave read" object from which you can read frames with the .readframes method, which returns a string of bytes which are the samples... in whatever format the wave file has them (you can determine the two parameters relevant to decomposing frames into samples with the .getnchannels method for the number of channels, and .getsampwidth for the number of bytes per sample).

The best way to turn the string of bytes into a sequence of numeric values is with the array module, and a type of (respectively) 'B', 'H', 'L' for 1, 2, 4 bytes per sample (on a 32-bit build of Python; you can use the itemsize value of your array object to double-check this). If you have different sample widths than array can provide you, you'll need to slice up the byte string (padding each little slice appropriately with bytes worth 0) and use the struct module instead (but that's clunkier and slower, so use array instead if you can).

Alex Martelli
when i try .getsamplewidth it gave me a value 2 meaning that 2 bytes..when i try .readframes(1) should return 1 frame then it returned for me such as " /x03/x16 " which i guess is 2 bytes,so does it means that 1 frame has only 1 sample..what is use getnchannels ?? i want to take samples from each frame separetely and represent them in intergers,how can i ??
kaki
@kaki, in each frame, there is the first sample from each channel, then the second sample from each channel, then so on. So unless your sound is mono i.e. just 1 channel you have to decide what to do ith the channels (skip all but one, average them, whatever). Say it's 1 channel (mono), simplest, then `x = array.array('h', w.getframes(1))` gives you in `x` an array with all the samples of the first frame (next one, if in a loop) as integers, just as you say you want (`h`, not `H`: they're signed). If stereo, 2 channels, even indices of `x` have e.g. left channel samples. Little-endian btw.
Alex Martelli
BTW, the format docs at https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ do not use the concept of "frames" but rather "chunks" and "subchunks", but in the end it comes to much the same thing of course;-).
Alex Martelli
ya thank u very much!!...i followed the same method
kaki
@kaki, you're welcome -- but do consider accepting the answer that has helped you (by clicking on the checkmark outline on the Q's left), as that is really fundamental SO etiquette!
Alex Martelli