annotate tools/edframe.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 edframe.c Edit (ie. partition) AIM output files.
tomwalters@0 3 ----------
tomwalters@0 4
tomwalters@0 5 The input file must have a model header.
tomwalters@0 6
tomwalters@0 7 Usage: edframe [[-]frame=a[-b]] [[-]time=a[-b]] [[-]freq=a[-b]] [file]
tomwalters@0 8
tomwalters@0 9 Special arguments:
tomwalters@0 10
tomwalters@0 11 -help Print help on stderr.
tomwalters@0 12 -info Print frame size information on the stdout.
tomwalters@0 13 info=fbank Print channel centre-frequency information for the selected
tomwalters@0 14 range of frequencies on the stdout. (This information is based
tomwalters@0 15 on the filterbank parameters given in the input header).
tomwalters@0 16
tomwalters@0 17 Each input frame is a matrix with (0,0) in the bottom left.
tomwalters@0 18 The partition, output for each frame, is a sub-matrix indexed by rows a-to-b
tomwalters@0 19 and columns a-to-b inclusive.
tomwalters@0 20 The partition is specified using args: freq=a-b (rows) and time=a-b (cols).
tomwalters@0 21 A single row or col is specified using a single number: freq=a or time=a.
tomwalters@0 22 Rows (channels) are numbered 0,1,...,frameheight-1 -(lowest freq first).
tomwalters@0 23 Cols (samples) are numbered 0,1,...,framewidth-1.
tomwalters@0 24 The strings "min" and "max" can be used as selectors, meaning eg:
tomwalters@0 25 freq=a-max rows a to frameheight-1
tomwalters@0 26 freq=min-b rows 0 to b
tomwalters@0 27 time=a-max cols a to framewidth-1
tomwalters@0 28 time=min-b cols 0 to b
tomwalters@0 29 The default selector specifies the whole matrix:
tomwalters@0 30 freq=min-max time=min-max
tomwalters@0 31
tomwalters@0 32 Expressing time as cols (along the horizontal axis) and frequency as rows
tomwalters@0 33 (up the vertical axis) applies to most gen programs with the exception of
tomwalters@0 34 genwav (where the vertical axis contains just one wave), and the excitation
tomwalters@0 35 patterns genasa, genepn, and gensep (where frequency is measured as cols
tomwalters@0 36 along the horizontal axis). The horizontal dimension is controlled by the
tomwalters@0 37 "freq" parameter for excitation patterns.
tomwalters@0 38
tomwalters@0 39 The units of the freq selector are Hz or kHz, specifying a range of channels
tomwalters@0 40 in terms of frequency, or if no units are appended, then the selector is
tomwalters@0 41 interpreted as a channel number in the range 0 to frameheight-1.
tomwalters@0 42 When the freq selector is given with frequency units, then the "closest"
tomwalters@0 43 corresponding channel number is used. (This depends upon the parameters
tomwalters@0 44 mincf_afb, maxcf_afb, and dencf_afb as given in the header).
tomwalters@0 45
tomwalters@0 46 The units of the time selector are s or ms, specifying a range of samples
tomwalters@0 47 in terms of time, (seconds and milliseconds respectively), or if no units
tomwalters@0 48 are appended, then the selector is interpreted as a sample number in the
tomwalters@0 49 range 0 to framewidth-1.
tomwalters@0 50
tomwalters@0 51
tomwalters@0 52 When the input consists of a cartoon of multiple frames (eg gensai output)
tomwalters@0 53 then individual frames or subsequences of frames may be selected from the
tomwalters@0 54 input using [[-]frame=a[-b]].
tomwalters@0 55 Input frames are numbered 0,1,2,...,frames-1
tomwalters@0 56 frame=a Select just the a'th frame.
tomwalters@0 57 frame=a-b Select frames from the a'th to b'th inclusive.
tomwalters@0 58 The strings "min" and "max" can be used as selectors, meaning eg:
tomwalters@0 59 frame=min Select the first frame.
tomwalters@0 60 frame=max Select the last frame.
tomwalters@0 61 frame=a-max Select frames from the a'th to the last inclusive.
tomwalters@0 62 frame=min-b Select frames from the first to the b'th inclusive.
tomwalters@0 63 The default selector is for all frames, (ie frame=min-max).
tomwalters@0 64
tomwalters@0 65 The units of the frame selector are s or ms, each specifying a frame which
tomwalters@0 66 is "closest" to the given time, being the frame number which is the greatest
tomwalters@0 67 integer multiple of the framestep (frstep_aid) which does not exceed the
tomwalters@0 68 given time, measured from the start of the input file.
tomwalters@0 69 If no units are appended, then the selector is interpreted as a frame number.
tomwalters@0 70
tomwalters@0 71 The output frames are preceded by a model header, so that the partition for
tomwalters@0 72 each frame can be plotted using the option "useprevious=on".
tomwalters@0 73
tomwalters@0 74 The "Header" option controls the output of the modified header. When it is
tomwalters@0 75 set Header=off then a header is not output.
tomwalters@0 76
tomwalters@0 77 The "Transpose" option is a matrix transpose (swap rows and columns) of the
tomwalters@0 78 output partition of each input frame.
tomwalters@0 79 When a frame partition has a height greater than it's width (ie. cols < rows)
tomwalters@0 80 then setting Transpose=on may provide a preferable display orientation.
tomwalters@0 81 For example, this enables a very narrow (eg. single column) time-slice to be
tomwalters@0 82 plotted horizontally, so that a time-slice of filterbank output may be
tomwalters@0 83 plotted as a spectrum on a horizontal frequency axis.
tomwalters@0 84
tomwalters@0 85
tomwalters@0 86 Examples:
tomwalters@0 87 ---------
tomwalters@0 88
tomwalters@0 89 Edited output may be displayed using the "useprevious" option, for example:
tomwalters@0 90
tomwalters@0 91 genXXX ... output=stdout file1 | edframe ... > file2.XXX
tomwalters@0 92 genXXX useprevious=on file2
tomwalters@0 93
tomwalters@0 94 Note that that file2.XXX must have a different base-name to the genXXX input
tomwalters@0 95 (file1) because genXXX will remove any file1.XXX as a side-effect.
tomwalters@0 96
tomwalters@0 97
tomwalters@0 98 Information on the output is printed on the stdout. For example:
tomwalters@0 99 Print size information for gensai output for all frames.
tomwalters@0 100
tomwalters@0 101 gensai output=stdout ... | edframe -info
tomwalters@0 102
tomwalters@0 103 Print channel centre-frequency information for genbmm output for the 1kHz
tomwalters@0 104 channel, and then for channel numbers 37 to 50.
tomwalters@0 105 (To print the exact centre-frequency occupied by a given channel).
tomwalters@0 106
tomwalters@0 107 genbmm output=stdout ... | edframe info=fbank freq=1kHz
tomwalters@0 108 genbmm output=stdout ... | edframe info=fbank freq=37-50
tomwalters@0 109
tomwalters@0 110
tomwalters@0 111 Selecting particular frames from AIM output.
tomwalters@0 112 -------------------------------------------
tomwalters@0 113
tomwalters@0 114 1. Plot gennap output and its transpose.
tomwalters@0 115
tomwalters@0 116 gennap output=stdout ... | edframe > file1.sai
tomwalters@0 117 gennap output=stdout ... | edframe Tran=on > file2.sai
tomwalters@0 118 gensai useprevious=on file1
tomwalters@0 119 gensai useprevious=on file2
tomwalters@0 120
tomwalters@0 121 2. Select and plot frame 2 (ie. the 3rd frame) of gensai output.
tomwalters@0 122
tomwalters@0 123 gensai output=stdout ... | edframe frame=2 > file.sai
tomwalters@0 124 gensai useprevious=on file
tomwalters@0 125
tomwalters@0 126 3. Select the frames of gensai output which start between 16ms and 47ms from
tomwalters@0 127 the start of it's input. (When the option frstep_aid=16ms then this would
tomwalters@0 128 select the 2nd and 3rd frames).
tomwalters@0 129
tomwalters@0 130 gensai output=stdout ... | edframe frame=16ms-47ms > file.sai
tomwalters@0 131
tomwalters@0 132 4. Select the 5th to the last frame inclusively of gensai output.
tomwalters@0 133
tomwalters@0 134 gensai output=stdout ... | edframe frame=4-max > file.sai
tomwalters@0 135
tomwalters@0 136 5. Select the first frame of genepn output and plot the spectrum.
tomwalters@0 137
tomwalters@0 138 genepn output=stdout ... | edframe frame=min > file1.epn
tomwalters@0 139 genepn useprevious=on file1
tomwalters@0 140
tomwalters@0 141
tomwalters@0 142 Editing frames to select particular frequency ranges or channels (ie rows).
tomwalters@0 143 --------------------------------------------------------------------------
tomwalters@0 144
tomwalters@0 145 6. Select and plot the channel with centre-frequency closest to 1kHz from
tomwalters@0 146 gennap output.
tomwalters@0 147
tomwalters@0 148 gennap output=stdout ... | edframe freq=1kHz > file.nap
tomwalters@0 149 gennap useprevious=on file
tomwalters@0 150
tomwalters@0 151 7. Select and plot channel 40 then the channel with the lowest and then
tomwalters@0 152 the highest centre-frequency over all frames of gensai output.
tomwalters@0 153
tomwalters@0 154 gensai output=stdout ... | edframe freq=40 > file.sai
tomwalters@0 155 gensai useprevious=on file
tomwalters@0 156
tomwalters@0 157 gensai output=stdout ... | edframe freq=min > file.sai
tomwalters@0 158 gensai useprevious=on file
tomwalters@0 159
tomwalters@0 160 gensai output=stdout ... | edframe freq=max > file.sai
tomwalters@0 161 gensai useprevious=on file
tomwalters@0 162
tomwalters@0 163 8. Select and plot all channels of genbmm output from channel 10 to
tomwalters@0 164 the channel with centre-frequency closest to 1kHz inclusively.
tomwalters@0 165
tomwalters@0 166 genbmm output=stdout ... | edframe freq=10-1000Hz > file.bmm
tomwalters@0 167 genbmm useprevious=on file
tomwalters@0 168
tomwalters@0 169 9. Select and plot a portion of the spectrum from the first frame of genepn
tomwalters@0 170 output between 1kHz and 2kHz.
tomwalters@0 171 Note: frequency controls the horizontal (ie cols) dimension for genepn.
tomwalters@0 172
tomwalters@0 173 genepn output=stdout ... | edframe frame=min freq=1kHz-2kHz > file.epn
tomwalters@0 174 genepn useprevious=on file
tomwalters@0 175
tomwalters@0 176
tomwalters@0 177 Editing frames to select particular time slices (ie cols).
tomwalters@0 178 ---------------------------------------------------------
tomwalters@0 179
tomwalters@0 180 10. Plot column (ie sample) 100 of the 3rd frame of gensai output as a row.
tomwalters@0 181
tomwalters@0 182 gensai output=stdout ... | edframe frame=2 time=100 Tran=on > file.sai
tomwalters@0 183 gensai useprevious=on file
tomwalters@0 184
tomwalters@0 185 11. Plot column of sample at 20ms from start of gennap output as a row
tomwalters@0 186
tomwalters@0 187 gennap output=stdout ... | edframe time=20ms Tran=on > file.nap
tomwalters@0 188 gennap useprevious=on file
tomwalters@0 189
tomwalters@0 190 12. Edit a wave to select the stretch between 4ms and 16ms, strip the
tomwalters@0 191 header and plot the resulting wave.
tomwalters@0 192
tomwalters@0 193 genwav output=stdout ... | edframe time=4ms-16ms Header=off > file
tomwalters@0 194 genwav file
tomwalters@0 195
tomwalters@0 196
tomwalters@0 197 Editing frames to select partitions.
tomwalters@0 198 -----------------------------------
tomwalters@0 199
tomwalters@0 200 13. Plot a partition of channels 40 to 44 over the last 5ms (ie near the
tomwalters@0 201 trigger point on the right of the image) of all frames of gensai output.
tomwalters@0 202 Then plot a partition of frequency range 1kHz to 1.5kHz over the first
tomwalters@0 203 20ms (on the left of the image) of all frames of gensai output.
tomwalters@0 204
tomwalters@0 205 gensai pwidth=35ms nwidth=0 output=stdout ... | edframe time=30ms-max > file.sai
tomwalters@0 206 gensai useprevious=on file
tomwalters@0 207 gensai output=stdout ... | edframe freq=1kHz-1.5kHz time=min-20ms > file.sai
tomwalters@0 208 gensai useprevious=on file
tomwalters@0 209
tomwalters@0 210 14. Plot the highest-frequency channel over the last 20ms of gennap output.
tomwalters@0 211
tomwalters@0 212 gennap output=stdout ... | edframe freq=max time=20ms-max > file.sai
tomwalters@0 213 gennap useprevious=on file
tomwalters@0 214
tomwalters@0 215
tomwalters@0 216 */
tomwalters@0 217
tomwalters@0 218
tomwalters@0 219 #include <stdio.h>
tomwalters@0 220 #include <math.h>
tomwalters@0 221 #include "header.h"
tomwalters@0 222 #include "options.h"
tomwalters@0 223 #include "units.h"
tomwalters@0 224 #include "strmatch.h"
tomwalters@0 225 #include "freqs.c"
tomwalters@0 226
tomwalters@0 227 char application[] = "Edit AIM output frames. " ;
tomwalters@0 228
tomwalters@0 229 static char *helpstr, *debugstr, *fstr, *tstr, *cfstr, *infostr, *transtr, *headstr ;
tomwalters@0 230
tomwalters@0 231 static Options option[] = {
tomwalters@0 232 { "help" , "off" , &helpstr , "help" , DEBUG },
tomwalters@0 233 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
tomwalters@0 234 { "frame" , "min-max" , &fstr , "select frames inclusively" , VAL },
tomwalters@0 235 { "time" , "min-max" , &tstr , "time (or sample number) partition" , VAL },
tomwalters@0 236 { "freq" , "min-max" , &cfstr , "frequency (or channel number) partition" , VAL },
tomwalters@0 237 { "Transpose" , "off" , &transtr , "transpose each output partition" , SETFLAG },
tomwalters@0 238 { "Header" , "on" , &headstr , "output header" , SETFLAG },
tomwalters@0 239 { "info" , "off" , &infostr , "print size and channel centre-frequency information" , SETFLAG },
tomwalters@0 240 ( char * ) 0 } ;
tomwalters@0 241
tomwalters@0 242
tomwalters@0 243 char *limitstr ;
tomwalters@0 244 char *qualstr ;
tomwalters@0 245 char *minstr ;
tomwalters@0 246 char *maxstr ;
tomwalters@0 247 char *denstr ;
tomwalters@0 248 char *chansstr ;
tomwalters@0 249
tomwalters@0 250 double *frequencies ;
tomwalters@0 251
tomwalters@0 252
tomwalters@0 253 int frameheight, framewidth ; /* Parameters read from header */
tomwalters@0 254 int frames, framebytes ;
tomwalters@0 255 int frstep ;
tomwalters@0 256 int samplerate ;
tomwalters@0 257
tomwalters@0 258 int applic ;
tomwalters@0 259 int format ;
tomwalters@0 260 int rows, cols, numframes ;
tomwalters@0 261 int Newrows, Newcols, Newnumframes ;
tomwalters@0 262
tomwalters@0 263 int Newframeheight, Newframewidth ;
tomwalters@0 264 int Newframes, Newframebytes ;
tomwalters@0 265
tomwalters@0 266 int Transpose ;
tomwalters@0 267
tomwalters@0 268
tomwalters@0 269 main(argc, argv)
tomwalters@0 270 int argc ;
tomwalters@0 271 char *argv[] ;
tomwalters@0 272 {
tomwalters@0 273 FILE *fopen(), *fp = (FILE *) 0 ;
tomwalters@0 274 char *header, *Header();
tomwalters@0 275 char *val1, *val2, *headerstring() ;
tomwalters@0 276 short *frame ;
tomwalters@0 277 int i,j,k, a,b, xa,xb, ya,yb;
tomwalters@0 278 char c, Info=0 ;
tomwalters@0 279
tomwalters@0 280 fp = openopts( option,argc,argv ) ;
tomwalters@0 281 if ( !isoff( helpstr ) )
tomwalters@0 282 helpopts( helpstr, argv[0], application, option ) ;
tomwalters@0 283
tomwalters@0 284 Transpose = ison( transtr ) ;
tomwalters@0 285
tomwalters@0 286 if ( (header = ReadHeader(fp)) == (char *) 0 ) {
tomwalters@0 287 fprintf(stderr,"edframe: header not found\n");
tomwalters@0 288 exit(1);
tomwalters@0 289 }
tomwalters@0 290 frameheight = HeaderInt( header, "frameheight" );
tomwalters@0 291 framewidth = HeaderInt( header, "framewidth" );
tomwalters@0 292 frames = HeaderInt( header, "frames" );
tomwalters@0 293 samplerate = HeaderSamplerate( header );
tomwalters@0 294
tomwalters@0 295 if ( ( applic = Applic( header) ) < 0 ) {
tomwalters@0 296 fprintf(stderr,"edframe: application name not found in header\n" ) ;
tomwalters@0 297 exit( 1 ) ;
tomwalters@0 298 }
tomwalters@0 299 format = Format( applic ) ;
tomwalters@0 300 frame_to_matrix( format, &rows, &cols, &numframes, frameheight, framewidth, frames ) ;
tomwalters@0 301 framebytes = rows * cols * sizeof(short) ;
tomwalters@0 302
tomwalters@0 303 if ( format > WAV ) { /* if not genwav */
tomwalters@0 304 limitstr = headerstring( header, "bwmin_afb" );
tomwalters@0 305 qualstr = headerstring( header, "quality_afb" );
tomwalters@0 306 minstr = headerstring( header, "mincf_afb" );
tomwalters@0 307 maxstr = headerstring( header, "maxcf_afb" );
tomwalters@0 308 denstr = headerstring( header, "dencf_afb" );
tomwalters@0 309 chansstr = headerstring( header, "channels_afb" );
tomwalters@0 310
tomwalters@0 311 SetErbParameters( to_Hz( limitstr, samplerate ), atof( qualstr ) ) ;
tomwalters@0 312 if( OptionInt( chansstr ) == 0 )
tomwalters@0 313 frequencies = GenerateCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), atof( denstr ) ) ;
tomwalters@0 314 else
tomwalters@0 315 frequencies = NumberedCenterFrequencies( to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ), OptionInt( chansstr ) ) ;
tomwalters@0 316 }
tomwalters@0 317 else frequencies = (double *)0 ;
tomwalters@0 318
tomwalters@0 319
tomwalters@0 320 if ( format == SAI ) /* if gensai or genspl */
tomwalters@0 321 frstep = to_p( headerstring( header, "frstep_aid" ), samplerate ) ;
tomwalters@0 322 else
tomwalters@0 323 frstep = 1 ;
tomwalters@0 324
tomwalters@0 325
tomwalters@0 326 /* Get limits on specified number of frames */
tomwalters@0 327
tomwalters@0 328 if ( getvals( fstr, &val1, &val2, "-" ) == BADVAL ) {
tomwalters@0 329 fprintf(stderr,"edframe: bad frame selector [%s]\n", fstr ) ;
tomwalters@0 330 exit( 1 ) ;
tomwalters@0 331 }
tomwalters@0 332 if ( ismin( val1 ) ) a = 0 ;
tomwalters@0 333 else if ( ismax( val1 ) ) a = numframes - 1 ;
tomwalters@0 334 else if ( Units( val1 ) ) a = (int)to_p( val1, samplerate ) / frstep ;
tomwalters@0 335 else a = atoi( val1 ) ;
tomwalters@0 336
tomwalters@0 337 if ( isempty( val2 ) ) b = a ;
tomwalters@0 338 else if ( ismin( val2 ) ) b = 0 ;
tomwalters@0 339 else if ( ismax( val2 ) ) b = numframes - 1 ;
tomwalters@0 340 else if ( Units( val2 ) ) b = (int)to_p( val2, samplerate ) / frstep ;
tomwalters@0 341 else b = atoi( val2 ) ;
tomwalters@0 342
tomwalters@0 343 if ( ison( debugstr ) ) {
tomwalters@0 344 printf("samplerate=%d val1=[%s] val2=[%s] a=%d b=%d numframes=%d\n", samplerate, val1,val2,a,b,numframes);
tomwalters@0 345 }
tomwalters@0 346
tomwalters@0 347 if ( a<0 || a>b || b>numframes ) {
tomwalters@0 348 if ( b>numframes ) fprintf(stderr,"edframe: bad frame selector [just %d frames available]\n", numframes );
tomwalters@0 349 else fprintf(stderr,"edframe: bad frame selector \n" );
tomwalters@0 350 exit(1);
tomwalters@0 351 }
tomwalters@0 352
tomwalters@0 353
tomwalters@0 354 if ( format == EPN ) /* kludge for excitation patterns with horizontal freq axis */
tomwalters@0 355 swap( &rows, &cols ) ;
tomwalters@0 356
tomwalters@0 357
tomwalters@0 358 /* Get limits on specified time (ie samples or cols) */
tomwalters@0 359
tomwalters@0 360 if ( getvals( tstr, &val1, &val2, "-" ) == BADVAL ) {
tomwalters@0 361 fprintf(stderr,"edframe: bad time selector [%s]\n", tstr ) ;
tomwalters@0 362 exit( 1 ) ;
tomwalters@0 363 }
tomwalters@0 364 if ( ismin( val1 ) ) xa = 0 ;
tomwalters@0 365 else if ( ismax( val1 ) ) xa = cols-1 ;
tomwalters@0 366 else if ( Units( val1 ) ) xa = to_p( val1, samplerate ) ;
tomwalters@0 367 else xa = atoi( val1 ) ;
tomwalters@0 368
tomwalters@0 369 if ( isempty( val2 ) ) xb = xa ;
tomwalters@0 370 else if ( ismin( val2 ) ) xb = 0 ;
tomwalters@0 371 else if ( ismax( val2 ) ) xb = cols-1 ;
tomwalters@0 372 else if ( Units( val2 ) ) xb = to_p( val2, samplerate ) ;
tomwalters@0 373 else xb = atoi( val2 ) ;
tomwalters@0 374
tomwalters@0 375 /* Get limits on specified freqency (ie channels or rows) */
tomwalters@0 376
tomwalters@0 377 if ( getvals( cfstr, &val1, &val2, "-" ) == BADVAL ) {
tomwalters@0 378 fprintf(stderr,"edframe: bad frequency selector [%s]\n", cfstr ) ;
tomwalters@0 379 exit( 1 ) ;
tomwalters@0 380 }
tomwalters@0 381 if ( ismin( val1 ) ) ya = 0 ;
tomwalters@0 382 else if ( ismax( val1 ) ) ya = rows-1 ;
tomwalters@0 383 else if ( Units( val1 ) ) ya = closest( to_Hz( val1, samplerate ), frequencies, rows ) ;
tomwalters@0 384 else ya = atoi( val1 ) ;
tomwalters@0 385
tomwalters@0 386 if ( isempty( val2 ) ) yb = ya ;
tomwalters@0 387 else if ( ismin( val2 ) ) yb = 0 ;
tomwalters@0 388 else if ( ismax( val2 ) ) yb = rows-1 ;
tomwalters@0 389 else if ( Units( val2 ) ) yb = closest( to_Hz( val2, samplerate ), frequencies, rows ) ;
tomwalters@0 390 else yb = atoi( val2 ) ;
tomwalters@0 391
tomwalters@0 392
tomwalters@0 393 if ( format == EPN ) { /* excitation patterns have horizontal freq axis */
tomwalters@0 394 swap( &xa, &ya ) ;
tomwalters@0 395 swap( &xb, &yb ) ;
tomwalters@0 396 swap( &rows, &cols ) ;
tomwalters@0 397 }
tomwalters@0 398
tomwalters@0 399 if ( ya<0 || yb>=rows || ya>yb || xa<0 || xb>=cols || xa>xb ) {
tomwalters@0 400 fprintf(stderr,"edframe: bad specifiers [xa=%d xb=%d ya=%d yb=%d]\n", xa,xb,ya,yb ) ;
tomwalters@0 401 fprintf(stderr," input frames have %d rows and %d columns \n", rows, cols ) ;
tomwalters@0 402 exit(1);
tomwalters@0 403 }
tomwalters@0 404
tomwalters@0 405 Newrows = yb - ya + 1 ;
tomwalters@0 406 Newcols = xb - xa + 1 ;
tomwalters@0 407 Newnumframes = b - a + 1 ;
tomwalters@0 408
tomwalters@0 409 if ( Transpose ) swap( &Newrows, &Newcols ) ;
tomwalters@0 410
tomwalters@0 411 matrix_to_frame( format, Newrows, Newcols, Newnumframes, &Newframeheight, &Newframewidth, &Newframes ) ;
tomwalters@0 412 Newframebytes = Newframewidth * Newframeheight * sizeof(short) ;
tomwalters@0 413
tomwalters@0 414 if ( !isoff( infostr ) ) {
tomwalters@0 415 if ( ison( infostr ) ) printinfo() ;
tomwalters@0 416 if ( isstr( infostr, "fbank" ) ) printfbank( xa, xb, ya, yb ) ;
tomwalters@0 417 exit( 0 ) ;
tomwalters@0 418 }
tomwalters@0 419 if ( ison( debugstr ) ) {
tomwalters@0 420 printf( "rows=%d cols=%d numframes=%d\n", rows,cols,numframes);
tomwalters@0 421 printf( "a=%d b=%d ya=%d yb=%d xa=%d xb=%d\n", a,b,ya,yb,xa,xb ) ;
tomwalters@0 422 printf( "Newrows=%d Newcols=%d Newnumframes=%d\n", Newrows,Newcols,Newnumframes);
tomwalters@0 423 printf( "Newframeheight=%d Newframewidth=%d Newframes=%d\n", Newframeheight, Newframewidth, Newframes ) ;
tomwalters@0 424 printf( "framebytes=%d Newframebytes=%d\n", framebytes, Newframebytes ) ;
tomwalters@0 425 exit( 1 ) ;
tomwalters@0 426 }
tomwalters@0 427
tomwalters@0 428 if ( ison( headstr ) )
tomwalters@0 429 WriteHeader( Header(header, ya,yb), stdout );
tomwalters@0 430
tomwalters@0 431
tomwalters@0 432 /* Allocate space for framebytes of data */
tomwalters@0 433
tomwalters@0 434 if ( (frame = (short *)malloc( framebytes )) == NULL ) {
tomwalters@0 435 fprintf(stderr,"edframe: malloc out of space\n");
tomwalters@0 436 exit(1);
tomwalters@0 437 }
tomwalters@0 438
tomwalters@0 439 /* seeks past `a' frames */
tomwalters@0 440
tomwalters@0 441 for ( i = 0 ; i < a && fread( frame,framebytes,1,fp ) ; i++ )
tomwalters@0 442 ;
tomwalters@0 443
tomwalters@0 444 /* edit frames `a' to `b' */
tomwalters@0 445
tomwalters@0 446 if ( Transpose ) {
tomwalters@0 447
tomwalters@0 448 for ( ; i <= b && fread( frame,framebytes,1,fp ) ; i++ ) {
tomwalters@0 449
tomwalters@0 450 if ( format == SAI || format == EPN )
tomwalters@0 451 for ( j=xa ; j<=xb ; j++ )
tomwalters@0 452 for ( k=ya ; k<=yb ; k++ )
tomwalters@0 453 fwrite( frame + k*framewidth + j, sizeof(short), 1, stdout ) ;
tomwalters@0 454 else
tomwalters@0 455 for ( j=ya ; j<=yb ; j++ )
tomwalters@0 456 for ( k=xa ; k<=xb ; k++ )
tomwalters@0 457 fwrite( frame + k*frameheight + j, sizeof(short), 1, stdout ) ;
tomwalters@0 458 }
tomwalters@0 459 }
tomwalters@0 460 else { /* direct (un-transposed) output */
tomwalters@0 461
tomwalters@0 462 for ( ; i <= b && fread( frame,framebytes,1,fp ) ; i++ ) {
tomwalters@0 463
tomwalters@0 464 if ( format == SAI || format == EPN )
tomwalters@0 465 for ( j=ya ; j<=yb ; j++ )
tomwalters@0 466 fwrite( frame + j*framewidth + xa, sizeof(short), Newcols, stdout ) ;
tomwalters@0 467 else
tomwalters@0 468 for ( j=xa ; j<=xb ; j++ )
tomwalters@0 469 fwrite( frame + j*frameheight + ya, sizeof(short), Newrows, stdout ) ;
tomwalters@0 470 }
tomwalters@0 471 }
tomwalters@0 472
tomwalters@0 473 fclose(fp);
tomwalters@0 474
tomwalters@0 475 }
tomwalters@0 476
tomwalters@0 477
tomwalters@0 478 /*
tomwalters@0 479 Return an allocated string to the value part of an option in the header
tomwalters@0 480 with the given name. Exit if option not found in header.
tomwalters@0 481 */
tomwalters@0 482
tomwalters@0 483 char *headerstring( header, name )
tomwalters@0 484 char *header, *name ;
tomwalters@0 485 {
tomwalters@0 486 char *valuestr ;
tomwalters@0 487
tomwalters@0 488 if ( (valuestr = HeaderStringOnly( header, name )) == (char *) 0) {
tomwalters@0 489 fprintf(stderr,"edframe: option %s not found in header\n", name);
tomwalters@0 490 exit( 1 ) ;
tomwalters@0 491 }
tomwalters@0 492 return ( valuestr ) ;
tomwalters@0 493 }
tomwalters@0 494
tomwalters@0 495
tomwalters@0 496 int OptionInt( str )
tomwalters@0 497 char *str ;
tomwalters@0 498 {
tomwalters@0 499 if( strcmp( str, "on" ) == 0 )
tomwalters@0 500 return( 1 ) ;
tomwalters@0 501 else if( strcmp( str, "Not_used" ) == 0 )
tomwalters@0 502 return( 0 ) ;
tomwalters@0 503 else
tomwalters@0 504 return( atoi( str ) ) ;
tomwalters@0 505 }
tomwalters@0 506
tomwalters@0 507
tomwalters@0 508 /*
tomwalters@0 509 Copy the original nap header to a new sai header, changing in order:
tomwalters@0 510 maxcf_afb
tomwalters@0 511 mincf_afb
tomwalters@0 512 channels_afb
tomwalters@0 513 frames
tomwalters@0 514 framewidth
tomwalters@0 515 frameheight
tomwalters@0 516 framebytes
tomwalters@0 517 view
tomwalters@0 518 Finally, update the new header_bytes, and return the new header.
tomwalters@0 519 */
tomwalters@0 520
tomwalters@0 521 char *Header( oldheader, ya,yb )
tomwalters@0 522 char *oldheader ;
tomwalters@0 523 int ya,yb ;
tomwalters@0 524 {
tomwalters@0 525 char *saiheader;
tomwalters@0 526 char *p0, *p1, *p2, *s, str[64];
tomwalters@0 527
tomwalters@0 528 saiheader = (char *)malloc( strlen(oldheader) + 64 ) ;
tomwalters@0 529
tomwalters@0 530 p0 = saiheader ;
tomwalters@0 531 p1 = oldheader ;
tomwalters@0 532
tomwalters@0 533
tomwalters@0 534 if ( format > WAV ) { /* if not genwav */
tomwalters@0 535
tomwalters@0 536 /** copy up to maxcf_afb **/
tomwalters@0 537
tomwalters@0 538 p2 = HeaderString( oldheader , "maxcf_afb" ) ;
tomwalters@0 539 while( p1 < p2 )
tomwalters@0 540 *p0++ = *p1++ ;
tomwalters@0 541
tomwalters@0 542 sprintf(str,"%.2fHz\n", frequencies[yb]);
tomwalters@0 543 for (s = str ; *s != '\n' ; )
tomwalters@0 544 *p0++ = *s++;
tomwalters@0 545 *p0++ = *s;
tomwalters@0 546 while (*p1 != '\n')
tomwalters@0 547 *p1++;
tomwalters@0 548 *p1++;
tomwalters@0 549
tomwalters@0 550
tomwalters@0 551 /** copy up to mincf_afb **/
tomwalters@0 552
tomwalters@0 553 p2 = HeaderString( oldheader , "mincf_afb" ) ;
tomwalters@0 554 while( p1 < p2 )
tomwalters@0 555 *p0++ = *p1++ ;
tomwalters@0 556
tomwalters@0 557 sprintf(str,"%.2fHz\n", frequencies[ya]);
tomwalters@0 558 for (s = str ; *s != '\n' ; )
tomwalters@0 559 *p0++ = *s++;
tomwalters@0 560 *p0++ = *s;
tomwalters@0 561 while (*p1 != '\n')
tomwalters@0 562 *p1++;
tomwalters@0 563 *p1++;
tomwalters@0 564
tomwalters@0 565
tomwalters@0 566 /** copy up to channels_afb **/
tomwalters@0 567
tomwalters@0 568 p2 = HeaderString( oldheader , "channels_afb" ) ;
tomwalters@0 569 while( p1 < p2 )
tomwalters@0 570 *p0++ = *p1++ ;
tomwalters@0 571
tomwalters@0 572 sprintf(str,"%d\n", Newframeheight);
tomwalters@0 573 for (s = str ; *s != '\n' ; )
tomwalters@0 574 *p0++ = *s++;
tomwalters@0 575 *p0++ = *s;
tomwalters@0 576 while (*p1 != '\n')
tomwalters@0 577 *p1++;
tomwalters@0 578 *p1++;
tomwalters@0 579
tomwalters@0 580 }
tomwalters@0 581
tomwalters@0 582 /** copy up to frames **/
tomwalters@0 583
tomwalters@0 584 p2 = HeaderString( oldheader , "frames" ) ;
tomwalters@0 585 while( p1 < p2 )
tomwalters@0 586 *p0++ = *p1++ ;
tomwalters@0 587
tomwalters@0 588 sprintf(str,"%d\n", Newframes);
tomwalters@0 589 for (s = str ; *s != '\n' ; )
tomwalters@0 590 *p0++ = *s++;
tomwalters@0 591 *p0++ = *s;
tomwalters@0 592 while (*p1 != '\n')
tomwalters@0 593 *p1++;
tomwalters@0 594 *p1++;
tomwalters@0 595
tomwalters@0 596
tomwalters@0 597 /** copy up to framewidth **/
tomwalters@0 598
tomwalters@0 599 p2 = HeaderString( oldheader , "framewidth" ) ;
tomwalters@0 600 while ( p1 < p2 )
tomwalters@0 601 *p0++ = *p1++ ;
tomwalters@0 602
tomwalters@0 603 sprintf(str,"%d\n", Newframewidth);
tomwalters@0 604 for (s = str ; *s != '\n' ; )
tomwalters@0 605 *p0++ = *s++;
tomwalters@0 606 *p0++ = *s;
tomwalters@0 607 while (*p1 != '\n')
tomwalters@0 608 *p1++;
tomwalters@0 609 *p1++;
tomwalters@0 610
tomwalters@0 611
tomwalters@0 612 /** copy up to frameheight **/
tomwalters@0 613
tomwalters@0 614 p2 = HeaderString( oldheader , "frameheight" ) ;
tomwalters@0 615 while ( p1 < p2 )
tomwalters@0 616 *p0++ = *p1++ ;
tomwalters@0 617
tomwalters@0 618 sprintf(str,"%d\n", Newframeheight);
tomwalters@0 619 for (s = str ; *s != '\n' ; )
tomwalters@0 620 *p0++ = *s++;
tomwalters@0 621 *p0++ = *s;
tomwalters@0 622 while (*p1 != '\n')
tomwalters@0 623 *p1++;
tomwalters@0 624 *p1++;
tomwalters@0 625
tomwalters@0 626
tomwalters@0 627 /** copy up to framebytes **/
tomwalters@0 628
tomwalters@0 629 p2 = HeaderString( oldheader , "framebytes" ) ;
tomwalters@0 630 while ( p1 < p2 )
tomwalters@0 631 *p0++ = *p1++ ;
tomwalters@0 632
tomwalters@0 633 sprintf(str,"%d\n", Newframebytes);
tomwalters@0 634 for (s = str ; *s != '\n' ; )
tomwalters@0 635 *p0++ = *s++;
tomwalters@0 636 *p0++ = *s;
tomwalters@0 637 while (*p1 != '\n')
tomwalters@0 638 *p1++;
tomwalters@0 639 *p1++;
tomwalters@0 640
tomwalters@0 641
tomwalters@0 642 /** copy rest of header **/
tomwalters@0 643
tomwalters@0 644 p2 = HeaderString( oldheader , "Version" ) ;
tomwalters@0 645 while ( p1 < p2 )
tomwalters@0 646 *p0++ = *p1++ ;
tomwalters@0 647
tomwalters@0 648 while (*p1 != '\n')
tomwalters@0 649 *p0++ = *p1++ ;
tomwalters@0 650 *p0++ = *p1++ ;
tomwalters@0 651
tomwalters@0 652
tomwalters@0 653 /** update header_bytes **/
tomwalters@0 654
tomwalters@0 655 sprintf(str, "%0*d", 7, p0-saiheader);
tomwalters@0 656 p0 = HeaderString( saiheader , "header_bytes" ) ;
tomwalters@0 657 s = str;
tomwalters@0 658 while(*p0 != '\n')
tomwalters@0 659 *p0++ = *s++ ;
tomwalters@0 660
tomwalters@0 661
tomwalters@0 662 return saiheader;
tomwalters@0 663 }
tomwalters@0 664
tomwalters@0 665
tomwalters@0 666
tomwalters@0 667
tomwalters@0 668 /* Return the index of the frequency closest to the given "freq" */
tomwalters@0 669
tomwalters@0 670 int closest( freq, frequencies, channels )
tomwalters@0 671 double freq, *frequencies ;
tomwalters@0 672 int channels ;
tomwalters@0 673 {
tomwalters@0 674 int i;
tomwalters@0 675
tomwalters@0 676 if ( frequencies == (double *)0 ) return 0 ;
tomwalters@0 677
tomwalters@0 678 for (i=0 ; i<channels && frequencies[i]<freq ; i++)
tomwalters@0 679 ;
tomwalters@0 680 if (i==channels) return ( i-1 ) ;
tomwalters@0 681 if (i==0) return i ;
tomwalters@0 682 if ( frequencies[i]-freq < freq-frequencies[i-1] ) return i ;
tomwalters@0 683 else return ( i-1 ) ;
tomwalters@0 684 }
tomwalters@0 685
tomwalters@0 686
tomwalters@0 687 /* Return 1 if the str has appended units. Otherwise return 0. */
tomwalters@0 688 /* (A freqency specifier with no units is interpreted as a channel number) */
tomwalters@0 689 Units(str)
tomwalters@0 690 char *str ;
tomwalters@0 691 {
tomwalters@0 692 char *eptr = str + strlen( str ) ;
tomwalters@0 693
tomwalters@0 694 if( isdigit( *--eptr ) ) return 0 ; /* last char is digit, so no units */
tomwalters@0 695 else return 1 ;
tomwalters@0 696 }
tomwalters@0 697
tomwalters@0 698
tomwalters@0 699 printinfo()
tomwalters@0 700 {
tomwalters@0 701 printf( "gen%s output file\n", gen_applics[ applic ] ) ;
tomwalters@0 702 switch ( format ) {
tomwalters@0 703 case WAV : printf( " wave format (array of time points)\n" ) ;
tomwalters@0 704 break ;
tomwalters@0 705 case NAP : printf( " activity-pattern format (by columns, lowest centre-frequency first in each)\n" ) ;
tomwalters@0 706 break ;
tomwalters@0 707 case SGM : printf( " spectrogram format (by columns, lowest centre-frequency first in each)\n" ) ;
tomwalters@0 708 break ;
tomwalters@0 709 case EPN : printf( " excitation-pattern format (array of frequency points per frame)\n" ) ;
tomwalters@0 710 break ;
tomwalters@0 711 case SAI : printf( " auditory-image format (by rows, lowest centre-frequency first per frame)\n" ) ;
tomwalters@0 712 break ;
tomwalters@0 713 }
tomwalters@0 714
tomwalters@0 715 if ( format != WAV && format != EPN ) /* frameheight meaningless for wav and epn */
tomwalters@0 716 printf( " frameheight = %4d channels (%.2fHz to %.2fHz) \n", rows, to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ) ) ;
tomwalters@0 717
tomwalters@0 718 if ( format == EPN ) /* horiz axis is freq for epn, otherwise is time */
tomwalters@0 719 printf( " framewidth = %4d channels (%.2fHz to %.2fHz) \n", cols, to_Hz( minstr, samplerate ), to_Hz( maxstr, samplerate ) ) ;
tomwalters@0 720 else
tomwalters@0 721 printf( " framewidth = %4d samples (%d ms at %dHz samplerate) \n", cols, (int)to_ms( itoa( cols ), samplerate ), samplerate ) ;
tomwalters@0 722
tomwalters@0 723 printf( " frames = %4d \n", numframes ) ;
tomwalters@0 724 printf( " framesize = %4d bytes \n", rows*cols*2 ) ;
tomwalters@0 725 }
tomwalters@0 726
tomwalters@0 727
tomwalters@0 728 printfbank( xa, xb, ya, yb ) /* print filterbank info */
tomwalters@0 729 int xa, xb, ya, yb ;
tomwalters@0 730 {
tomwalters@0 731 int i ;
tomwalters@0 732
tomwalters@0 733 if ( format > WAV ) { /* no filterbank for genwav */
tomwalters@0 734 if ( format == EPN ) /* freq axis is horiz for epn */
tomwalters@0 735 for (i=xa ; i<=xb ; i++)
tomwalters@0 736 printf( "channel %2d. %7.2fHz, %4.2fms, %5.2f samples \n", i, frequencies[i], 1000./frequencies[i], (double)samplerate/frequencies[i] );
tomwalters@0 737 else
tomwalters@0 738 for (i=ya ; i<=yb ; i++)
tomwalters@0 739 printf( "channel %2d. %7.2fHz, %4.2fms, %5.2f samples \n", i, frequencies[i], 1000./frequencies[i], (double)samplerate/frequencies[i] );
tomwalters@0 740 }
tomwalters@0 741 }
tomwalters@0 742
tomwalters@0 743
tomwalters@0 744 /* Swap the values in integer addresses p1 and p2 */
tomwalters@0 745
tomwalters@0 746 swap( p1, p2 )
tomwalters@0 747 int *p1 , *p2 ;
tomwalters@0 748 {
tomwalters@0 749 int tmp ;
tomwalters@0 750
tomwalters@0 751 tmp = *p1 ;
tomwalters@0 752 *p1 = *p2 ;
tomwalters@0 753 *p2 = tmp ;
tomwalters@0 754 }