Reading *.Wav Files in Python

how to read multiple wav files in python, and convert to numpy arrays to plot

Looking at the scipy internals this is caused by the file signature not being understood, from the error message you get it looks like the file signature is missing (''), or there is some other issue reading data from the file:

def _read_riff_chunk(fid):
str1 = fid.read(4) # File signature
if str1 == b'RIFF':
is_big_endian = False
fmt = '<I'
elif str1 == b'RIFX':
is_big_endian = True
fmt = '>I'
else:
# There are also .wav files with "FFIR" or "XFIR" signatures?
raise ValueError("File format {}... not "
"understood.".format(repr(str1)))

I can't see any similar limitations at a glance using the python wave library so potentially try reading in using that and convert the data to a numpy array afterwards

reading wav files in all subdirectories

You need to join root with f to get proper file path using os.path.join:

for root, sub, files in os.walk(r_dir):
files = sorted(files)
for f in files:
s_rate, x = scipy.io.wavfile.read(os.path.join(root, f)) # <---
rate.append(s_rate)
data.append(x)

Sample rate and wav data contains different dimensions

Replace

ax1.plot(np.linspace(0, sample_rate/len(samples), sample_rate), samples)

with

ax1.plot(np.linspace(0, len(samples)/sample_rate, len(samples)), samples)

The sample rate is how many samples per second. If you are trying to plot all of your samples, the number of x values should be the number of samples, not the number of samples per second.

For the second change I am assuming that you are trying to make your x-axis in seconds. number of samples/number of samples per second will give you the number of seconds, not the other way around.

Read and write stereo .wav file with python + metadatas

Here is an updated version of scipy.io.wavfile that adds:

  • 24 bit .wav files support for read/write,
  • access to cue markers,
  • cue marker labels,
  • some other metadata like pitch (if defined), etc.

wavfile.py (enhanced)


Old (original) answer: a solution for only a part of the question (ie read stereo samples):

(fs, x) = read('stereo_small-file.wav')
print len(x.shape) # 1 if mono, 2 if stereo
# if stereo, x is a 2-dimensional array, so we can access both channels with :
print x[:,0]
print x[:,1]

Reading 24-Bit WAV with wavio Python 3.5

The shape of a is (num_samples, nchannels, 4) and sampwidth == 3, so that line is the same as

a[:, :, 3:] = (a[:, :, 2:3] >> 7) * 255

which is the same as

a[:, :, 3] = (a[:, :, 2] >> 7) * 255

we could devectorize the outer two loops:

for i in range(num_samples):
for j in range(nchannels):
a[i, j, 3] = (a[i, j, 2] >> 7) * 255

The dtype of a is _np.uint8, so a[...] >> 7 can only give out 0 when the value is <128, or 1 when it is ≥128, so the above becomes:

for i in range(num_samples):
for j in range(nchannels):
v = a[i, j, 2]
a[i, j, 3] = 255 if v >= 128 else 0

If the data are 24-bit little-endian integers, this is equivalent to doing a sign-extension into 32-bit.

Reading *.wav files in Python

Per the documentation, scipy.io.wavfile.read(somefile) returns a tuple of two items: the first is the sampling rate in samples per second, the second is a numpy array with all the data read from the file:

from scipy.io import wavfile
samplerate, data = wavfile.read('./output/audio.wav')


Related Topics



Leave a reply



Submit