File: auwrite.sci

package info (click to toggle)
scilab 5.3.3-10
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 330,656 kB
file content (168 lines) | stat: -rw-r--r-- 5,138 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
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-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'),'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