Home > voicebox > readaif.m

readaif

PURPOSE ^

READAIF Read a .AIF format sound file [Y,FS,WMODE,FIDX]=(FILENAME,MODE,NMAX,NSKIP)

SYNOPSIS ^

function [y,fs,wmode,fidx]=readaif(filename,mode,nmax,nskip)

DESCRIPTION ^

READAIF  Read a .AIF format sound file [Y,FS,WMODE,FIDX]=(FILENAME,MODE,NMAX,NSKIP)

 Input Parameters:

    FILENAME gives the name of the file (with optional .AIF extension) or alternatively
                 can be the FIDX output from a previous call to READAIF
    MODE        specifies the following (*=default):

    Scaling: 's'    Auto scale to make data peak = +-1
             'r'    Raw unscaled data (integer values)
             'q'    Scaled to make 0dBm0 be unity mean square
             'p' *    Scaled to make +-1 equal full scale
             'o'    Scale to bin centre rather than bin edge (e.g. 127 rather than 127.5 for 8 bit values)
                     (can be combined with n+p,r,s modes)
             'n'    Scale to negative peak rather than positive peak (e.g. 128.5 rather than 127.5 for 8 bit values)
                     (can be combined with o+p,r,s modes)
   File I/O: 'f'    Do not close file on exit
             'd'    Look in data directory: voicebox('dir_data')

    NMAX     maximum number of samples to read (or -1 for unlimited [default])
    NSKIP    number of samples to skip from start of file
               (or -1 to continue from previous read when FIDX is given instead of FILENAME [default])

 Output Parameters:

    Y        data matrix of dimension (samples,channels)
    FS       sample frequency in Hz
    WMODE    mode string needed to recreate the data file
    FIDX     Information row vector containing the element listed below.

           (1)  file id
                (2)  current position in file
           (3)  dataoff    byte offset in file to start of data
           (4)  nsamp    number of samples
           (5)  nchan    number of channels
           (6)  nbyte    bytes per data value
           (7)  bits    number of bits of precision
           (8)  code    Data format: 1=PCM, 2=ADPCM, 6=A-law, 7=Mu-law (always 1 for AIFF)
           (9)  fs    sample frequency
           (10) offset
           (11) block size

   If no output parameters are specified, header information will be printed.

   For stereo data, y(:,1) is the left channel and y(:,2) the right

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [y,fs,wmode,fidx]=readaif(filename,mode,nmax,nskip)
0002 %READAIF  Read a .AIF format sound file [Y,FS,WMODE,FIDX]=(FILENAME,MODE,NMAX,NSKIP)
0003 %
0004 % Input Parameters:
0005 %
0006 %    FILENAME gives the name of the file (with optional .AIF extension) or alternatively
0007 %                 can be the FIDX output from a previous call to READAIF
0008 %    MODE        specifies the following (*=default):
0009 %
0010 %    Scaling: 's'    Auto scale to make data peak = +-1
0011 %             'r'    Raw unscaled data (integer values)
0012 %             'q'    Scaled to make 0dBm0 be unity mean square
0013 %             'p' *    Scaled to make +-1 equal full scale
0014 %             'o'    Scale to bin centre rather than bin edge (e.g. 127 rather than 127.5 for 8 bit values)
0015 %                     (can be combined with n+p,r,s modes)
0016 %             'n'    Scale to negative peak rather than positive peak (e.g. 128.5 rather than 127.5 for 8 bit values)
0017 %                     (can be combined with o+p,r,s modes)
0018 %   File I/O: 'f'    Do not close file on exit
0019 %             'd'    Look in data directory: voicebox('dir_data')
0020 %
0021 %    NMAX     maximum number of samples to read (or -1 for unlimited [default])
0022 %    NSKIP    number of samples to skip from start of file
0023 %               (or -1 to continue from previous read when FIDX is given instead of FILENAME [default])
0024 %
0025 % Output Parameters:
0026 %
0027 %    Y        data matrix of dimension (samples,channels)
0028 %    FS       sample frequency in Hz
0029 %    WMODE    mode string needed to recreate the data file
0030 %    FIDX     Information row vector containing the element listed below.
0031 %
0032 %           (1)  file id
0033 %                (2)  current position in file
0034 %           (3)  dataoff    byte offset in file to start of data
0035 %           (4)  nsamp    number of samples
0036 %           (5)  nchan    number of channels
0037 %           (6)  nbyte    bytes per data value
0038 %           (7)  bits    number of bits of precision
0039 %           (8)  code    Data format: 1=PCM, 2=ADPCM, 6=A-law, 7=Mu-law (always 1 for AIFF)
0040 %           (9)  fs    sample frequency
0041 %           (10) offset
0042 %           (11) block size
0043 %
0044 %   If no output parameters are specified, header information will be printed.
0045 %
0046 %   For stereo data, y(:,1) is the left channel and y(:,2) the right
0047 
0048 %  future enhancements: (1) handle LIST and CAT files as well
0049 %                       (2) deal with offset and blocksize properly
0050 %                       (3) handle other chunk types sensibly
0051 
0052 %       Copyright (C) Mike Brookes 1998
0053 %      Version: $Id: readaif.m 713 2011-10-16 14:45:43Z dmb $
0054 %
0055 %   VOICEBOX is a MATLAB toolbox for speech processing.
0056 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
0057 %
0058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0059 %   This program is free software; you can redistribute it and/or modify
0060 %   it under the terms of the GNU General Public License as published by
0061 %   the Free Software Foundation; either version 2 of the License, or
0062 %   (at your option) any later version.
0063 %
0064 %   This program is distributed in the hope that it will be useful,
0065 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0066 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0067 %   GNU General Public License for more details.
0068 %
0069 %   You can obtain a copy of the GNU General Public License from
0070 %   http://www.gnu.org/copyleft/gpl.html or by writing to
0071 %   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
0072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0073 
0074 if nargin<1 error('Usage: [y,fs,wmode,fidx]=READAIFF(filename,mode,nmax,nskip)'); end
0075 
0076 if nargin<2 mode='p';
0077 else mode = [mode(:).' 'p'];
0078 end
0079 k=find((mode>='p') & (mode<='s'));
0080 mno=all(mode~='o');                      % scale to input limits not output limits
0081 sc=mode(k(1)); 
0082 
0083 
0084 info=zeros(1,11);
0085 if ischar(filename)
0086     if any(mode=='d')
0087         filename=fullfile(voicebox('dir_data'),filename);
0088     end
0089     fid=fopen(filename,'rb','b');
0090     if fid == -1
0091         fn=[filename,'.aif'];
0092         fid=fopen(fn,'rb','b'); 
0093         if fid ~= -1 filename=fn; end
0094     end
0095     if fid == -1 error(sprintf('Can''t open %s for input',filename)); end
0096     info(1)=fid;
0097 else
0098     info=filename;
0099     fid=info(1);
0100 end
0101 
0102 if ~info(3)
0103     fseek(fid,0,-1);                        % read file header
0104     header=fread(fid,4,'uchar');
0105     if header' ~= 'FORM' fclose(fid); error(sprintf('File %s does not begin with a FORM group ID',filename)); end
0106     filen=fread(fid,1,'ulong')-4;
0107     header=fread(fid,4,'uchar');
0108     if header' ~= 'AIFF' fclose(fid); error(sprintf('File %s does not begin with a AIFF type ID',filename)); end
0109     
0110     
0111     fmt=0;
0112     data=0;
0113     while filen>=8                        % loop to read all chunks
0114         header=fread(fid,4,'char');
0115         len=fread(fid,1,'ulong');
0116         lenx=len+rem(len,2);    % round up to an even number
0117         filen=filen-lenx-8;
0118         %fprintf(1,'%s chunk, %d bytes, %d bytes remaining\n',char(header'),len,filen);
0119         if header' == 'COMM'                    % ******* found COMM chunk *********
0120             fmt=1;
0121             info(5)=fread(fid,1,'ushort');            %number of channels
0122             info(4)=fread(fid,1,'ulong');            %number of samples
0123             info(7)=fread(fid,1,'ushort');                % bits per sample
0124             info(6)=ceil(info(7)/8);            % bytes per sample
0125             info(8)=1;
0126             ieeex=fread(fid,5,'ushort');               % read a 10-byte extended ieee format number
0127             fsign=ieeex(1)>32767;
0128             ieeex(1)=ieeex(1)-32768*fsign;
0129             if ~ieeex info(9)=0;
0130             elseif ieeex(1)==32767 info(9)=nan;
0131             else
0132                 info(9)=(1-2*fsign)*sum(pow2(ieeex(2:5)',ieeex(1)-(16398:16:16446)));
0133             end
0134             fseek(fid,lenx-18,0);                % skip to end of header
0135         elseif header' == 'SSND'                % ******* found DATA chunk *********
0136             info(10)=fread(fid,1,'ulong');            %number of channels
0137             info(11)=fread(fid,1,'ulong');            %number of channels
0138             info(3)=ftell(fid);
0139             data=1;
0140             fseek(fid,lenx-8,0);                % skip to end of chunk
0141         else                            % ******* found unwanted chunk *********
0142             fseek(fid,lenx,0);
0143         end
0144     end
0145     if filen~=0
0146         fprintf(2,'READAIF warning: Inconsistent file length - %d extra bytes\n',filen);
0147     end
0148 end
0149 fs=info(9);
0150 if ~fmt | ~data fclose(fid); error(sprintf('File %s does not contain COMM and SSND chunks',filename)); end
0151 
0152 
0153 if nargin<4 nskip=info(2);
0154 elseif nskip<0 nskip=info(2);
0155 end
0156 
0157 ksamples=info(4)-nskip;
0158 if nargin>2
0159     if nmax>=0
0160         ksamples=min(nmax,ksamples);
0161     end
0162 elseif ~nargout
0163     ksamples=min(5,ksamples);
0164 end
0165 if ksamples>0
0166     info(2)=nskip+ksamples;
0167     pk=pow2(0.5,8*info(6))*(1+(mno/2-all(mode~='n'))/pow2(0.5,info(7)));  % use modes o and n to determine effective peak
0168     fseek(fid,info(3)+info(6)*info(5)*nskip,-1);
0169     nsamples=info(5)*ksamples;
0170     if info(6)<3
0171         if info(6)<2
0172             y=fread(fid,nsamples,'schar');
0173         else
0174             y=fread(fid,nsamples,'short');
0175         end
0176     else
0177         if info(6)<4
0178             y=fread(fid,3*nsamples,'uchar');
0179             y=reshape(y,3,nsamples);
0180             y=[1 256 65536]*y-pow2(fix(pow2(y(3,:),-7)),24);
0181         else
0182             y=fread(fid,nsamples,'long');
0183         end
0184     end
0185     if sc ~= 'r'
0186         if sc=='s' sf=1/max(max(abs(y)),1);
0187         elseif sc=='p' sf=1/pk;
0188         else   sf=2.03033976/pk;
0189         end
0190         y=sf*y;
0191     else
0192         y=y*pow2(1,info(7)-8*info(6)); % shift to get the data into the LSB end
0193     end
0194     
0195     if info(5)>1 y = reshape(y,info(5),ksamples).'; end
0196 else
0197     y=[];
0198 end
0199 
0200 if all(mode~='f') fclose(fid); end
0201 
0202 if nargout>2
0203     if ~mno wmode=[wmode 'o']; end
0204     if any(mode=='n') wmode=[wmode 'n']; end
0205     wmode=[sc num2str(info(7))];
0206     fidx=info;
0207 elseif ~nargout
0208     fprintf(1,'\n%d Hz sample rate\n%d channel x %d samples x %d bit = %.3g seconds\n',info([9 5 4]), info(7),info(4)/info(9));
0209 end
0210 
0211 
0212

Generated on Tue 10-Oct-2017 08:30:10 by m2html © 2003