📄 writewav.m
字号:
function fidx=wwav(d,fs,filename,mode,nskip)
%WRITEWAV Creates .WAV format sound files FIDX=(D,FS,FILENAME,MODE,NSKIP)
%
% The input arguments for WRITEWAV are as follows:
%
% D The sampled data to save
% FS The rate at which the data was sampled
% FILENAME A string containing the name of the .WAV file to create or
% alternatively the FIDX output from a previous writewav call
% MODE String containing any reasonable mixture of the following (*=default):
%
% Precision: 'a' for 8-bit A-law PCM
% 'u' for 8-bit mu-law PCM
% '16' * for 16 bit PCM data
% '8' for 8 bit PCM data
% ... any number in the range 2 to 32 for PCM
%
% 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
% Offset: 'y' * Correct for offset in <=8 bit PCM data
% 'z' No offset correction
% File I/O: 'f' Do not close file on exit
% NSKIP Number of samples to skip before writing or -1[default] to continue from previous write
% Only valid if FIDX is specified for FILENAME
%
% Output Parameter:
%
% 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
% (9) fs sample frequency
%
% Note: WRITEWAV will create an 16-bit PCM, auto-scaled wave file by default.
% For stereo data, d(:,1) is the left channel and d(:,2) the right
%
% See also READWAV
% Copyright (C) Mike Brookes 1998
%
% Last modified Tue May 12 16:11:10 1998
%
% VOICEBOX home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You can obtain a copy of the GNU General Public License from
% ftp://prep.ai.mit.edu/pub/gnu/COPYING-2.0 or by writing to
% Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin<3 error('Usage: WRITEWAV(data,fs,filename,mode,nskip)'); end
info=zeros(1,9);
info(9)=fs;
if nargin<4 mode='s';
else mode = [mode(:).' 's'];
end
info(7)=16; info(8)=1; hi=32767; lo=-32768; pk=32767.5;
if nargin>3
k=find((mode>='0') & (mode<='9'));
if k info(7)=str2num(mode(k)); hi=pow2(0.5,info(7))-1; lo=-1-hi; pk=hi+0.5; end
if any(mode=='a') info(8)=6; pk=4096; info(7)=8; end
if any(mode=='u') info(8)=7; pk=8159; info(7)=8; end % pk value wrong
end
k=find((mode>='p') & (mode<='s'));
sc=mode(k(1));
z=128*all(mode~='z');
info(6)=ceil(info(7)/8);
[n,nc]=size(d);
if n==1 n=nc; nc=1;
else d = d.';
end;
if nc>10 error('WRITEWAV: attempt to write a sound file with >10 channels'); end
nc=max(nc,1);
ncy=nc*info(6);
nyd=n*ncy;
if ischar(filename)
nskip=0;
ny=nyd;
if isempty(findstr(filename,'.')) filename=[filename,'.wav']; end
fid=fopen(filename,'wb+','l');
if fid == -1 error(sprintf('Can''t open %s for output',filename)); end
info(1)=fid;
fwrite(fid,'RIFF','uchar');
fwrite(fid,36+ny,'ulong');
fwrite(fid,'WAVEfmt ','uchar');
fwrite(fid,[16 0 info(8) nc],'ushort');
fwrite(fid,[fs fs*ncy],'ulong');
fwrite(fid,[ncy info(7)],'ushort');
fwrite(fid,'data','uchar');
fwrite(fid,ny,'ulong');
info(3)=44;
info(4)=n+nskip;
info(2)=info(4);
else
info=filename;
fid=info(1);
fseek(fid,0,1);
if nargin<5 nskip=info(2);
elseif nskip<0 nskip=info(2);
end
info(2)=n+nskip;
ny=nyd+nskip*ncy;
if n & (info(2)>info(4))
if ~info(4)
fseek(fid,22,-1); fwrite(fid,nc,'ushort');
fseek(fid,28,-1); fwrite(fid,fs*ncy,'ulong');
fwrite(fid,ncy,'ushort');
end
fseek(fid,4,-1); fwrite(fid,36+ny,'ulong');
fseek(fid,40,-1); fwrite(fid,ny,'ulong');
info(4)=info(2);
end
end
info(5)=nc;
if n
st=fseek(fid,info(3)+nskip*nc*info(6),-1);
if st error(sprintf('Cannot seek to %d in output file',info(3)+nskip*nc*info(6))); end
if sc~='r'
if sc=='s' pd=max(abs(d(:))); pd=pd+(pd==0);
elseif sc=='p' pd=1;
else
if info(8)==7
pd=2.03761563;
else
pd=2.03033976;
end
end
d=pk/pd*d;
end
if info(8)<6
d=round(0.5*(lo+hi+abs(d-lo)-abs(d-hi)))*pow2(1,8*info(6)-info(7));
else
z=0;
if info(8) < 7
d=lin2pcma(d,213,1);
else
d=lin2pcmu(d,1);
end
end
if info(6)<3
if info(6)<2
fwrite(fid,d+z,'uchar');
else
fwrite(fid,d,'short');
end
else
if info(6)<4
d=d(:)';
d2=floor(d/65536);
d=d-65536*d2;
fwrite(fid,[rem(d,256); floor(d/256); d2],'uchar');
else
fwrite(fid,d,'long');
end
end
if rem(ny,2) fwrite(fid,0,'uchar'); end
end
if all(mode~='f') fclose(fid); end
if nargout fidx=info; end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -