annotate tools/audim.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 audim.c auditory images
tomwalters@0 3 ---------
tomwalters@0 4
tomwalters@0 5 This program provides methods of constructing time-varying auditory
tomwalters@0 6 images from the output of the cochlear model which are alternatives to
tomwalters@0 7 the gensai (stabilized auditory image) program. Correlograms (ie. row-
tomwalters@0 8 wise autocorrelation) and row-wise Fourier transform are provided. The
tomwalters@0 9 program reads an AIM header and the output from the genbmm (basilar mem-
tomwalters@0 10 brane motion) or gennap (neural activity pattern) programs. This is
tomwalters@0 11 divided into contiguous time frames and written on the stdout with an
tomwalters@0 12 appropriate header as if output from the gensai program. This enables
tomwalters@0 13 genbmm or gennap output to be divided into time frames and replayed as a
tomwalters@0 14 cartoon by gensai using the "useprevious" option. Additional processing
tomwalters@0 15 to each frame is optionally available to compute alternative forms of
tomwalters@0 16 auditory image according to the "image" option.
tomwalters@0 17
tomwalters@0 18
tomwalters@0 19 The options "start" and "length" specify the size of the input. The
tomwalters@0 20 options "width" and "frstep" specify the frames which are output. The
tomwalters@0 21 input is divided into frames according to the width option and the
tomwalters@0 22 frstep option.
tomwalters@0 23
tomwalters@0 24 Special option values are:
tomwalters@0 25
tomwalters@0 26 length=max Read all the input from the given start to its end.
tomwalters@0 27 width=max Output framewidth is set equal to the given input
tomwalters@0 28 length, and if this is also "max", then the
tomwalters@0 29 framewidth is the remainder of the input.
tomwalters@0 30 frames=1-max Select the 1st to the last frame inclusively.
tomwalters@0 31 frame=4 Select the 4th frame only.
tomwalters@0 32
tomwalters@0 33 image=off Divide the input into frames for replay as a cartoon.
tomwalters@0 34 image=acgram Compute correlogram of each frame.
tomwalters@0 35 image=ftgram Compute power spectrum of each channel of each frame.
tomwalters@0 36 image=phgram Compute phase spectrum of each channel of each frame.
tomwalters@0 37
tomwalters@0 38 Most options in the input header are copied to the output header. This
tomwalters@0 39 enables options which are needed for the eventual display to pass
tomwalters@0 40 straight through. Some options are set so that they can override the
tomwalters@0 41 input header. For example, the display option is set on to enable
tomwalters@0 42 display even when input has display=off. The animate option can be set
tomwalters@0 43 on even when the input has animate=off. Parts of the header are changed
tomwalters@0 44 for the new sai format: (frames, frameshift, framewidth, frameheight,
tomwalters@0 45 framebytes).
tomwalters@0 46
tomwalters@0 47 Padding:
tomwalters@0 48 The input nap is divided into frames according to the width option (called
tomwalters@0 49 framewidth internally) and the frstep option (called frameshift internally).
tomwalters@0 50 The framewidth is used as the basis for output image frame width:
tomwalters@0 51 the output width is actually the next power-of-2 above twice the framewidth.
tomwalters@0 52 This is because:
tomwalters@0 53 a. fft and acf output is always half the given frame size, due to symmetry,
tomwalters@0 54 so the input must be padded to twice its width.
tomwalters@0 55 b. To use fft, the input must also be a power of two.
tomwalters@0 56 So, each input row is padded out to the next power of two above twice its
tomwalters@0 57 width.
tomwalters@0 58
tomwalters@0 59 Certain display parameters have different default values for different
tomwalters@0 60 applications. The gensai display parameters should be set to the
tomwalters@0 61 appropriate values, in order to plot the cartoon on the same scale. For
tomwalters@0 62 example: when the source application is gennap, set gensai top=1000,
tomwalters@0 63 when the source application is genbmm, set gensai bottom=-100.
tomwalters@0 64
tomwalters@0 65
tomwalters@0 66 Examples:
tomwalters@0 67
tomwalters@0 68 1. An animated normalized autocorrelogram from a nap:
tomwalters@0 69
tomwalters@0 70 gennap len=64ms output=stdout display=off file | audim norm=on anim=on > file.sai
tomwalters@0 71 gensai useprev=on top=1000 cegc -(for landscape plot)
tomwalters@0 72 genspl useprev=on top=1000 pensize=2 cegc -(for spiral plot)
tomwalters@0 73
tomwalters@0 74
tomwalters@0 75 2. To convert a nap to multiple animated frames:
tomwalters@0 76
tomwalters@0 77 gennap len=16ms display=off output=stdout file | audim image=off width=8ms frstep=0.2ms anim=on > file.sai
tomwalters@0 78 gensai useprev=on top=1000 cegc -(for landscape plot)
tomwalters@0 79 genspl useprev=on top=1000 pensize=2 cegc -(for spiral plot)
tomwalters@0 80
tomwalters@0 81 (Note: spirals look better in a square box, so you might use options:
tomwalters@0 82 dencf=1 width=500 height=500 )
tomwalters@0 83
tomwalters@0 84 3. To view the basilar membrane from a cross section, animating the waves on it.
tomwalters@0 85
tomwalters@0 86 genbmm mincf=220 maxcf=660 len=8ms output=stdout display=off file | audim image=off width=1p frstep=1p display=on anim=on | edframe Tran=on > foo.sai
tomwalters@0 87 gensai bott=-100 useprev=on mag=.2 foo
tomwalters@0 88
tomwalters@0 89 or:
tomwalters@0 90
tomwalters@0 91 genbmm mincf=220 maxcf=660 len=32ms output=stdout display=off file | \
tomwalters@0 92 audim image=off width=1p frstep=1p display=on anim=on | \
tomwalters@0 93 edframe Tran=on Header=off > foo
tomwalters@0 94
tomwalters@0 95 x11play -n75 -a500 foo
tomwalters@0 96
tomwalters@0 97 */
tomwalters@0 98
tomwalters@0 99
tomwalters@0 100 #include <stdio.h>
tomwalters@0 101 #include <math.h>
tomwalters@0 102 #include "header.h"
tomwalters@0 103 #include "options.h"
tomwalters@0 104 #include "units.h"
tomwalters@0 105 #include "strmatch.h"
tomwalters@0 106 #include "sigproc.h"
tomwalters@0 107 #include "freqs.c"
tomwalters@0 108
tomwalters@0 109 char applic[] = "Auditory images of neural activity patterns (NAP). " ;
tomwalters@0 110
tomwalters@0 111 static char *helpstr, *debugstr, *dispstr, *anistr, *startstr, *imstr ;
tomwalters@0 112 static char *lengthstr, *widthstr, *shiftstr, *headerstr, *cfstr, *framestr ;
tomwalters@0 113 static char *normstr, *wstr, *sacfstr, *smagstr, *sphstr ;
tomwalters@0 114 static char *blstr, *erbstr ;
tomwalters@0 115
tomwalters@0 116 static Options option[] = {
tomwalters@0 117 { "help" , "off" , &helpstr , "help" , DEBUG },
tomwalters@0 118 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
tomwalters@0 119 { "display" , "on" , &dispstr , "Display output image." , SETFLAG },
tomwalters@0 120 { "animate" , "off" , &anistr , "Animate cartoon." , SETFLAG },
tomwalters@0 121 { "frames" , "1-max" , &framestr , "Select frames inclusively" , VAL },
tomwalters@0 122 { "image" , "acgram" , &imstr , "Form of auditory image." , VAL },
tomwalters@0 123 { "header" , "on" , &headerstr , "Header (for gensai useprevious=on)." , VAL },
tomwalters@0 124 { "start" , "0" , &startstr , "Start point in i/p NAP" , VAL },
tomwalters@0 125 { "length" , "max" , &lengthstr , "Length of i/p NAP to process." , VAL },
tomwalters@0 126 { "frstep" , "16ms" , &shiftstr , "Step between frames of the auditory image." , VAL },
tomwalters@0 127 { "width" , "32ms" , &widthstr , "Width of auditory image." , VAL },
tomwalters@0 128 { "normalize" , "off" , &normstr , "Normalization" , SETFLAG },
tomwalters@0 129 { "window" , "off" , &wstr , "Hamming window" , SETFLAG },
tomwalters@0 130 { "bandlimit" , "off" , &blstr , "Zero outside bandwidth." , SETFLAG },
tomwalters@0 131 { "erbs" , "2" , &erbstr , "Width (in ERBS) of band either side of cf." , SVAL },
tomwalters@0 132 { "align_cf" , "off" , &cfstr , "Align on centre frequency." , SETFLAG },
tomwalters@0 133 { "scale_acf" , "0.025" , &sacfstr , "Scale factor for acf output" , SVAL },
tomwalters@0 134 { "scale_fft" , "0.08" , &smagstr , "Scale factor for fft magnitude output" , SVAL },
tomwalters@0 135 { "scale_phs" , "100" , &sphstr , "Scale factor for fft phase output" , SVAL },
tomwalters@0 136 ( char * ) 0 } ;
tomwalters@0 137
tomwalters@0 138
tomwalters@0 139 int frameheight ; /* Nap parameters read from header */
tomwalters@0 140 int frames, samplerate ;
tomwalters@0 141 int framewidth ; /* width option */
tomwalters@0 142
tomwalters@0 143 int start, length ;
tomwalters@0 144
tomwalters@0 145 int Newframeheight, Newframewidth ; /* Sai parameters to write */
tomwalters@0 146 int Newframes ;
tomwalters@0 147 int Newframeshift ;
tomwalters@0 148 int Newframebytes ;
tomwalters@0 149
tomwalters@0 150
tomwalters@0 151 char *limitstr ; /* Sai parameters used to get centre-frequencies */
tomwalters@0 152 char *qualstr ;
tomwalters@0 153 char *minstr ;
tomwalters@0 154 char *maxstr ;
tomwalters@0 155 char *denstr ;
tomwalters@0 156 char *chansstr ;
tomwalters@0 157 double *frequencies ;
tomwalters@0 158 int nerbs ; /* bandwidth defined as number of erbs either side of cf */
tomwalters@0 159 int bandlimit ; /* flag for zeroing outside bandwidth around centre-freqs */
tomwalters@0 160 int align ; /* flag for aligning centre-freqs */
tomwalters@0 161
tomwalters@0 162 #define NONE 0 /* forms of auditory image */
tomwalters@0 163 #define ACGRAM 1
tomwalters@0 164 #define FTGRAM 2
tomwalters@0 165 #define PHGRAM 3
tomwalters@0 166 int image ;
tomwalters@0 167
tomwalters@0 168 float *buf ; /* fft working space */
tomwalters@0 169 int zeroes ; /* padding */
tomwalters@0 170 float *W ; /* Hamming window for fft */
tomwalters@0 171 short window ; /* flag for window */
tomwalters@0 172
tomwalters@0 173 short debug ; /* flag for debug printf's */
tomwalters@0 174
tomwalters@0 175 main(argc, argv)
tomwalters@0 176 int argc ;
tomwalters@0 177 char *argv[] ;
tomwalters@0 178 {
tomwalters@0 179 FILE *fp ;
tomwalters@0 180 int i, framebytes, startbytes, frameshift, framebyteshift;
tomwalters@0 181 char *header, *SaiHeader();
tomwalters@0 182 short *nap, *frame, *endframe;
tomwalters@0 183 int a, b ;
tomwalters@0 184 char *val1, *val2 ;
tomwalters@0 185
tomwalters@0 186 fp = openopts( option,argc,argv ) ;
tomwalters@0 187 if ( !isoff( helpstr ) )
tomwalters@0 188 helpopts( helpstr, argv[0], applic, option ) ;
tomwalters@0 189
tomwalters@0 190 window = ison( wstr ) ;
tomwalters@0 191 nerbs = atoi( erbstr ) ;
tomwalters@0 192 debug = ison( debugstr ) ;
tomwalters@0 193
tomwalters@0 194 /**** Form of image ****/
tomwalters@0 195
tomwalters@0 196 if ( iststr( imstr, "acgram" ) ) {
tomwalters@0 197 image = ACGRAM ;
tomwalters@0 198 }
tomwalters@0 199 else if ( iststr( imstr, "ftgram" ) ) {
tomwalters@0 200 image = FTGRAM ;
tomwalters@0 201 }
tomwalters@0 202 else if ( iststr( imstr, "phgram" ) ) {
tomwalters@0 203 image = PHGRAM ;
tomwalters@0 204 }
tomwalters@0 205 else if ( isoff( imstr ) ) {
tomwalters@0 206 image = NONE ;
tomwalters@0 207 }
tomwalters@0 208 else {
tomwalters@0 209 fprintf(stderr, "audim: unknown form of auditory image [%s]\n", imstr ) ;
tomwalters@0 210 exit( 1 ) ;
tomwalters@0 211 }
tomwalters@0 212
tomwalters@0 213 align = ison( cfstr ) ;
tomwalters@0 214 bandlimit = ison( blstr ) ;
tomwalters@0 215
tomwalters@0 216
tomwalters@0 217 /**** parse bounds on number of frames ****/
tomwalters@0 218
tomwalters@0 219 if ( getvals( framestr, &val1, &val2, "-" ) == BADVAL ) {
tomwalters@0 220 fprintf(stderr,"audim: bad frame selector [%s]\n", framestr ) ;
tomwalters@0 221 exit( 1 ) ;
tomwalters@0 222 }
tomwalters@0 223 a = atoi( val1 ) ;
tomwalters@0 224 if ( isempty( val2 ) ) b = a ;
tomwalters@0 225 else if ( ismax( val2 ) ) b = 0 ;
tomwalters@0 226 else b = atoi( val2 ) ;
tomwalters@0 227
tomwalters@0 228 if (b<a && b>0) fprintf(stderr,"audim warning: bad frame specifiers\n");
tomwalters@0 229
tomwalters@0 230
tomwalters@0 231 /**** Read header and options to find dimensions of auditory image ****/
tomwalters@0 232
tomwalters@0 233 if ( (header = ReadHeader(fp)) == (char *) 0 ) {
tomwalters@0 234 fprintf(stderr,"audim: header not found\n");
tomwalters@0 235 exit(1);
tomwalters@0 236 }
tomwalters@0 237
tomwalters@0 238 frameheight = HeaderInt( header, "frameheight" );
tomwalters@0 239 frames = HeaderInt( header, "frames" );
tomwalters@0 240 samplerate = HeaderSamplerate( header );
tomwalters@0 241 start = to_p( startstr, samplerate );
tomwalters@0 242 frameshift = to_p( shiftstr, samplerate ) ;
tomwalters@0 243
tomwalters@0 244 if ( ismax( lengthstr ) ) /* Special case for remainder of input */
tomwalters@0 245 length = frames - start ;
tomwalters@0 246 else
tomwalters@0 247 length = to_p( lengthstr, samplerate );
tomwalters@0 248
tomwalters@0 249 if ( start + length > frames ) {
tomwalters@0 250 fprintf(stderr,"audim: nap too small (%d ms) for requested start and length \n", to_ms( frames, samplerate ) );
tomwalters@0 251 exit(1);
tomwalters@0 252 }
tomwalters@0 253
tomwalters@0 254 framebytes = frameheight * length * sizeof(short) ;
tomwalters@0 255 startbytes = frameheight * start * sizeof(short) ;
tomwalters@0 256
tomwalters@0 257 if ( ismax( widthstr ) ) /* Special case for single frame of max width */
tomwalters@0 258 framewidth = length ;
tomwalters@0 259 else
tomwalters@0 260 framewidth = to_p( widthstr, samplerate ) ;
tomwalters@0 261
tomwalters@0 262 frames = ( length - framewidth ) / frameshift ;
tomwalters@0 263 zeroes = getpower( framewidth << 1 ) - framewidth ;
tomwalters@0 264
tomwalters@0 265
tomwalters@0 266 /**** Get centre-frequencies information using info given in header ****/
tomwalters@0 267
tomwalters@0 268 limitstr = HeaderStringOnly( header, "bwmin_afb" );
tomwalters@0 269 qualstr = HeaderStringOnly( header, "quality_afb" );
tomwalters@0 270 minstr = HeaderStringOnly( header, "mincf_afb" );
tomwalters@0 271 maxstr = HeaderStringOnly( header, "maxcf_afb" );
tomwalters@0 272 denstr = HeaderStringOnly( header, "dencf_afb" );
tomwalters@0 273 chansstr = HeaderStringOnly( header, "channels_afb" );
tomwalters@0 274
tomwalters@0 275 SetErbParameters( to_Hz( limitstr ), atof( qualstr ) ) ;
tomwalters@0 276 if( OptionInt( chansstr ) == 0 )
tomwalters@0 277 frequencies = GenerateCenterFrequencies( to_Hz( minstr ), to_Hz( maxstr ), atof( denstr ) ) ;
tomwalters@0 278 else
tomwalters@0 279 frequencies = NumberedCenterFrequencies( to_Hz( minstr ), to_Hz( maxstr ), OptionInt( chansstr ) ) ;
tomwalters@0 280
tomwalters@0 281
tomwalters@0 282 /**** Output frame dimensions (to write into new header) ****/
tomwalters@0 283
tomwalters@0 284 Newframeheight = frameheight ;
tomwalters@0 285
tomwalters@0 286 if ( !align ) {
tomwalters@0 287 if ( image == NONE )
tomwalters@0 288 Newframewidth = framewidth ;
tomwalters@0 289 else
tomwalters@0 290 Newframewidth = ( framewidth + zeroes ) >> 1 ; /* spectral bins */
tomwalters@0 291 }
tomwalters@0 292 else { /* number of bins corresponding to the filter bandwidth */
tomwalters@0 293 switch ( image ) {
tomwalters@0 294 case NONE : Newframewidth = framewidth ;
tomwalters@0 295 break ;
tomwalters@0 296 case ACGRAM : Newframewidth = maxlagwidth( to_Hz( minstr ), nerbs ) ;
tomwalters@0 297 break ;
tomwalters@0 298 case FTGRAM : Newframewidth = maxbandwidth( to_Hz( maxstr ), nerbs, (framewidth+zeroes)>>1 ) ;
tomwalters@0 299 break ;
tomwalters@0 300 }
tomwalters@0 301 }
tomwalters@0 302 Newframeshift = frameshift ;
tomwalters@0 303 Newframebytes = Newframeheight * Newframewidth * sizeof(short) ;
tomwalters@0 304
tomwalters@0 305 if ( frameshift > 0 ) {
tomwalters@0 306 if ( b == 0 )
tomwalters@0 307 Newframes = frames - (a-1) ;
tomwalters@0 308 else
tomwalters@0 309 Newframes = b - (a-1) ;
tomwalters@0 310 }
tomwalters@0 311 else {
tomwalters@0 312 fprintf(stderr,"audim: non-positive frstep [%d]\n", frameshift);
tomwalters@0 313 exit(1);
tomwalters@0 314 }
tomwalters@0 315
tomwalters@0 316
tomwalters@0 317 /**** Check limits etc.. ****/
tomwalters@0 318
tomwalters@0 319 if ( b > frames ) {
tomwalters@0 320 fprintf(stderr,"audim: can't select frame %d out of %d frames\n", b, frames ) ;
tomwalters@0 321 exit(1);
tomwalters@0 322 }
tomwalters@0 323
tomwalters@0 324 if ( length < framewidth ) {
tomwalters@0 325 fprintf(stderr,"audim: nap too small (%d ms) for requested width\n", to_ms( length, samplerate ) );
tomwalters@0 326 exit(1);
tomwalters@0 327 }
tomwalters@0 328
tomwalters@0 329 if (frames<=0) {
tomwalters@0 330 if (frames==0) fprintf(stderr,"audim: zero frames input\n");
tomwalters@0 331 if (frames<0) fprintf(stderr,"audim: garbled number of frames, (start set too big?)\n");
tomwalters@0 332 exit(1);
tomwalters@0 333 }
tomwalters@0 334
tomwalters@0 335 if (a>frames || b>frames)
tomwalters@0 336 fprintf(stderr,"audim warning: bad frame selectors\n");
tomwalters@0 337
tomwalters@0 338
tomwalters@0 339
tomwalters@0 340 if ( debug ) {
tomwalters@0 341 fprintf(stderr, "Header: frames=%d frameheight=%d\n", frames, frameheight ) ;
tomwalters@0 342 fprintf(stderr, "Options: a=%d b=%d start=%d length=%d frameshift=%d framewidth=%d\n", a, b, start, length, frameshift, framewidth ) ;
tomwalters@0 343 fprintf(stderr, "Output: zeroes=%d Newframewidth=%d Newframes=%d \n", zeroes, Newframewidth, Newframes ) ;
tomwalters@0 344 }
tomwalters@0 345
tomwalters@0 346
tomwalters@0 347 /**** Write new sai header ****/
tomwalters@0 348
tomwalters@0 349 if ( ison( headerstr ) )
tomwalters@0 350 WriteHeader( SaiHeader(header), stdout );
tomwalters@0 351
tomwalters@0 352
tomwalters@0 353 /**** Allocate space for framebytes of nap data ****/
tomwalters@0 354
tomwalters@0 355 if ( (nap = (short *)malloc( framebytes )) == NULL ) {
tomwalters@0 356 fprintf(stderr,"audim: malloc out of space\n");
tomwalters@0 357 exit(1);
tomwalters@0 358 }
tomwalters@0 359
tomwalters@0 360
tomwalters@0 361 /**** Allocate and assign window coeffs ****/
tomwalters@0 362
tomwalters@0 363 if ( window )
tomwalters@0 364 W = hamming( framewidth ) ;
tomwalters@0 365
tomwalters@0 366
tomwalters@0 367 /**** Allocate fft working space ****/
tomwalters@0 368
tomwalters@0 369 buf = (float *)malloc( ( framewidth + zeroes ) * sizeof(float) );
tomwalters@0 370
tomwalters@0 371
tomwalters@0 372 /**** Seek to start in blocks of framebytes ****/
tomwalters@0 373
tomwalters@0 374 for (i=framebytes ; i < startbytes ; i += framebytes)
tomwalters@0 375 if ( fread( nap, framebytes, 1, fp ) == NULL ) {
tomwalters@0 376 fprintf(stderr,"audim: missing data after header\n");
tomwalters@0 377 exit(1);
tomwalters@0 378 }
tomwalters@0 379 if ( (startbytes -= (i - framebytes)) > 0 )
tomwalters@0 380 if ( fread( nap, startbytes, 1, fp ) == NULL ) {
tomwalters@0 381 fprintf(stderr,"audim: missing data after header\n");
tomwalters@0 382 exit(1);
tomwalters@0 383 }
tomwalters@0 384
tomwalters@0 385 /**** Read framebytes of i/p nap data ****/
tomwalters@0 386
tomwalters@0 387 if ( fread( nap, framebytes, 1, fp ) == NULL ) {
tomwalters@0 388 fprintf(stderr,"audim: missing data after header\n");
tomwalters@0 389 exit(1);
tomwalters@0 390 }
tomwalters@0 391
tomwalters@0 392 framebyteshift = frameshift * frameheight ;
tomwalters@0 393 nap = nap + (a-1) * framebyteshift ;
tomwalters@0 394 endframe = nap + Newframes * framebyteshift ;
tomwalters@0 395
tomwalters@0 396 switch ( image ) {
tomwalters@0 397 case NONE : fprintf(stderr,"Output framewidth = %dp \n", Newframewidth ) ; break ;
tomwalters@0 398 case ACGRAM : fprintf(stderr,"Output framewidth = %dp Lag range = 0-%dms\n", Newframewidth, (Newframewidth*1000)/samplerate ) ; break ;
tomwalters@0 399 case FTGRAM : fprintf(stderr,"Output framewidth = %dp Frequency range = 0-%dkHz\n", Newframewidth, samplerate/2000 ) ; break ;
tomwalters@0 400 case PHGRAM : break ;
tomwalters@0 401 }
tomwalters@0 402
tomwalters@0 403 for ( frame = nap ; frame < endframe ; frame += framebyteshift ) {
tomwalters@0 404
tomwalters@0 405 fprintf(stderr,"audim: %d / %d\n", a++, frames );
tomwalters@0 406 switch ( image ) {
tomwalters@0 407
tomwalters@0 408 case NONE : writeframe( frame ) ; break ;
tomwalters@0 409 case ACGRAM : acgram( frame ) ; break ;
tomwalters@0 410 case FTGRAM : ftgram( frame ) ; break ;
tomwalters@0 411 case PHGRAM : phgram( frame ) ; break ;
tomwalters@0 412
tomwalters@0 413 }
tomwalters@0 414 }
tomwalters@0 415 fprintf(stderr,"audim: done\n" );
tomwalters@0 416 }
tomwalters@0 417
tomwalters@0 418
tomwalters@0 419
tomwalters@0 420
tomwalters@0 421
tomwalters@0 422 int OptionInt( str )
tomwalters@0 423 char *str ;
tomwalters@0 424 {
tomwalters@0 425 if( strcmp( str, "on" ) == 0 )
tomwalters@0 426 return( 1 ) ;
tomwalters@0 427 else if( strcmp( str, "Not_used" ) == 0 )
tomwalters@0 428 return( 0 ) ;
tomwalters@0 429 else
tomwalters@0 430 return( atoi( str ) ) ;
tomwalters@0 431 }
tomwalters@0 432
tomwalters@0 433
tomwalters@0 434 /*********************** Read header and build new header *****************/
tomwalters@0 435
tomwalters@0 436 /*
tomwalters@0 437 Copy the original nap header to a new sai header, changing in order:
tomwalters@0 438 frames
tomwalters@0 439 frameshift
tomwalters@0 440 framewidth
tomwalters@0 441 frameheight
tomwalters@0 442 framebytes
tomwalters@0 443 animate
tomwalters@0 444 display
tomwalters@0 445 Finally, update the new header_bytes, and return the new header.
tomwalters@0 446 */
tomwalters@0 447
tomwalters@0 448 char *SaiHeader( napheader )
tomwalters@0 449 char *napheader ;
tomwalters@0 450 {
tomwalters@0 451 char *saiheader;
tomwalters@0 452 char *p0, *p1, *p2, *s, str[64];
tomwalters@0 453
tomwalters@0 454 saiheader = (char *)malloc( strlen(napheader) + 256 ) ;
tomwalters@0 455
tomwalters@0 456 p0 = saiheader ;
tomwalters@0 457 p1 = napheader ;
tomwalters@0 458
tomwalters@0 459 /* copy to first item after the header_bytes */
tomwalters@0 460
tomwalters@0 461 p2 = HeaderString( napheader , "header_bytes" ) ;
tomwalters@0 462 while( p1 < p2 )
tomwalters@0 463 *p0++ = *p1++ ;
tomwalters@0 464 while (*p1 != '\n')
tomwalters@0 465 *p0++ = *p1++ ;
tomwalters@0 466 *p0++ = *p1++;
tomwalters@0 467
tomwalters@0 468 /* insert frstep_aid at top of new header */
tomwalters@0 469
tomwalters@0 470 sprintf( str,"frstep_aid=%s\n", shiftstr ) ;
tomwalters@0 471 for (s = str ; *s != '\n' ; )
tomwalters@0 472 *p0++ = *s++;
tomwalters@0 473 *p0++ = *s;
tomwalters@0 474
tomwalters@0 475 /** copy up to frames **/
tomwalters@0 476
tomwalters@0 477 p2 = HeaderString( napheader , "frames" ) ;
tomwalters@0 478 while( p1 < p2 )
tomwalters@0 479 *p0++ = *p1++ ;
tomwalters@0 480
tomwalters@0 481 sprintf(str,"%d\n", Newframes);
tomwalters@0 482 for (s = str ; *s != '\n' ; )
tomwalters@0 483 *p0++ = *s++;
tomwalters@0 484 *p0++ = *s;
tomwalters@0 485 while (*p1 != '\n')
tomwalters@0 486 *p1++;
tomwalters@0 487 *p1++;
tomwalters@0 488
tomwalters@0 489
tomwalters@0 490 /** copy up to frameshift **/
tomwalters@0 491
tomwalters@0 492 p2 = HeaderString( napheader , "frameshift" ) ;
tomwalters@0 493 while ( p1 < p2 )
tomwalters@0 494 *p0++ = *p1++ ;
tomwalters@0 495
tomwalters@0 496 sprintf(str,"%d\n", Newframeshift);
tomwalters@0 497 for (s = str ; *s != '\n' ; )
tomwalters@0 498 *p0++ = *s++;
tomwalters@0 499 *p0++ = *s;
tomwalters@0 500 while (*p1 != '\n')
tomwalters@0 501 *p1++;
tomwalters@0 502 *p1++;
tomwalters@0 503
tomwalters@0 504
tomwalters@0 505 /** copy up to framewidth **/
tomwalters@0 506
tomwalters@0 507 p2 = HeaderString( napheader , "framewidth" ) ;
tomwalters@0 508 while ( p1 < p2 )
tomwalters@0 509 *p0++ = *p1++ ;
tomwalters@0 510
tomwalters@0 511 sprintf(str,"%d\n", Newframewidth);
tomwalters@0 512 for (s = str ; *s != '\n' ; )
tomwalters@0 513 *p0++ = *s++;
tomwalters@0 514 *p0++ = *s;
tomwalters@0 515 while (*p1 != '\n')
tomwalters@0 516 *p1++;
tomwalters@0 517 *p1++;
tomwalters@0 518
tomwalters@0 519
tomwalters@0 520 /** copy up to frameheight **/
tomwalters@0 521
tomwalters@0 522 p2 = HeaderString( napheader , "frameheight" ) ;
tomwalters@0 523 while ( p1 < p2 )
tomwalters@0 524 *p0++ = *p1++ ;
tomwalters@0 525
tomwalters@0 526 sprintf(str,"%d\n", Newframeheight);
tomwalters@0 527 for (s = str ; *s != '\n' ; )
tomwalters@0 528 *p0++ = *s++;
tomwalters@0 529 *p0++ = *s;
tomwalters@0 530 while (*p1 != '\n')
tomwalters@0 531 *p1++;
tomwalters@0 532 *p1++;
tomwalters@0 533
tomwalters@0 534
tomwalters@0 535 /** copy up to framebytes **/
tomwalters@0 536
tomwalters@0 537 p2 = HeaderString( napheader , "framebytes" ) ;
tomwalters@0 538 while ( p1 < p2 )
tomwalters@0 539 *p0++ = *p1++ ;
tomwalters@0 540
tomwalters@0 541 sprintf(str,"%d\n", Newframebytes);
tomwalters@0 542 for (s = str ; *s != '\n' ; )
tomwalters@0 543 *p0++ = *s++;
tomwalters@0 544 *p0++ = *s;
tomwalters@0 545 while (*p1 != '\n')
tomwalters@0 546 *p1++;
tomwalters@0 547 *p1++;
tomwalters@0 548
tomwalters@0 549
tomwalters@0 550 /** copy up to animate_ctn **/
tomwalters@0 551
tomwalters@0 552 p2 = HeaderString( napheader , "animate_ctn" ) ;
tomwalters@0 553 while ( p1 < p2 )
tomwalters@0 554 *p0++ = *p1++ ;
tomwalters@0 555
tomwalters@0 556 sprintf(str,"%s\n", anistr );
tomwalters@0 557 for (s = str ; *s != '\n' ; )
tomwalters@0 558 *p0++ = *s++;
tomwalters@0 559 *p0++ = *s;
tomwalters@0 560 while (*p1 != '\n')
tomwalters@0 561 *p1++;
tomwalters@0 562 *p1++;
tomwalters@0 563
tomwalters@0 564
tomwalters@0 565 /** copy up to display **/
tomwalters@0 566
tomwalters@0 567 p2 = HeaderString( napheader , "display" ) ;
tomwalters@0 568 while ( p1 < p2 )
tomwalters@0 569 *p0++ = *p1++ ;
tomwalters@0 570
tomwalters@0 571 sprintf(str,"%s\n", dispstr );
tomwalters@0 572 for (s = str ; *s != '\n' ; )
tomwalters@0 573 *p0++ = *s++;
tomwalters@0 574 *p0++ = *s;
tomwalters@0 575 while (*p1 != '\n')
tomwalters@0 576 *p1++;
tomwalters@0 577 *p1++;
tomwalters@0 578
tomwalters@0 579
tomwalters@0 580 /** copy rest of header **/
tomwalters@0 581
tomwalters@0 582 p2 = HeaderString( napheader , "Version" ) ;
tomwalters@0 583 while ( p1 < p2 )
tomwalters@0 584 *p0++ = *p1++ ;
tomwalters@0 585
tomwalters@0 586 if ( ( p2 = ApplicString( napheader ) ) == (char *)0 ) {
tomwalters@0 587 fprintf(stderr,"audim: application name not found in header\n");
tomwalters@0 588 exit( 1 ) ;
tomwalters@0 589 }
tomwalters@0 590 while ( p1 < p2 )
tomwalters@0 591 *p0++ = *p1++ ;
tomwalters@0 592
tomwalters@0 593 *p0++ = 's' ; *p0++ = 'a' ; *p0++ = 'i' ; /* copy sai into applic name */
tomwalters@0 594 p1 += 3 ;
tomwalters@0 595
tomwalters@0 596 while (*p1 != '\n')
tomwalters@0 597 *p0++ = *p1++ ;
tomwalters@0 598 *p0++ = *p1++ ;
tomwalters@0 599
tomwalters@0 600
tomwalters@0 601 /** update header_bytes **/
tomwalters@0 602
tomwalters@0 603 sprintf(str, "%0*d", 7, p0-saiheader);
tomwalters@0 604 p0 = HeaderString( saiheader , "header_bytes" ) ;
tomwalters@0 605 s = str;
tomwalters@0 606 while(*p0 != '\n')
tomwalters@0 607 *p0++ = *s++ ;
tomwalters@0 608
tomwalters@0 609
tomwalters@0 610 return saiheader;
tomwalters@0 611 }
tomwalters@0 612
tomwalters@0 613
tomwalters@0 614 /************************** Autocorrelation function ***********************/
tomwalters@0 615
tomwalters@0 616 /* Call acf for each row in auditory image */
tomwalters@0 617
tomwalters@0 618 acgram( frame )
tomwalters@0 619 short *frame ;
tomwalters@0 620 {
tomwalters@0 621 static float scale ;
tomwalters@0 622 static int normalize ;
tomwalters@0 623 static int first = 1 ;
tomwalters@0 624 register int i, j, row, col ;
tomwalters@0 625 short p ;
tomwalters@0 626
tomwalters@0 627 if (first) {
tomwalters@0 628 normalize = ison( normstr ) ;
tomwalters@0 629 scale = 1./(double)( framewidth + zeroes ) * atof( sacfstr ) ;
tomwalters@0 630 first=0;
tomwalters@0 631 }
tomwalters@0 632
tomwalters@0 633 for ( row=0 ; row < frameheight ; row++ ) {
tomwalters@0 634 for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight )
tomwalters@0 635 buf[col] = frame[i] ;
tomwalters@0 636 for ( j=0 ; j<zeroes ; j++ ) /* padding */
tomwalters@0 637 buf[col++] = 0 ;
tomwalters@0 638
tomwalters@0 639 acf( buf, framewidth+zeroes ) ;
tomwalters@0 640
tomwalters@0 641 if ( align || bandlimit )
tomwalters@0 642 writelags( buf, row, (framewidth+zeroes)>>1, Newframewidth, scale ) ;
tomwalters@0 643 else {
tomwalters@0 644 if ( normalize == 0 )
tomwalters@0 645 writebuf( buf, Newframewidth, scale ) ;
tomwalters@0 646 else
tomwalters@0 647 writebuf( buf, Newframewidth, 5000./buf[0] ) ;
tomwalters@0 648 }
tomwalters@0 649 }
tomwalters@0 650 }
tomwalters@0 651
tomwalters@0 652
tomwalters@0 653 /********************************** FFT ************************************/
tomwalters@0 654
tomwalters@0 655 /* Call fft and magnitude spectrum for each row in auditory image */
tomwalters@0 656
tomwalters@0 657 ftgram( frame )
tomwalters@0 658 short *frame ;
tomwalters@0 659 {
tomwalters@0 660 static float scale ;
tomwalters@0 661 static int first = 1 ;
tomwalters@0 662 register int i, j, row, col ;
tomwalters@0 663
tomwalters@0 664 if (first) {
tomwalters@0 665 scale = atof( smagstr ) ;
tomwalters@0 666 first=0;
tomwalters@0 667 }
tomwalters@0 668
tomwalters@0 669 for ( row=0 ; row < frameheight ; row++ ) {
tomwalters@0 670 if ( window )
tomwalters@0 671 for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight )
tomwalters@0 672 buf[col] = frame[i] * W[col] ;
tomwalters@0 673 else
tomwalters@0 674 for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight )
tomwalters@0 675 buf[col] = frame[i] ;
tomwalters@0 676
tomwalters@0 677 for ( j=0 ; j<zeroes ; j++ ) /* padding */
tomwalters@0 678 buf[col++] = 0 ;
tomwalters@0 679
tomwalters@0 680 fft( buf, framewidth+zeroes, 1 ) ;
tomwalters@0 681 mag( buf, framewidth+zeroes ) ;
tomwalters@0 682
tomwalters@0 683 if ( align || bandlimit )
tomwalters@0 684 writebins( buf, row, (framewidth+zeroes)>>1, Newframewidth, scale ) ;
tomwalters@0 685 else
tomwalters@0 686 writebuf( buf, Newframewidth, scale ) ;
tomwalters@0 687 }
tomwalters@0 688 }
tomwalters@0 689
tomwalters@0 690
tomwalters@0 691 /********************************** Phase **********************************/
tomwalters@0 692
tomwalters@0 693 /* Call fft and phase spectrum for each row in auditory image */
tomwalters@0 694
tomwalters@0 695 phgram( frame )
tomwalters@0 696 short *frame ;
tomwalters@0 697 {
tomwalters@0 698 static float scale ;
tomwalters@0 699 static int first = 1 ;
tomwalters@0 700 register int i, j, row, col ;
tomwalters@0 701
tomwalters@0 702 if (first) {
tomwalters@0 703 scale = atof( sphstr ) ;
tomwalters@0 704 first=0;
tomwalters@0 705 }
tomwalters@0 706
tomwalters@0 707 for ( row=0 ; row < frameheight ; row++ ) {
tomwalters@0 708 for ( col=0 , i=row ; col < framewidth ; col++, i+=frameheight )
tomwalters@0 709 buf[col] = frame[i] ;
tomwalters@0 710 for ( j=0 ; j<zeroes ; j++ ) /* padding */
tomwalters@0 711 buf[col++] = 0 ;
tomwalters@0 712
tomwalters@0 713 fft( buf, framewidth+zeroes, 1 ) ;
tomwalters@0 714 phase( buf, framewidth+zeroes ) ;
tomwalters@0 715
tomwalters@0 716 writebuf( buf, Newframewidth, scale ) ;
tomwalters@0 717 }
tomwalters@0 718 }
tomwalters@0 719
tomwalters@0 720
tomwalters@0 721 /**** Write o/p routines ****/
tomwalters@0 722
tomwalters@0 723 writebuf( buf, n, scale ) /* write buffer as scaled shorts */
tomwalters@0 724 float *buf ;
tomwalters@0 725 int n ;
tomwalters@0 726 float scale ;
tomwalters@0 727 {
tomwalters@0 728 register int i ;
tomwalters@0 729 short p ;
tomwalters@0 730
tomwalters@0 731 for (i=0 ; i < n ; i++) {
tomwalters@0 732 p = (short)( buf[i] * scale ) ;
tomwalters@0 733 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 734 }
tomwalters@0 735 }
tomwalters@0 736
tomwalters@0 737
tomwalters@0 738
tomwalters@0 739
tomwalters@0 740 writeframe( frame ) /* Write a nap frame in sai format */
tomwalters@0 741 short *frame ;
tomwalters@0 742 {
tomwalters@0 743 int i, row, col;
tomwalters@0 744
tomwalters@0 745 for (row=0 ; row < frameheight ; row++)
tomwalters@0 746 for (col=0 , i=row ; col < framewidth ; col++, i+=frameheight)
tomwalters@0 747 fwrite( &frame[i], sizeof(short), 1, stdout );
tomwalters@0 748 }
tomwalters@0 749
tomwalters@0 750
tomwalters@0 751 /*
tomwalters@0 752 Write a band of spectral bins around the centre-freq of the given channel.
tomwalters@0 753
tomwalters@0 754 The o/p spectrum is 0 to samplerate/2 Hz, resolved into spectral bins:
tomwalters@0 755 bins = (framewidth + zeroes) / 2
tomwalters@0 756
tomwalters@0 757 For the i'th channel, the centre-frequency cf = frequencies[i].
tomwalters@0 758 Filters are symmetrical bandpass, so considering a bandwidth of 4 ERB
tomwalters@0 759 the side-frequencies at the band limits are:
tomwalters@0 760
tomwalters@0 761 side1 = cf - 2*ERB [Hz]
tomwalters@0 762 side2 = cf + 2*ERB [Hz]
tomwalters@0 763
tomwalters@0 764 Note: side1 < side2
tomwalters@0 765
tomwalters@0 766 Convert frequency to bin number as follows:
tomwalters@0 767 Let centre-frequency cf have bin number j, so that ratios:
tomwalters@0 768 cf/(samplerate/2) = j/bins
tomwalters@0 769 and so:
tomwalters@0 770 j = ( cf*bins ) / ( samplerate/2 )
tomwalters@0 771
tomwalters@0 772 (Similarly for each of the side-frequencies at the 2-ERB band limits).
tomwalters@0 773
tomwalters@0 774 */
tomwalters@0 775
tomwalters@0 776 writebins( buf, chan, bins, maxwidth, scale )
tomwalters@0 777 float *buf ;
tomwalters@0 778 int chan ;
tomwalters@0 779 int bins ; /* number of spectral bins */
tomwalters@0 780 int maxwidth ;
tomwalters@0 781 float scale ;
tomwalters@0 782 {
tomwalters@0 783 double ERB, cf, side1, side2, max ;
tomwalters@0 784 register int i, j, s1, s2 ;
tomwalters@0 785 short p ;
tomwalters@0 786
tomwalters@0 787 ERB = frequencies[chan]/9.26449 + 24.7 ;
tomwalters@0 788 cf = frequencies[chan] ;
tomwalters@0 789 side1 = frequencies[chan] - nerbs*ERB ;
tomwalters@0 790 side2 = frequencies[chan] + nerbs*ERB ;
tomwalters@0 791
tomwalters@0 792 j = (int)( ( cf * bins ) / ( samplerate >> 1 ) + 0.5 ) ; /* rounding */
tomwalters@0 793 s1 = (int)( ( side1 * bins ) / ( samplerate >> 1 ) + 0.5 ) ;
tomwalters@0 794 s2 = (int)( ( side2 * bins ) / ( samplerate >> 1 ) + 0.5 ) ;
tomwalters@0 795
tomwalters@0 796 if ( debug )
tomwalters@0 797 fprintf(stderr,"chan=%d bins=%d maxwidth=%d j=%d side1=%d side2=%d\n",chan,bins,maxwidth,j,s1,s2);
tomwalters@0 798
tomwalters@0 799 /* Plot the given bandwidth, zeroing elsewhere: */
tomwalters@0 800
tomwalters@0 801 if ( bandlimit && !align ) {
tomwalters@0 802
tomwalters@0 803 for ( i=0, p=0 ; i < s1 ; i++ )
tomwalters@0 804 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 805
tomwalters@0 806 for ( ; i < s2 && i < bins ; i++ ) {
tomwalters@0 807 p = (short)( buf[i] * scale ) ;
tomwalters@0 808 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 809 }
tomwalters@0 810
tomwalters@0 811 for ( p=0 ; i < bins ; i++ )
tomwalters@0 812 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 813 }
tomwalters@0 814
tomwalters@0 815 /* Plot the given bandwidth, shifting it to the centre */
tomwalters@0 816
tomwalters@0 817 if ( align ) {
tomwalters@0 818
tomwalters@0 819 /* align on max bin in band
tomwalters@0 820 max = 0 ;
tomwalters@0 821 for ( i=s1 ; i<s2 ; i++ )
tomwalters@0 822 if ( buf[i] >= max ) {
tomwalters@0 823 max = buf[i] ;
tomwalters@0 824 j = i ;
tomwalters@0 825 }
tomwalters@0 826 for ( i=0, p=0 ; i < s1+(maxwidth/2-j) ; i++ )
tomwalters@0 827 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 828 for ( j = s1 ; j < s2 && i < maxwidth ; i++, j++ ) {
tomwalters@0 829 p = (short)( buf[j] * scale ) ;
tomwalters@0 830 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 831 }
tomwalters@0 832 for ( p=0 ; i < maxwidth ; i++ )
tomwalters@0 833 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 834 */
tomwalters@0 835
tomwalters@0 836 j = (maxwidth+s1-s2)/2 ;
tomwalters@0 837 for ( i=0, p=0 ; i < j ; i++ )
tomwalters@0 838 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 839
tomwalters@0 840 for ( j = s1 ; j < s2 ; i++, j++ ) {
tomwalters@0 841 p = (short)( buf[j] * scale ) ;
tomwalters@0 842 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 843 }
tomwalters@0 844 for ( p=0 ; i < maxwidth ; i++ )
tomwalters@0 845 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 846
tomwalters@0 847 }
tomwalters@0 848 }
tomwalters@0 849
tomwalters@0 850
tomwalters@0 851
tomwalters@0 852 /*
tomwalters@0 853 Write a band of acf lags around the centre-period of the given channel.
tomwalters@0 854
tomwalters@0 855 For the i'th channel, the centre-frequency
tomwalters@0 856 Centre-frequency cf = frequencies[i] [Hz]
tomwalters@0 857 Bandwidth ERB = cf/9.26449 + 24.7 [Hz]
tomwalters@0 858 Centre-period cp = samplerate / cf [samples]
tomwalters@0 859
tomwalters@0 860 Filters are symmetrical bandpass, so considering a bandwidth of 4 ERB
tomwalters@0 861
tomwalters@0 862 side1 = samplerate / ( cf - 2*ERB ) [samples]
tomwalters@0 863 side2 = samplerate / ( cf + 2*ERB ) [samples]
tomwalters@0 864
tomwalters@0 865 Note: side2 < side1 since periods
tomwalters@0 866
tomwalters@0 867 Also, successive bins ARE successive lags (in samples).
tomwalters@0 868 */
tomwalters@0 869
tomwalters@0 870
tomwalters@0 871
tomwalters@0 872 writelags( buf, chan, lags, maxwidth, scale )
tomwalters@0 873 float *buf ;
tomwalters@0 874 int chan ;
tomwalters@0 875 int lags ; /* number of acf lags */
tomwalters@0 876 int maxwidth ;
tomwalters@0 877 float scale ;
tomwalters@0 878 {
tomwalters@0 879 double ERB, cp, side1, side2 ;
tomwalters@0 880 register int i, j, s1, s2 ;
tomwalters@0 881 short p ;
tomwalters@0 882
tomwalters@0 883 ERB = frequencies[chan]/9.26449 + 24.7 ;
tomwalters@0 884 cp = (double)samplerate / frequencies[chan] ;
tomwalters@0 885 side1 = (double)samplerate / ( frequencies[chan] - nerbs*ERB ) ;
tomwalters@0 886 side2 = (double)samplerate / ( frequencies[chan] + nerbs*ERB ) ;
tomwalters@0 887
tomwalters@0 888 j = (int)( cp + 0.5 ) ; /* rounding */
tomwalters@0 889 s1 = (int)( side1 + 0.5 ) ;
tomwalters@0 890 s2 = (int)( side2 + 0.5 ) ;
tomwalters@0 891
tomwalters@0 892 if ( debug )
tomwalters@0 893 fprintf(stderr,"chan=%d lags=%d side1=%d side2=%d\n",chan,lags,s1,s2);
tomwalters@0 894
tomwalters@0 895 /* Plot the given bandwidth, zeroing elsewhere: */
tomwalters@0 896
tomwalters@0 897 if ( bandlimit && !align ) {
tomwalters@0 898
tomwalters@0 899 for ( i=0, p=0 ; i < s2 ; i++ )
tomwalters@0 900 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 901
tomwalters@0 902 for ( ; i < s1 && i < lags ; i++ ) {
tomwalters@0 903 p = (short)( buf[i] * scale ) ;
tomwalters@0 904 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 905 }
tomwalters@0 906
tomwalters@0 907 for ( p=0 ; i < lags ; i++ )
tomwalters@0 908 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 909 }
tomwalters@0 910
tomwalters@0 911 /* Plot the given bandwidth, shifting it to the centre */
tomwalters@0 912
tomwalters@0 913 if ( align ) {
tomwalters@0 914
tomwalters@0 915 j = (maxwidth+s2-s1)/2 ;
tomwalters@0 916 for ( i=0, p=0 ; i < j ; i++ )
tomwalters@0 917 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 918
tomwalters@0 919 for ( j = s2 ; j < s1 ; i++, j++ ) {
tomwalters@0 920 p = (short)( buf[j] * scale ) ;
tomwalters@0 921 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 922 }
tomwalters@0 923 for ( p=0 ; i < maxwidth ; i++ )
tomwalters@0 924 fwrite( &p, sizeof(short), 1, stdout ) ;
tomwalters@0 925 }
tomwalters@0 926 }
tomwalters@0 927
tomwalters@0 928
tomwalters@0 929 /*
tomwalters@0 930 Return the number of lags corresponding to a bandwidth of nerbs ERBS either
tomwalters@0 931 side of a given mincf. This will be the max required framewidth.
tomwalters@0 932 */
tomwalters@0 933
tomwalters@0 934 maxlagwidth( mincf, nerbs )
tomwalters@0 935 double mincf ;
tomwalters@0 936 int nerbs ;
tomwalters@0 937 {
tomwalters@0 938 double ERB, side1, side2 ;
tomwalters@0 939
tomwalters@0 940 ERB = mincf/9.26449 + 24.7 ;
tomwalters@0 941 side1 = (double)samplerate / ( mincf - nerbs*ERB ) ;
tomwalters@0 942 side2 = (double)samplerate / ( mincf + nerbs*ERB ) ;
tomwalters@0 943
tomwalters@0 944 return (int)( side1 - side2 ) ;
tomwalters@0 945 }
tomwalters@0 946
tomwalters@0 947
tomwalters@0 948 /*
tomwalters@0 949 Return the number of bins corresponding to a bandwidth of nerbs ERBS either
tomwalters@0 950 side of a given maxcf. This will be the max required framewidth.
tomwalters@0 951 */
tomwalters@0 952
tomwalters@0 953 maxbandwidth( maxcf, nerbs, bins )
tomwalters@0 954 double maxcf ;
tomwalters@0 955 int nerbs ;
tomwalters@0 956 int bins ;
tomwalters@0 957 {
tomwalters@0 958 double ERB, side1, side2 ;
tomwalters@0 959 int s1, s2 ;
tomwalters@0 960
tomwalters@0 961 ERB = maxcf/9.26449 + 24.7 ;
tomwalters@0 962 side1 = maxcf - nerbs*ERB ;
tomwalters@0 963 side2 = maxcf + nerbs*ERB ;
tomwalters@0 964
tomwalters@0 965 /* convert frequencies to bin numbers */
tomwalters@0 966
tomwalters@0 967 s1 = (int)( ( side1 * bins ) / ( samplerate >> 1 ) + 0.5 ) ;
tomwalters@0 968 s2 = (int)( ( side2 * bins ) / ( samplerate >> 1 ) + 0.5 ) ;
tomwalters@0 969
tomwalters@0 970 return (int)( s2 - s1 ) ;
tomwalters@0 971 }
tomwalters@0 972
tomwalters@0 973