Mercurial > forge
comparison main/audio/ausave.m @ 0:6b33357c7561 octave-forge
Initial revision
author | pkienzle |
---|---|
date | Wed, 10 Oct 2001 19:54:49 +0000 |
parents | |
children | 4cad27e73814 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:6b33357c7561 |
---|---|
1 ## Copyright (C) 1999 Paul Kienzle | |
2 ## | |
3 ## This program is free software; you can redistribute it and/or modify | |
4 ## it under the terms of the GNU General Public License as published by | |
5 ## the Free Software Foundation; either version 2 of the License, or | |
6 ## (at your option) any later version. | |
7 ## | |
8 ## This program is distributed in the hope that it will be useful, | |
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 ## GNU General Public License for more details. | |
12 ## | |
13 ## You should have received a copy of the GNU General Public License | |
14 ## along with this program; if not, write to the Free Software | |
15 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
16 | |
17 ## usage: ausave('filename.ext', x, fs, format) | |
18 ## | |
19 ## Writes an audio file with the appropriate header. The extension on | |
20 ## the filename determines the layout of the header. Currently supports | |
21 ## .wav and .au layouts. Data is a matrix of audio samples, one row | |
22 ## time step, one column per channel. Fs defaults to 8000 Hz. Format | |
23 ## is one of ulaw, alaw, char, short, long, float, double | |
24 function ausave(path, data, rate, sampleformat) | |
25 | |
26 if nargin < 2 || nargin>4 | |
27 usage("ausave('filename.ext', x [, fs, sampleformat])"); | |
28 end | |
29 if nargin < 3, rate = 8000; end | |
30 if nargin < 4, sampleformat = 'short'; end | |
31 | |
32 ext = rindex(path, '.'); | |
33 if (ext == 0) | |
34 usage("ausave('filename.ext', x [, fs, sampleformat])"); | |
35 end | |
36 ext = tolower(substr(path, ext+1, length(path)-ext)); | |
37 | |
38 [samples, channels] = size(data); | |
39 | |
40 ## Microsoft .wav format | |
41 if strcmp(ext,'wav') | |
42 | |
43 ## Header format obtained from sox/wav.c | |
44 ## April 15, 1992 | |
45 ## Copyright 1992 Rick Richardson | |
46 ## Copyright 1991 Lance Norskog And Sundry Contributors | |
47 ## This source code is freely redistributable and may be used for | |
48 ## any purpose. This copyright notice must be maintained. | |
49 ## Lance Norskog And Sundry Contributors are not responsible for | |
50 ## the consequences of using this software. | |
51 | |
52 if (strcmp(sampleformat,'uchar')) | |
53 formatid = 1; | |
54 samplesize = 1; | |
55 elseif (strcmp(sampleformat,'short')) | |
56 formatid = 1; | |
57 samplesize = 2; | |
58 elseif (strcmp(sampleformat, 'long')) | |
59 formatid = 1; | |
60 samplesize = 4; | |
61 elseif (strcmp(sampleformat, 'alaw')) | |
62 formatid = 6; | |
63 samplesize = 1; | |
64 elseif (strcmp(sampleformat, 'ulaw')) | |
65 formatid = 7; | |
66 samplesize = 1; | |
67 else | |
68 error("%s is invalid format for .wav file\n", sampleformat); | |
69 end | |
70 datasize = channels*samplesize*samples; | |
71 | |
72 [file, msg] = fopen(path, 'w'); | |
73 if (file == -1) | |
74 error("%s: %s", msg, path); | |
75 end | |
76 | |
77 ## write the magic header | |
78 arch = 'ieee-le'; | |
79 fwrite(file, toascii('RIFF'), 'char'); | |
80 fwrite(file, datasize+36, 'long', 0, arch); | |
81 fwrite(file, toascii('WAVE'), 'char'); | |
82 | |
83 ## write the "fmt " section | |
84 fwrite(file, toascii('fmt '), 'char'); | |
85 fwrite(file, 16, 'long', 0, arch); | |
86 fwrite(file, formatid, 'short', 0, arch); | |
87 fwrite(file, channels, 'short', 0, arch); | |
88 fwrite(file, rate, 'long', 0, arch); | |
89 fwrite(file, rate*channels*samplesize, 'long', 0, arch); | |
90 fwrite(file, channels*samplesize, 'short', 0, arch); | |
91 fwrite(file, samplesize*8, 'short', 0, arch); | |
92 | |
93 ## write the "data" section | |
94 fwrite(file, toascii('data'), 'char'); | |
95 fwrite(file, datasize, 'long', 0, arch); | |
96 | |
97 ## Sun .au format | |
98 elseif strcmp(ext, 'au') | |
99 | |
100 ## Header format obtained from sox/au.c | |
101 ## September 25, 1991 | |
102 ## Copyright 1991 Guido van Rossum And Sundry Contributors | |
103 ## This source code is freely redistributable and may be used for | |
104 ## any purpose. This copyright notice must be maintained. | |
105 ## Guido van Rossum And Sundry Contributors are not responsible for | |
106 ## the consequences of using this software. | |
107 | |
108 if (strcmp(sampleformat, 'ulaw')) | |
109 formatid = 1; | |
110 samplesize = 1; | |
111 elseif (strcmp(sampleformat,'uchar')) | |
112 formatid = 2; | |
113 samplesize = 1; | |
114 elseif (strcmp(sampleformat,'short')) | |
115 formatid = 3; | |
116 samplesize = 2; | |
117 elseif (strcmp(sampleformat, 'long')) | |
118 formatid = 5; | |
119 samplesize = 4; | |
120 elseif (strcmp(sampleformat, 'float')) | |
121 formatid = 6; | |
122 samplesize = 4; | |
123 elseif (strcmp(sampleformat, 'double')) | |
124 formatid = 7; | |
125 samplesize = 8; | |
126 else | |
127 error("%s is invalid format for .au file\n", sampleformat); | |
128 end | |
129 datasize = channels*samplesize*samples; | |
130 | |
131 [file, msg] = fopen(path, 'w'); | |
132 if (file == -1) | |
133 error("%s: %s", msg, path); | |
134 end | |
135 | |
136 arch = 'ieee-be'; | |
137 fwrite(file, toascii('.snd'), 'char'); | |
138 fwrite(file, 24, 'long', 0, arch); | |
139 fwrite(file, datasize, 'long', 0, arch); | |
140 fwrite(file, formatid, 'long', 0, arch); | |
141 fwrite(file, rate, 'long', 0, arch); | |
142 fwrite(file, channels, 'long', 0, arch); | |
143 | |
144 ## Apple/SGI .aiff format | |
145 elseif strcmp(ext,'aiff') | |
146 | |
147 ## Header format obtained from sox/aiff.c | |
148 ## September 25, 1991 | |
149 ## Copyright 1991 Guido van Rossum And Sundry Contributors | |
150 ## This source code is freely redistributable and may be used for | |
151 ## any purpose. This copyright notice must be maintained. | |
152 ## Guido van Rossum And Sundry Contributors are not responsible for | |
153 ## the consequences of using this software. | |
154 ## | |
155 ## IEEE 80-bit float I/O taken from | |
156 ## ftp://ftp.mathworks.com/pub/contrib/signal/osprey.tar | |
157 ## David K. Mellinger | |
158 ## dave@mbari.org | |
159 ## +1-831-775-1805 | |
160 ## fax -1620 | |
161 ## Monterey Bay Aquarium Research Institute | |
162 ## 7700 Sandholdt Road | |
163 | |
164 if (strcmp(sampleformat,'uchar')) | |
165 samplesize = 1; | |
166 elseif (strcmp(sampleformat,'short')) | |
167 samplesize = 2; | |
168 elseif (strcmp(sampleformat, 'long')) | |
169 samplesize = 4; | |
170 else | |
171 error("%s is invalid format for .aiff file\n", sampleformat); | |
172 end | |
173 datasize = channels*samplesize*samples; | |
174 | |
175 [file, msg] = fopen(path, 'w'); | |
176 if (file == -1) | |
177 error("%s: %s", msg, path); | |
178 end | |
179 | |
180 ## write the magic header | |
181 arch = 'ieee-be'; | |
182 fwrite(file, toascii('FORM'), 'char'); | |
183 fwrite(file, datasize+46, 'long', 0, arch); | |
184 fwrite(file, toascii('AIFF'), 'char'); | |
185 | |
186 ## write the "COMM" section | |
187 fwrite(file, toascii('COMM'), 'char'); | |
188 fwrite(file, 18, 'long', 0, arch); | |
189 fwrite(file, channels, 'short', 0, arch); | |
190 fwrite(file, samples, 'long', 0, arch); | |
191 fwrite(file, 8*samplesize, 'short', 0, arch); | |
192 fwrite(file, 16414, 'ushort', 0, arch); % sample rate exponent | |
193 fwrite(file, [rate, 0], 'ulong', 0, arch); % sample rate mantissa | |
194 | |
195 ## write the "SSND" section | |
196 fwrite(file, toascii('SSND'), 'char'); | |
197 fwrite(file, datasize+8, 'long', 0, arch); # section length | |
198 fwrite(file, 0, 'long', 0, arch); # block size | |
199 fwrite(file, 0, 'long', 0, arch); # offset | |
200 | |
201 ## file extension unknown | |
202 else | |
203 error('ausave(filename.ext,...) understands .wav .au and .aiff only'); | |
204 end | |
205 | |
206 ## convert samples from range [-1, 1) | |
207 if strcmp(sampleformat, 'alaw') | |
208 error("FIXME: ausave needs linear to alaw conversion\n"); | |
209 precision = 'uchar'; | |
210 elseif strcmp(sampleformat, 'ulaw') | |
211 data = lin2mu(data); | |
212 precision = 'uchar' | |
213 elseif strcmp(sampleformat, 'uchar') | |
214 data = data*128 + 128; | |
215 precision = 'uchar'; | |
216 elseif strcmp(sampleformat, 'short') | |
217 data = data*32768; | |
218 precision = 'short'; | |
219 elseif strcmp(sampleformat, 'long') | |
220 data = data*2^31; | |
221 precision = 'long'; | |
222 else | |
223 precision = sampleformat; | |
224 end | |
225 fwrite(file, data', precision, 0, arch); | |
226 fclose(file); | |
227 | |
228 endfunction |