00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <math.h>
00031 #include <stdio.h>
00032 #include <lal/LALStdlib.h>
00033 #include <lal/LALStdio.h>
00034 #include <lal/Audio.h>
00035
00036 #define LAL_SOUND_MAX 32760
00037
00038 NRCSID( AUDIOC, "$Id: Audio.c,v 1.3 2007/09/21 19:24:56 jolien Exp $" );
00039
00040
00041 static FILE * fopen_if_null( FILE *fp, const char *name, const char *extn )
00042 {
00043 if ( ! fp ) {
00044 char fname[FILENAME_MAX];
00045 LALSnprintf( fname, sizeof( fname ), "%s.%s", name, extn );
00046 fp = fopen( fname, "w" );
00047 }
00048 return fp;
00049 }
00050
00051 static int output_wav_hdr( FILE *fp, INT4 samplerate, UINT4 datasize )
00052 {
00053 UINT4 totalsize = datasize + 36;
00054 INT4 byterate = samplerate * sizeof( UINT2 );
00055
00056
00057
00058
00059
00060
00061
00062
00063 fprintf( fp, "RIFF" );
00064
00065
00066 fputc( (totalsize & 0x000000ff) , fp );
00067 fputc( (totalsize & 0x0000ff00) >> 8 , fp );
00068 fputc( (totalsize & 0x00ff0000) >> 16 , fp );
00069 fputc( (totalsize & 0xff000000) >> 24 , fp );
00070
00071
00072 fprintf( fp, "WAVE" );
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 fprintf( fp, "fmt " );
00084
00085
00086 fputc( 16, fp );
00087 fputc( 0, fp );
00088 fputc( 0, fp );
00089 fputc( 0, fp );
00090
00091
00092 fputc( 1, fp );
00093 fputc( 0, fp );
00094
00095
00096 fputc( 1, fp );
00097 fputc( 0, fp );
00098
00099
00100 fputc( (samplerate & 0x000000ff) , fp );
00101 fputc( (samplerate & 0x0000ff00) >> 8 , fp );
00102 fputc( (samplerate & 0x00ff0000) >> 16, fp );
00103 fputc( (samplerate & 0xff000000) >> 24, fp );
00104
00105
00106 fputc( (byterate & 0x000000ff) , fp );
00107 fputc( (byterate & 0x0000ff00) >> 8 , fp );
00108 fputc( (byterate & 0x00ff0000) >> 16, fp );
00109 fputc( (byterate & 0xff000000) >> 24, fp );
00110
00111
00112
00113 fputc( 2, fp );
00114 fputc( 0, fp );
00115
00116
00117 fputc( 16, fp );
00118 fputc( 0, fp );
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 fprintf( fp, "data" );
00130
00131
00132 fputc( (datasize & 0x000000ff), fp );
00133 fputc( (datasize & 0x0000ff00) >> 8, fp );
00134 fputc( (datasize & 0x00ff0000) >> 16, fp );
00135 fputc( (datasize & 0xff000000) >> 24, fp );
00136
00137 return 0;
00138 }
00139
00140 static int output_au_hdr( FILE *fp, INT4 samplerate, UINT4 datasize )
00141 {
00142
00143
00144
00145
00146
00147
00148
00149 fprintf( fp, ".snd" );
00150
00151
00152 fputc( 0, fp );
00153 fputc( 0, fp );
00154 fputc( 0, fp );
00155 fputc( 24, fp );
00156
00157
00158 fputc( (datasize & 0xff000000) >> 24, fp );
00159 fputc( (datasize & 0x00ff0000) >> 16, fp );
00160 fputc( (datasize & 0x0000ff00) >> 8, fp );
00161 fputc( (datasize & 0x000000ff), fp );
00162
00163
00164 fputc( 0, fp );
00165 fputc( 0, fp );
00166 fputc( 0, fp );
00167 fputc( 3, fp );
00168
00169
00170 fputc( (samplerate & 0xff000000) >> 24, fp );
00171 fputc( (samplerate & 0x00ff0000) >> 16, fp );
00172 fputc( (samplerate & 0x0000ff00) >> 8, fp );
00173 fputc( (samplerate & 0x000000ff), fp );
00174
00175
00176 fputc( 0, fp );
00177 fputc( 0, fp );
00178 fputc( 0, fp );
00179 fputc( 1, fp );
00180
00181 return 0;
00182 }
00183
00184 static int output_REAL4Vector( FILE *fp, REAL4Vector *data, int wavfmt )
00185 {
00186 REAL4 maxval, minval, midval, scale;
00187 UINT4 i;
00188
00189
00190 maxval = minval = data->data[0];
00191 for ( i = 1; i < data->length; ++i ) {
00192 if ( data->data[i] > maxval )
00193 maxval = data->data[i];
00194 if ( data->data[i] < minval )
00195 minval = data->data[i];
00196 }
00197 midval = 0.5*(maxval + minval);
00198 maxval -= midval;
00199 minval -= midval;
00200 if ( fabs( minval ) > fabs( maxval ) )
00201 maxval = fabs( minval );
00202 scale = LAL_SOUND_MAX / maxval;
00203
00204
00205 if ( wavfmt == 1 ) {
00206 for ( i = 0; i < data->length; ++i ) {
00207 UINT2 val;
00208 val = (UINT2)( scale * (data->data[i] - midval) );
00209 fputc( (val & 0x00ff), fp );
00210 fputc( (val & 0xff00) >> 8, fp );
00211 }
00212 } else {
00213 for ( i = 0; i < data->length; ++i ) {
00214 UINT2 val;
00215 val = (UINT2)(scale*data->data[i]);
00216 fputc( (val & 0xff00) >> 8, fp );
00217 fputc( (val & 0x00ff), fp );
00218 }
00219 }
00220 return 0;
00221 }
00222
00223 static int output_REAL8Vector( FILE *fp, REAL8Vector *data, int wavfmt )
00224 {
00225 REAL4 maxval, minval, midval, scale;
00226 UINT4 i;
00227
00228
00229 maxval = minval = data->data[0];
00230 for ( i = 1; i < data->length; ++i ) {
00231 if ( data->data[i] > maxval )
00232 maxval = data->data[i];
00233 if ( data->data[i] < minval )
00234 minval = data->data[i];
00235 }
00236 midval = 0.5*(maxval + minval);
00237 maxval -= midval;
00238 minval -= midval;
00239 if ( fabs( minval ) > fabs( maxval ) )
00240 maxval = fabs( minval );
00241 scale = LAL_SOUND_MAX / maxval;
00242
00243
00244 if ( wavfmt == 1 ) {
00245 for ( i = 0; i < data->length; ++i ) {
00246 UINT2 val;
00247 val = (UINT2)( scale * (data->data[i] - midval) );
00248 fputc( (val & 0x00ff), fp );
00249 fputc( (val & 0xff00) >> 8, fp );
00250 }
00251 } else {
00252 for ( i = 0; i < data->length; ++i ) {
00253 UINT2 val;
00254 val = (UINT2)(scale*data->data[i]);
00255 fputc( (val & 0xff00) >> 8, fp );
00256 fputc( (val & 0x00ff), fp );
00257 }
00258 }
00259
00260 return 0;
00261 }
00262
00263
00264 int XLALAudioWAVRecordREAL4TimeSeries( FILE *fp, REAL4TimeSeries *series )
00265 {
00266 static const char * func = "XLALAudioWAVRecordREAL4TimeSeries";
00267 INT4 samplerate;
00268 UINT4 datasize;
00269 FILE *fpout;
00270
00271 if ( ! series )
00272 XLAL_ERROR( func, XLAL_EFAULT );
00273 if ( ! series->data )
00274 XLAL_ERROR( func, XLAL_EINVAL );
00275 if ( ! series->data->length )
00276 XLAL_ERROR( func, XLAL_EBADLEN );
00277
00278 datasize = series->data->length * sizeof( UINT2 );
00279 samplerate = (INT4)(1.0/series->deltaT);
00280 if ( samplerate < 1 )
00281 XLAL_ERROR( func, XLAL_EINVAL );
00282
00283 fpout = fopen_if_null( fp, series->name, "wav" );
00284 if ( ! fpout )
00285 XLAL_ERROR( func, XLAL_EIO );
00286
00287
00288 output_wav_hdr( fpout, samplerate, datasize );
00289
00290
00291 output_REAL4Vector( fpout, series->data, 1 );
00292
00293 if ( !fp )
00294 fclose( fpout );
00295
00296 return 0;
00297 }
00298
00299
00300 int XLALAudioWAVRecordREAL8TimeSeries( FILE *fp, REAL8TimeSeries *series )
00301 {
00302 static const char * func = "XLALAudioWAVRecordREAL8TimeSeries";
00303 INT4 samplerate;
00304 UINT4 datasize;
00305 FILE *fpout;
00306
00307 if ( ! series )
00308 XLAL_ERROR( func, XLAL_EFAULT );
00309 if ( ! series->data )
00310 XLAL_ERROR( func, XLAL_EINVAL );
00311 if ( ! series->data->length )
00312 XLAL_ERROR( func, XLAL_EBADLEN );
00313
00314 datasize = series->data->length * sizeof( UINT2 );
00315 samplerate = (INT4)(1.0/series->deltaT);
00316 if ( samplerate < 1 )
00317 XLAL_ERROR( func, XLAL_EINVAL );
00318
00319 fpout = fopen_if_null( fp, series->name, "wav" );
00320 if ( ! fpout )
00321 XLAL_ERROR( func, XLAL_EIO );
00322
00323
00324 output_wav_hdr( fpout, samplerate, datasize );
00325
00326
00327 output_REAL8Vector( fpout, series->data, 1 );
00328
00329 if ( !fp )
00330 fclose( fpout );
00331
00332 return 0;
00333 }
00334
00335
00336
00337 int XLALAudioAURecordREAL4TimeSeries( FILE *fp, REAL4TimeSeries *series )
00338 {
00339 static const char * func = "XLALAudioAURecordREAL4TimeSeries";
00340 INT4 samplerate;
00341 UINT4 datasize;
00342 FILE *fpout;
00343
00344 if ( ! series )
00345 XLAL_ERROR( func, XLAL_EFAULT );
00346 if ( ! series->data )
00347 XLAL_ERROR( func, XLAL_EINVAL );
00348 if ( ! series->data->length )
00349 XLAL_ERROR( func, XLAL_EBADLEN );
00350
00351 datasize = series->data->length * sizeof( UINT2 );
00352 samplerate = (INT4)(1.0/series->deltaT);
00353 if ( samplerate < 1 )
00354 XLAL_ERROR( func, XLAL_EINVAL );
00355
00356 fpout = fopen_if_null( fp, series->name, "au" );
00357 if ( ! fpout )
00358 XLAL_ERROR( func, XLAL_EIO );
00359
00360
00361 output_au_hdr( fpout, samplerate, datasize );
00362
00363
00364 output_REAL4Vector( fpout, series->data, 0 );
00365
00366 if ( !fp )
00367 fclose( fpout );
00368
00369 return 0;
00370 }
00371
00372
00373 int XLALAudioAURecordREAL8TimeSeries( FILE *fp, REAL8TimeSeries *series )
00374 {
00375 static const char * func = "XLALAudioAURecordREAL8TimeSeries";
00376 INT4 samplerate;
00377 UINT4 datasize;
00378 FILE *fpout;
00379
00380 if ( ! series )
00381 XLAL_ERROR( func, XLAL_EFAULT );
00382 if ( ! series->data )
00383 XLAL_ERROR( func, XLAL_EINVAL );
00384 if ( ! series->data->length )
00385 XLAL_ERROR( func, XLAL_EBADLEN );
00386
00387 datasize = series->data->length * sizeof( UINT2 );
00388 samplerate = (INT4)(1.0/series->deltaT);
00389 if ( samplerate < 1 )
00390 XLAL_ERROR( func, XLAL_EINVAL );
00391
00392 fpout = fopen_if_null( fp, series->name, "au" );
00393 if ( ! fpout )
00394 XLAL_ERROR( func, XLAL_EIO );
00395
00396
00397 output_au_hdr( fpout, samplerate, datasize );
00398
00399
00400 output_REAL8Vector( fpout, series->data, 0 );
00401
00402 if ( !fp )
00403 fclose( fpout );
00404
00405 return 0;
00406 }