File: auwrite.sci

package info (click to toggle)
scilab 4.0-12
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 100,640 kB
  • ctags: 57,333
  • sloc: ansic: 377,889; fortran: 242,862; xml: 179,819; tcl: 42,062; sh: 10,593; ml: 9,441; makefile: 4,377; cpp: 1,354; java: 621; csh: 260; yacc: 247; perl: 130; lex: 126; asm: 72; lisp: 30
file content (159 lines) | stat: -rw-r--r-- 4,190 bytes parent folder | download | duplicates (2)
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