|
|
|
|
Send Page To a Friend

|
M-Pack
1: WAV file processing: MATLAB function reference
|
| Version 1.2 |
Requires MATLAB
6.0 (R12) or later |
|
|
|
Read
a PCM WAV format audio file, either in its entirety
or chunk-by-chunk. Supports both WAVE_FORMAT_PCM and
WAVE_FORMAT_EXTENSIBLE multichannel uncompressed formats
and any bit resolution between 2 and 32 inclusive.
|
|
| File
format: |
m-file |
|
Editable
source code:
|
yes
|
| Utilises
non-editable functions: |
no |
|
Platform:
|
PC/Windows
|
| Required
MATLAB Toolboxes: |
none
(except core MATLAB) |
| Demo
version limitations: |
p-code
only (non-editable), 30 second WAV file length limit
(then silence) |
|
|
|
|
[y,fs,fdx]=wavin(filename);
|
|
[y,fs,fdx]=wavin(filename,scale,oflag); |
|
[y,fs,fdx]=wavin(filename,scale,oflag,readsize);
|
|
[y,fs,fdx]=wavin(filename,scale,oflag,readsize,skipsize);
|
|
|
|
| Inputs: |
| filename |
name of input WAV file (with optional .WAV extension)
or alternatively can be the fdx
output from a previous call to wavin
(e.g. for reading
chunk-by-chunk via successive calls).
|
| scale |
string
with value 'full', 'norm', or 'raw'. Determines the
scaling from the WAV data to the output data, as follows:
-
'full': [default] maps the WAV data on to the floating-point
range -1:+1 assuming that the WAV data has been
scaled and formatted in accordance with the established
conventions when the file was written. Type 'help
wavout' for more detail on the accepted WAV scaling
and formatting conventions. If the WAV file has
been written in a non-standard manner, the output
data may not be within the range -1:+1, and, moreover,
may be garbled. If this is the case, try using the
'norm' or 'raw' options.
- 'norm':
maps the WAV data on to the floating-point range
-1:+1, irrespective of storage format. The normalization
is applied across all channels, i.e. using a range
determined by the minimum value across all channels
and the maximum value across all channels. WARNING:
care should be exercised when using this option
in chunk-by-chunk mode since each chunk will be
individually normalised leading to non-uniform normalization
across the entire file.
- 'raw':
reads the stored WAV data verbatim without performing
any mapping. Useful in those cases when the file
has been written in a non-standard manner. Scaling
can be applied later (e.g. using wavscale)
|
| oflag |
flag
for determining whether or not to leave the file open
when exiting the function. Possible values are:
0: close on exit [default]
1:
leave open (e.g. for chunk-by-chunk reading)
|
| readsize |
maximum number of samples to read (or -1 for entire
file [default]) |
| skipsize |
number
of samples to skip from start of file when reading.
Set to -1 in order to continue from previous read when
fdx is given instead of filename [default]).
|
| Note:
either of the following input arguments: scale, and
oflag, may be substituted by [ ] to force their
respective default value(s). |
|
| Outputs: |
| y |
data
matrix of dimension: (number_of_samples * number_of_channels).
|
| fs |
[optional]
sample rate (Hz) |
| fdx |
[optional] row vector (1X10) containing the following
elements:
- file
id (obtained from the fopen command)
- current
'per channel' byte position in file (i.e. not the
actual offset which takes into account all channels).
Required for navigation when using chunk-by-chunk
write mode.
- byte
offset from start of file to start of actual data
i.e. after all headers etc. Required for navigation
when using chunk-by-chunk write mode.
- number
of samples per channel in the entire file
- number
of channels
- "container
size" (in bytes) per data value. Note: corresponding
container size in bits (= ContainerBytes/8) is always
an integer multiple of 8.
- umber
of valids bits of precision (may be less than given
container size)
- WAVE
data format. Supported values are:
-
1 -- for WAVE_FORMAT_PCM i.e. uncompressed PCM,
"old style", fine for 8-bit and 16-bit, but
ambiguous for higher bit-resolutions
- 65534
-- for WAVE_FORMAT_EXTENSIBLE i.e. uncompressed
PCM, "new style" with multichannel speaker-location
options plus no ambiguity for high bit-resolutions
(see M-Pack 1 overview
and ref [1]).
- No
other formats are supported by this m-function
- sample
rate in Hz
- the
"ChannelMask" variable (in decimal format) which
prescribes the multichannel speaker allocation for
WAVE_FORMAT_EXTENSIBLE. Type 'help
chnmsk2spkrlist'
to read more about the ChannelMask property.
|
|
|
|
|
See
the M-Pack 1 overview
for a discussion of the WAV format.
Notes:
(i)
the 'full'
scale setting ensures that amplitudes are preserved
on reading. So, for example, if the WAV file was originally
written from low-amplitude data (e.g. on the order
of 0.001, bearing in mind that the nominal floating-point
range for audio data is -1:+1), then this will be
recovered by the
wavin statement which will return correspondingly
low-amplitude values. In other words, the 'full'
scale setting when used on both the wavout
and the wavin
functions preserves the amplitude identically -- as
long as the original data lies within the -1:+1 floating-point
range.
(ii)
wavin
does not support wave-list data, nor does it read
any peripheral header information (e.g. in the '.info'
field) beyond the basic '.fmt' (audio format information).
(iii)
wavin
does not support wave-list data, nor does it read
any peripheral header information (e.g. in the '.info'
field) beyond the basic '.fmt' (audio format information).
(iv)
for WAVE_FORMAT_EXTENSIBLE files,
wavin only supports PCM storage format (i.e.
SubFormat corresponding to Microsoft GUID KSDATAFORMAT_SUBTYPE_PCM.
Ref[1]:
"Enhanced
Audio Formats For Multi-Channel Configurations And
High Bit Resolution" Windows Multimedia Group Microsoft
Corporation, 1999.
|
|
|
|
|
|
|
|
| The
first four examples demonstrate how to read WAV files
in their entirety. The
final example demonstrates how to read arbitrary portions
of a WAV file from arbitrary locations in the file (as
well as writing chunk-by-chunk with wavout).
For an example of how to read and write an
entire file chunk-by-chunk,
refer to example
10 in the wavout
help page (and in the m-script
file entitled xmplwavout.m).
See also waveffect
for an example of how to use wavin
and wavout
to create a chunk-by-chunk effects processor. |
| |
| Ex.1 |
Read
a mono WAV file named wavewarp.wav
located in
the directory ..\WAVFiles then play the
data using the sound
command (requires a Windows-compatible soundcard) |
| |
| |
[y,fs]=wavin('..\WAVfiles\wavewarp.wav'); |
| |
sound(y,fs);
%play the
mono data |
| |
|
| Ex.2 |
The
previous example used, by default, the 'full'
scale setting. This ensures that amplitudes are preserved
on reading. The resulting data range can be explored
as follows: |
| |
| |
>>
[min(y) max(y)] |
| |
ans
= -0.9818 0.8780 |
| |
|
| |
The
fact that the range is smaller than -1:+1 shows that,
in this example, the data does not take up the full
range available (perhaps intentionally!). In any case,
by using the 'norm' scale setting, the wavin function
will automatically normalize the data to take up the
entire available range: |
| |
|
| |
[y,fs]=wavin('..\WAVfiles\wavewarp.wav','norm'); |
| |
>>
[min(y) max(y)] |
| |
ans
= -1 1 |
| |
|
| Ex.3 |
By
using the 'raw'
scale setting, the WAV data is read directly in its
integer format, without any scaling: |
| |
| |
|
| |
[y,fs]=wavin('..\WAVfiles\wavewarp.wav','raw'); |
| |
>>
[min(y) max(y)] |
| |
ans
= -32171 28771 |
| |
|
| |
This
is useful when reading files which have not been written
according to the accepted standards. The scaling can
be performed later (e.g. using the wavscale
function). |
| |
| Ex.4 |
Read
a 4-channel WAV file named 4channel.wav
located in
the directory ..\WAVFiles then play the
data (two channels at a time, since the sound
command only accepts at most two channels) |
| |
| |
[y,fs]=wavin('..\WAVfiles\4channel.wav'); |
| |
sound(y(:,1:2),fs);
%play channels
1 and 2 |
| |
sound(y(:,3:4),fs);
%play channels
3 and 4 |
| |
| Ex.5 |
Demonstrates
how to read arbitrary portions from arbitrary locations
of the multichannel WAV file from Ex. 4 (then demonstrates
how to concatenate these portions (chunk-by-chunk)
to an output file using wavout
).
First
determine the length of the file (in samples per channel)
using wavinfo
:
|
| |
| |
info=wavinfo('4channel.wav'); |
| |
>>
LengthSamples = info.SamplesPerChannel
169031
|
| |
|
| |
Now
read the first 50000 samples (of each channel), then
close the file (by default via oflag=[]): |
| |
[y1,fs]=wavin('4channel.wav',[],[],50000); |
| |
|
| |
Now
re-open the file, read the next 60000 samples (of each
channel) by offsetting by 50000 from the previous call,
then close the file (by default
via
oflag=[]): |
| |
[y2,fs]=wavin('4channel.wav',[],[],60000,50000);
|
| |
|
| |
Now
re-open the file, read the final 59031 samples (of each
channel, making the total of 169031 samples per channel)
by offsetting by 110000 from the previous two calls,
then close the file (by default
via
oflag=[]): |
| |
[y3,fs]=wavin('4channel.wav',[],[],59031,110000); |
| |
|
| |
To
demonstrate that these actions have been successful,
re-create the original file by writing the three data
chunks successively to an output file, then compare
this file with the original. |
| |
|
| |
Write
the first chunk, keeping the output file open thereafter
(i.e. by using a return argument, fdxo,
and by specifying oflag=1
for
wavout): |
| |
fdxo=wavout(y1,fs,'myfile.wav',[],[],[],1);
|
| |
|
| |
Append
the next chunk (i.e. by using fdxo
instead of a string filename and setting writeskip=-1
in the input arguments to wavout
),
keeping the output file open thereafter (i.e. by using
specifying oflag=1
for
wavout): |
| |
fdxo=wavout(y2,fs,fdxo,[],[],[],1,-1); |
| |
|
| |
Append
the third chunk (i.e. by using fdxo
instead of a string filename and setting writeskip=-1
in the input arguments to wavout
),
then close the output file thereafter (i.e. by using
specifying oflag=0
for
wavout): |
| |
fdxo=wavout(y3,fs,fdxo,[],[],[],0,-1);
|
| |
|
| |
Compare
the original and the re-constructed file to verify that
they are, in fact, identical. Do this by reading both
files into memory then looking at the maximum absolute
difference (should be zero): |
| |
[y_orig,fs]=wavin('4channel.wav'); |
| |
[y_new,fs]=wavin('myfile.wav'); |
| |
>>
max(abs(y_orig - y_new)) |
| |
ans=
0 0 0 0
|
| |
...Demonstrating
that indeed the files are identical ! |
| |
|

Send Page To a Friend
|
|