LAL  7.5.0.1-b72065a
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 */
31 static 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 
41 static 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 
130 static 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 
174 static 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 
213 static 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 )
274  XLAL_ERROR( XLAL_EIO );
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 )
309  XLAL_ERROR( XLAL_EIO );
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 )
345  XLAL_ERROR( XLAL_EIO );
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 )
380  XLAL_ERROR( XLAL_EIO );
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 FILE * fopen_if_null(FILE *fp, const char *name, const char *extn)
Definition: Audio.c:31
static int output_wav_hdr(FILE *fp, INT4 samplerate, UINT4 datasize)
Definition: Audio.c:41
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