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 }
|