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
160
161
162
163
164
165
166
167
168
|
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) ???? - INRIA - Scilab
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution. The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
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(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"auwrite",2,5));
elseif nargin>5 then
error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"auwrite",2,5));
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(msprintf(gettext("%s: Wrong values for input argument: Filename must be a string.\n"),"auwrite"));
end
if strindex(aufile,".")==[] then
aufile = aufile+".au";
end
[fid,junk] = mopen(aufile,"wb",0) // Big-endian
if junk<0 then
error(msprintf(gettext("%s: Cannot open file %s.\n"),"auwrite",aufile));
end
if length(size(y)) > 2 then
error(msprintf(gettext("%s: An error occurred: %s\n"),"auwrite",gettext("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(gettext("Data clipped during write to file."));
end
snd = write_sndhdr(fid,Fs,nbits,method,size(y));
if write_sndata(fid,snd,y) then
error(msprintf(gettext("%s: An error occurred: %s\n"),"auwrite",gettext("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(msprintf(gettext("%s: An error occurred: %s\n"),"auwrite",gettext("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(msprintf(gettext("%s: An error occurred: %s\n"),"auwrite",gettext("Unrecognized data format.")));
return
end
else
error(msprintf(gettext("%s: An error occurred: %s\n"),"auwrite",gettext("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"),"uib",fid); // data location
mput(snd("databytes"),"uib",fid); // size in bytes
mput(snd("format"),"uib",fid); // data format
//
mput(snd("rate")/snd("chans"),"uib",fid); // sample rate
mput(snd("chans"),"uib",fid); // channels
mput(ascii(snd("info")),"c",fid); // info
endfunction
|