1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
function []=auwrite(y,Fs,nbits,method,aufile)
//Write .au sound file.
//auwrite(y,aufile) writes a sound file specified by the
//string aufile. The data should be arranged with one channel
//per column. Amplitude values outside the range [-1,+1] are
//clipped prior to writing.
//
//Supports multi-channel data for 8-bit mu-law, and 8- and
//16-bit linear formats:
//
//auwrite(y,Fs,aufile) specifies the sample rate of the data
//in Hertz.
//
//auwrite(y,Fs,bits,aufile) selects the number of bits in
//the encoder. Allowable settings are bits=8 and bits=16.
//
//auwrite(y,Fs,bits,method,aufile) allows selection of the
//encoding method, which can be either 'mu' or 'linear'.
//Note that mu-law files must be 8-bit. By default, method='mu'.
// test :
// auwrite(y,44100,8,'mu','poo.au')
// aplay -c 1 -f MU_LAW --rate=22050 poo.au
//
// Get default:
[nargout,nargin] = argn(0)
Fs_pref = 22050;
nbits_pref = 8;
method_pref = 'mu';
if nargin==1 then
error('Incorrect number of input arguments.');
elseif nargin>5 then
error('Incorrect number of input arguments.');
elseif nargin==4 then
aufile = method;
method = method_pref;
elseif nargin==3 then
aufile = nbits;
method = method_pref;
nbits = nbits_pref;
elseif nargin==2 then
aufile = Fs;
method = method_pref;
nbits = nbits_pref;
Fs = Fs_pref;
end
if ~(type(aufile)==10) then
error('Filename must be a string.');
end
if strindex(aufile,'.')==[] then
aufile = aufile+'.au';
end
[fid,junk] = mopen(aufile,'wb',0) // Big-endian
if junk<0 then
error('Cannot open .au sound file');
end
if length(size(y)) > 2 then
error('Data array must have 1- or 2-dimensions, only.');
end
if size(y,2)==1 then
y = y';
end
// Clip data to normalized range [-1,+1]:
i = matrix(find(abs(y)>1),1,-1);
if ~(i==[]) then
y(i) = sign(y(i));
warning('Data clipped during write to file.');
end
snd = write_sndhdr(fid,Fs,nbits,method,size(y));
if write_sndata(fid,snd,y) then
error('Error while writing sound file.');
end
mclose(fid);
endfunction
function [status]=write_sndata(fid,snd,data)
status = 0;
if snd('format')==1 then
dtype = 'uc';
data = lin2mu(data);
elseif snd('format')==2 then
dtype = 'c';// 'int8';
data = round(data*(2^7-1));
elseif snd('format')==3 then
dtype = 'sb';// 'int16"
data = round(data*(2^15-1));
elseif snd('format')==5 then
dtype = 'ib';// 'int32"
data = round(data*(2^31-1));
elseif snd('format')==6 then
dtype = 'fb';
//
elseif snd('format')==7 then
dtype = 'db';// double precision
//
else
status = -1;
return
end
total_samples = snd('samples')*snd('chans');
mput(data,dtype,fid);
endfunction
function [snd]=write_sndhdr(fid,Fs,nbits,method,sz)
// write header part
if method=='mu' then
if nbits~=8 then
error('Mu-law can only be used with 8 bit data.'+' Use method=''linear'' instead.');
end
snd.format = 1;
snd.bits = 8;
elseif method=='linear' then
if nbits==8 then
snd.format=2 // 8-bit linear
snd.bits=8
elseif nbits==16 then
snd.format=3 // 16-bit linear
snd.bits=16
elseif nbits==32 then
snd.format=5 // 32-bit linear
snd.bits=32;
elseif nbits==64 then
snd.format=7; // Double-precision
snd.bits=64;
else
error('Wavwrite: unrecognized data format');
return
end
else
error('Unrecognized data format');
end
// Define sound header structure:
snd('samples')=sz(2)
snd('chans')=sz(1)
total_samples = snd('samples')*snd('chans');
bytes_per_sample = ceil(snd('bits')/8);
snd('rate')=Fs
snd('databytes')=bytes_per_sample*total_samples
snd('offset')=28
snd('info')='SCI0';
mput(ascii('.snd'),'c',fid); // magic number
mput(snd('offset'),'ulb',fid); // data location
mput(snd('databytes'),'ulb',fid); // size in bytes
mput(snd('format'),'ulb',fid); // data format
//
mput(snd('rate')/snd('chans'),'ulb',fid); // sample rate
mput(snd('chans'),'ulb',fid); // channels
mput(ascii(snd('info')),'c',fid); // info
endfunction
|