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
How to Get a Random Number Between a Float Range
Multiprocessing: Sharing a Large Read-Only Object Between Processes
Importing an Ipynb File from Another Ipynb File
Find and Replace String Values in List
How to Verify If One List Is a Subset of Another
Python String Prints as [U'String']
How to Sandbox Python in Pure Python
Find_Element_By_* Commands Are Deprecated in Selenium
Numpy Array Assignment with Copy
Windows Cmd Encoding Change Causes Python Crash
Attributeerror: Module 'Time' Has No Attribute 'Clock' in Python 3.8
Selenium Compound Class Names Not Permitted