Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Audio.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/* vim: set noet ts=4 sw=4: */
21
22#include <math.h>
23#include <stdio.h>
24#include <lal/LALStdlib.h>
25#include <lal/LALStdio.h>
26#include <lal/Audio.h>
27
28#define LAL_SOUND_MAX 32760
29
30/* if file pointer is NULL then create a new file based on series name */
31static FILE * fopen_if_null( FILE *fp, const char *name, const char *extn )
32{
33 if ( ! fp ) {
34 char fname[FILENAME_MAX];
35 snprintf( fname, sizeof( fname ), "%s.%s", name, extn );
36 fp = LALFopen( fname, "w" );
37 }
38 return fp;
39}
40
41static int output_wav_hdr( FILE *fp, INT4 samplerate, UINT4 datasize )
42{
43 UINT4 totalsize = datasize + 36; /* for header */
44 INT4 byterate = samplerate * sizeof( UINT2 );
45
46 /*
47 *
48 * Write RIFF Header
49 *
50 */
51
52 /* magic */
53 fprintf( fp, "RIFF" );
54
55 /* size of rest of file (bytes) */
56 fputc( (totalsize & 0x000000ff) , fp );
57 fputc( (totalsize & 0x0000ff00) >> 8 , fp );
58 fputc( (totalsize & 0x00ff0000) >> 16 , fp );
59 fputc( (totalsize & 0xff000000) >> 24 , fp );
60
61 /* file type "WAVE" */
62 fprintf( fp, "WAVE" );
63
64
65 /*
66 *
67 * Write Format Chunk
68 *
69 */
70
71
72 /* magic */
73 fprintf( fp, "fmt " );
74
75 /* chunk size */
76 fputc( 16, fp );
77 fputc( 0, fp );
78 fputc( 0, fp );
79 fputc( 0, fp );
80
81 /* format tag (1=uncompressed) */
82 fputc( 1, fp );
83 fputc( 0, fp );
84
85 /* number of channels */
86 fputc( 1, fp );
87 fputc( 0, fp );
88
89 /* samples per second */
90 fputc( (samplerate & 0x000000ff) , fp );
91 fputc( (samplerate & 0x0000ff00) >> 8 , fp );
92 fputc( (samplerate & 0x00ff0000) >> 16, fp );
93 fputc( (samplerate & 0xff000000) >> 24, fp );
94
95 /* average bytes per second */
96 fputc( (byterate & 0x000000ff) , fp );
97 fputc( (byterate & 0x0000ff00) >> 8 , fp );
98 fputc( (byterate & 0x00ff0000) >> 16, fp );
99 fputc( (byterate & 0xff000000) >> 24, fp );
100
101 /* block alignment (bytes of data per time step) */
102 /* i.e., number of channels times sample width in bytes */
103 fputc( 2, fp );
104 fputc( 0, fp );
105
106 /* bits per sample */
107 fputc( 16, fp );
108 fputc( 0, fp );
109
110
111 /*
112 *
113 * Write Data Chunk
114 *
115 */
116
117
118 /* magic */
119 fprintf( fp, "data" );
120
121 /* size of this chunk in bytes */
122 fputc( (datasize & 0x000000ff), fp );
123 fputc( (datasize & 0x0000ff00) >> 8, fp );
124 fputc( (datasize & 0x00ff0000) >> 16, fp );
125 fputc( (datasize & 0xff000000) >> 24, fp );
126
127 return 0;
128}
129
130static int output_au_hdr( FILE *fp, INT4 samplerate, UINT4 datasize )
131{
132 /*
133 *
134 * Write header
135 *
136 */
137
138 /* magic number */
139 fprintf( fp, ".snd" );
140
141 /* header length */
142 fputc( 0, fp );
143 fputc( 0, fp );
144 fputc( 0, fp );
145 fputc( 24, fp );
146
147 /* data size (bytes) */
148 fputc( (datasize & 0xff000000) >> 24, fp );
149 fputc( (datasize & 0x00ff0000) >> 16, fp );
150 fputc( (datasize & 0x0000ff00) >> 8, fp );
151 fputc( (datasize & 0x000000ff), fp );
152
153 /* encoding (16 bit pcm) */
154 fputc( 0, fp );
155 fputc( 0, fp );
156 fputc( 0, fp );
157 fputc( 3, fp );
158
159 /* sample rate */
160 fputc( (samplerate & 0xff000000) >> 24, fp );
161 fputc( (samplerate & 0x00ff0000) >> 16, fp );
162 fputc( (samplerate & 0x0000ff00) >> 8, fp );
163 fputc( (samplerate & 0x000000ff), fp );
164
165 /* number of channels */
166 fputc( 0, fp );
167 fputc( 0, fp );
168 fputc( 0, fp );
169 fputc( 1, fp );
170
171 return 0;
172}
173
174static int output_REAL4Vector( FILE *fp, REAL4Vector *data, int wavfmt )
175{
176 REAL4 maxval, minval, midval, scale;
177 UINT4 i;
178
179 /* compute range */
180 maxval = minval = data->data[0];
181 for ( i = 1; i < data->length; ++i ) {
182 if ( data->data[i] > maxval )
183 maxval = data->data[i];
184 if ( data->data[i] < minval )
185 minval = data->data[i];
186 }
187 midval = 0.5*(maxval + minval);
188 maxval -= midval;
189 minval -= midval;
190 if ( fabs( minval ) > fabs( maxval ) )
191 maxval = fabs( minval );
192 scale = LAL_SOUND_MAX / maxval;
193
194 /* output data */
195 if ( wavfmt == 1 ) { /* wav format */
196 for ( i = 0; i < data->length; ++i ) {
197 UINT2 val;
198 val = (UINT2)( scale * (data->data[i] - midval) );
199 fputc( (val & 0x00ff), fp );
200 fputc( (val & 0xff00) >> 8, fp );
201 }
202 } else { /* au format */
203 for ( i = 0; i < data->length; ++i ) {
204 UINT2 val;
205 val = (UINT2)(scale*data->data[i]);
206 fputc( (val & 0xff00) >> 8, fp );
207 fputc( (val & 0x00ff), fp );
208 }
209 }
210 return 0;
211}
212
213static int output_REAL8Vector( FILE *fp, REAL8Vector *data, int wavfmt )
214{
215 REAL4 maxval, minval, midval, scale;
216 UINT4 i;
217
218 /* compute range */
219 maxval = minval = data->data[0];
220 for ( i = 1; i < data->length; ++i ) {
221 if ( data->data[i] > maxval )
222 maxval = data->data[i];
223 if ( data->data[i] < minval )
224 minval = data->data[i];
225 }
226 midval = 0.5*(maxval + minval);
227 maxval -= midval;
228 minval -= midval;
229 if ( fabs( minval ) > fabs( maxval ) )
230 maxval = fabs( minval );
231 scale = LAL_SOUND_MAX / maxval;
232
233 /* output data */
234 if ( wavfmt == 1 ) { /* wav format */
235 for ( i = 0; i < data->length; ++i ) {
236 UINT2 val;
237 val = (UINT2)( scale * (data->data[i] - midval) );
238 fputc( (val & 0x00ff), fp );
239 fputc( (val & 0xff00) >> 8, fp );
240 }
241 } else { /* au format */
242 for ( i = 0; i < data->length; ++i ) {
243 UINT2 val;
244 val = (UINT2)(scale*data->data[i]);
245 fputc( (val & 0xff00) >> 8, fp );
246 fputc( (val & 0x00ff), fp );
247 }
248 }
249
250 return 0;
251}
252
253/** Records a time series as a .wav audio file */
255{
256 INT4 samplerate;
257 UINT4 datasize;
258 FILE *fpout;
259
260 if ( ! series )
262 if ( ! series->data )
264 if ( ! series->data->length )
266
267 datasize = series->data->length * sizeof( UINT2 );
268 samplerate = (INT4)(1.0/series->deltaT);
269 if ( samplerate < 1 )
271
272 fpout = fopen_if_null( fp, series->name, "wav" );
273 if ( ! fpout )
275
276 /* write header */
277 output_wav_hdr( fpout, samplerate, datasize );
278
279 /* write data */
280 output_REAL4Vector( fpout, series->data, 1 );
281
282 if ( !fp )
283 fclose( fpout );
284
285 return 0;
286}
287
288/** Records a time series as a .wav audio file */
290{
291 INT4 samplerate;
292 UINT4 datasize;
293 FILE *fpout;
294
295 if ( ! series )
297 if ( ! series->data )
299 if ( ! series->data->length )
301
302 datasize = series->data->length * sizeof( UINT2 );
303 samplerate = (INT4)(1.0/series->deltaT);
304 if ( samplerate < 1 )
306
307 fpout = fopen_if_null( fp, series->name, "wav" );
308 if ( ! fpout )
310
311 /* write header */
312 output_wav_hdr( fpout, samplerate, datasize );
313
314 /* write data */
315 output_REAL8Vector( fpout, series->data, 1 );
316
317 if ( !fp )
318 fclose( fpout );
319
320 return 0;
321}
322
323
324/** Records a time series as a .au audio file */
326{
327 INT4 samplerate;
328 UINT4 datasize;
329 FILE *fpout;
330
331 if ( ! series )
333 if ( ! series->data )
335 if ( ! series->data->length )
337
338 datasize = series->data->length * sizeof( UINT2 );
339 samplerate = (INT4)(1.0/series->deltaT);
340 if ( samplerate < 1 )
342
343 fpout = fopen_if_null( fp, series->name, "au" );
344 if ( ! fpout )
346
347 /* write header */
348 output_au_hdr( fpout, samplerate, datasize );
349
350 /* write data */
351 output_REAL4Vector( fpout, series->data, 0 );
352
353 if ( !fp )
354 fclose( fpout );
355
356 return 0;
357}
358
359/** Records a time series as a .au audio file */
361{
362 INT4 samplerate;
363 UINT4 datasize;
364 FILE *fpout;
365
366 if ( ! series )
368 if ( ! series->data )
370 if ( ! series->data->length )
372
373 datasize = series->data->length * sizeof( UINT2 );
374 samplerate = (INT4)(1.0/series->deltaT);
375 if ( samplerate < 1 )
377
378 fpout = fopen_if_null( fp, series->name, "au" );
379 if ( ! fpout )
381
382 /* write header */
383 output_au_hdr( fpout, samplerate, datasize );
384
385 /* write data */
386 output_REAL8Vector( fpout, series->data, 0 );
387
388 if ( !fp )
389 fclose( fpout );
390
391 return 0;
392}
static int output_au_hdr(FILE *fp, INT4 samplerate, UINT4 datasize)
Definition: Audio.c:130
#define LAL_SOUND_MAX
Definition: Audio.c:28
static int output_wav_hdr(FILE *fp, INT4 samplerate, UINT4 datasize)
Definition: Audio.c:41
static FILE * fopen_if_null(FILE *fp, const char *name, const char *extn)
Definition: Audio.c:31
static int output_REAL4Vector(FILE *fp, REAL4Vector *data, int wavfmt)
Definition: Audio.c:174
static int output_REAL8Vector(FILE *fp, REAL8Vector *data, int wavfmt)
Definition: Audio.c:213
#define fprintf
const char *const name
type name
Definition: UserInput.c:193
int XLALAudioAURecordREAL8TimeSeries(FILE *fp, REAL8TimeSeries *series)
Records a time series as a .au audio file.
Definition: Audio.c:360
int XLALAudioWAVRecordREAL8TimeSeries(FILE *fp, REAL8TimeSeries *series)
Records a time series as a .wav audio file.
Definition: Audio.c:289
int XLALAudioWAVRecordREAL4TimeSeries(FILE *fp, REAL4TimeSeries *series)
Records a time series as a .wav audio file.
Definition: Audio.c:254
int XLALAudioAURecordREAL4TimeSeries(FILE *fp, REAL4TimeSeries *series)
Records a time series as a .au audio file.
Definition: Audio.c:325
uint16_t UINT2
Two-byte unsigned integer.
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
#define LALFopen
Definition: LALStdio.h:50
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:700
@ XLAL_EBADLEN
Inconsistent or invalid length.
Definition: XLALError.h:419
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EIO
I/O error.
Definition: XLALError.h:406
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:570
CHAR name[LALNameLength]
The name of the time series.
Definition: LALDatatypes.h:571
REAL4Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:576
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:573
Vector of type REAL4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:145
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Time series of REAL8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:580
REAL8Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:586
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:583
CHAR name[LALNameLength]
The name of the time series.
Definition: LALDatatypes.h:581
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158
FILE * fp
Definition: tconvert.c:105