Sounds Logical
Send Page To a Friend

Table Of Contents Previous Page Next Page

[M-Pack 1 overview]

M-Pack 1: WAV file processing: MATLAB function reference

wavin
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)
Syntax:

[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);
Arguments:
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:

  1. file id (obtained from the fopen command)
  2. 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.
  3. 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.
  4. number of samples per channel in the entire file
  5. number of channels
  6. "container size" (in bytes) per data value. Note: corresponding container size in bits (= ContainerBytes/8) is always an integer multiple of 8.
  7. umber of valids bits of precision (may be less than given container size)
  8. 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
  9. sample rate in Hz
  10. 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.

 

  wavinfo     reading the header from a WAV file
  wavout     WAV file writing
  wavscale     scaling of WAV data
Examples:
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 !
 

Top Of Page Table Of Contents Previous Page Next Page

Send Page To a Friend

home - news - products - store - support - site map - company info
© 2007 Sounds Logical. All rights reserved.
Sounds Logical
legal notice - privacy statement