Processing a Set of Files
There continue to be questions on the MATLAB newsgroup regarding processing a set of files. So, for the record, and even though Steve covered this topic in his blog, I thought I'd get an answer on record here as well.
Contents
Setup
I should start a clean workspace and with no WAV-files in my blog publishing directory.
clear all delete *.wav
Problem Statement
Suppose I want to convert sounds stored in MATLAB MAT-files to files saved in WAV format for Windows. Without explictly hardcoding in the filenames, here's a way to proceed.
Collect the MAT-files Containing Sounds
matfiles = dir(fullfile(matlabroot,'toolbox','matlab','audiovideo','*.mat'))
matfiles = 7x1 struct array with fields: name date bytes isdir
Check out the Files
We can see from the length of matfiles that I have 7 MAT-files. I know I don't care about the first one in this case so I am starting my analysis with the second one.
load(matfiles(2).name) whos
Name Size Bytes Class Fs 1x1 8 double array matfiles 7x1 2435 struct array y 13129x1 105032 double array Grand total is 13390 elements using 107475 bytes
Loading the data places the MAT-file contents into a structure from which I can extract the information I need and write it back out. The sound files that MATLAB ships with store the data in y and the sampling frequency in Fs. Let's look at the first signal.
N = length(y); plot((1:N)/(N*Fs),y), title(matfiles(2).name(1:end-4))
Loops over the Files
for ind = 2:length(matfiles) data = load(matfiles(ind).name); wavwrite(data.y,data.Fs,matfiles(ind).name(1:end-4)); end
Warning: Data clipped during write to file:gong Warning: Data clipped during write to file:splat Warning: Data clipped during write to file:train
What about Those Files?
dir *.wav
chirp.wav handel.wav splat.wav gong.wav laughter.wav train.wav
Read a File Back for Verification
I'll double-check the last file I just read in and wrote out. ind is still set despite no longer being in the for loop. Let's check both the frequencies and the signals themselves.
[ywav, Fswav] = wavread(matfiles(ind).name(1:end-4)); eqFreqs = isequal(Fswav, data.Fs) datadiff = norm(ywav-data.y)
eqFreqs = 1 datadiff = 0.0010
The data stored in the WAV-file is NOT exactly the same as that stored in the MAT-file. Reading the help for wavwrite gives some insight; the data in the WAV-file, by default, is stored as 16-bit data vs. MATLAB's standard 64-bit double.
Thoughts?
Does it confuse people here that I don't worry about vectorization? Any other thoughts on this topic?
Published with MATLAB® 7.2
- Category:
- Best Practice