问题
I have to read the data from just one channel in a stereo wave file in Python. For this I tried it with scipy.io:
import scipy.io.wavfile as wf
import numpy
def read(path):
data = wf.read(path)
for frame in data[1]:
data = numpy.append(data, frame[0])
return data
But this code is very slow, especially if I have to work with longer files. So does anybody know a faster way to do this? I thought about the standard wave module by using wave.readframes(), but how are the frames stored there?
回答1:
scipy.io.wavfile.read returns the tuple (rate, data)
. If the file is stereo, data
is a numpy array with shape (nsamples, 2)
. To get a specific channel, use a slice of data
. For example,
rate, data = wavfile.read(path)
# data0 is the data from channel 0.
data0 = data[:, 0]
回答2:
The wave
module returns the frames as a string of bytes, which can be converted to numbers with the struct
module. For instance:
def oneChannel(fname, chanIdx):
""" list with specified channel's data from multichannel wave with 16-bit data """
f = wave.open(fname, 'rb')
chans = f.getnchannels()
samps = f.getnframes()
sampwidth = f.getsampwidth()
assert sampwidth == 2
s = f.readframes(samps) #read the all the samples from the file into a byte string
f.close()
unpstr = '<{0}h'.format(samps*chans) #little-endian 16-bit samples
x = list(struct.unpack(unpstr, s)) #convert the byte string into a list of ints
return x[chanIdx::chans] #return the desired channel
If your WAV file has some other sample size, you can use the (uglier) function in another answer I wrote here.
I've never used scipy
's wavfile
function so I can't compare speed, but the wave
and struct
approach I use here has always worked for me.
回答3:
rate, audio = wavfile.read(path)
audio = np.mean(audio, axis=1)
来源:https://stackoverflow.com/questions/23154400/read-the-data-of-a-single-channel-from-a-stereo-wave-file-in-python