1 /* Signal Processing Main
2
3 * Copyright (C) 1998 J.A. Bezemer
4 *
5 * Licensed under the terms of the GNU General Public License.
6 * ABSOLUTELY NO WARRANTY.
7 * See the file `COPYING' in this directory.
8 */
9
10 #include "signpr_main.h"
11 #include "signpr_general.h"
12 #ifndef SWIG
13 #include "signpr_infilenm.h"
14 #include "signpr_filtmenu.h"
15 #include "signpr_outfilenm.h"
16 #endif
17 #include "errorwindow.h"
18 #include "signpr_wav.h"
19 #include "fmtheaders.h"
20 #ifndef SWIG
21 #include "clrscr.h"
22 #endif
23 #include "secshms.h"
24 #include <sys/stat.h>
25 #ifndef SWIG
26 #ifndef OLD_CURSES
27 #include <ncurses.h>
28 #else
29 #include <curses.h>
30 #endif
31 #else
32 #include <stdio.h>
33 #endif
34 #include <string.h>
35 #include <stdlib.h>
36
37 #ifndef SWIG
38 int
signproc_get_options(char * startdir,char * infilename,char * outfilename,scrollmenu_t * filtlist,int * filtnumbers,char ** helptexts,scrollmenu_t * selectedfilts,int * usetracktimes,int * usebeginendtime,double * begintime,double * endtime)39 signproc_get_options (char *startdir, char *infilename, char *outfilename,
40 scrollmenu_t * filtlist, int *filtnumbers,
41 char **helptexts, scrollmenu_t * selectedfilts,
42 int *usetracktimes, int *usebeginendtime,
43 double *begintime, double *endtime)
44 {
45 int currscreen = 0;
46 int options_ready = 0;
47 int returnval = 0; /* 0: Cancel, 1: OK */
48 char oldinfilename[250];
49 struct stat buf;
50
51 oldinfilename[0] = '\0';
52
53 do
54 switch (currscreen)
55 {
56 case 0:
57 switch (signproc_select_infile (startdir, infilename))
58 /* 0: Cancel,
59 1: PreviousScreen,
60 2: NextScreen/Start */
61 {
62 case 0:
63 options_ready = 1;
64 returnval = 0;
65 break;
66 case 2:
67 currscreen = 1;
68 break;
69 /* default: currscreen+=0 */
70 }
71 break;
72
73 case 1:
74 if (strcmp (infilename, oldinfilename))
75 {
76 strcpy (oldinfilename, infilename);
77 stat (infilename, &buf);
78 if (buf.st_size < sizeof (wavhead))
79 *endtime = 0;
80 else
81 *endtime = (buf.st_size - sizeof (wavhead))
82 / (2 * 2 * 44100.);
83 *begintime = 0;
84 /* *usetracktimes = 1; Is static now.
85 *usebeginendtime = 0; */
86 }
87
88 switch (signproc_select_filters (filtlist, filtnumbers, helptexts,
89 selectedfilts, usetracktimes,
90 usebeginendtime, begintime, endtime))
91 /* 0: Cancel,
92 1: PreviousScreen,
93 2: NextScreen/Start */
94 {
95 case 0:
96 options_ready = 1;
97 returnval = 0;
98 break;
99 case 1:
100 currscreen = 0;
101 break;
102 case 2:
103 currscreen = 2;
104 break;
105 /* default: currscreen+=0 */
106 }
107 break;
108
109 case 2:
110 switch (signproc_select_outfile (startdir, outfilename))
111 /* 0: Cancel,
112 1: PreviousScreen,
113 2: NextScreen/Start */
114 {
115 case 0:
116 options_ready = 1;
117 returnval = 0;
118 break;
119 case 1:
120 currscreen = 1;
121 break;
122 case 2:
123 returnval = 1;
124 options_ready = 1;
125 break;
126 /* default: currscreen+=0 */
127 }
128 break;
129 }
130 while (!options_ready);
131
132 return returnval;
133 }
134 #endif /* SWIG */
135
136 long totalsize_samples;
137 long current_total_sample;
138 long tracksize_samples;
139 long current_sample;
140
141 #define TRACKS_TEXT "[Tracks]"
142 #define NUM_OF_TRACKS_TEXT "Number_of_tracks="
143
144 #define notMORE_VERBOSE
145
146 int
load_track_times(char * filename,beginendsample_t * tracktimes,int * number_of_tracks)147 load_track_times (char *filename, beginendsample_t * tracktimes,
148 int *number_of_tracks)
149 /* Returns: 0: error, 1: OK */
150 {
151 char tempstring[250];
152 char tempstring2[250];
153 FILE *tracksfile;
154 long tracks_pos;
155 int i;
156 double seconds;
157
158 strcpy (tempstring, filename);
159 strcat (tempstring, ".tracks");
160
161 tracksfile = fopen (tempstring, "r");
162
163 if (tracksfile == NULL)
164 return 0;
165
166 tempstring[0] = '\0';
167 while (!feof (tracksfile) &&
168 strncasecmp (tempstring, TRACKS_TEXT, strlen (TRACKS_TEXT)))
169 fgets (tempstring, 250, tracksfile);
170
171 if (feof (tracksfile)) /* [Tracks] on last line => stop reading */
172 {
173 #ifdef MORE_VERBOSE
174 error_window ("[Tracks] not found.");
175 #endif
176 fclose (tracksfile);
177 return 0;
178 }
179
180 tracks_pos = ftell (tracksfile);
181
182 tempstring[0] = '\0';
183 while (!feof (tracksfile) && strncasecmp (tempstring,
184 NUM_OF_TRACKS_TEXT, strlen (NUM_OF_TRACKS_TEXT)))
185 fgets (tempstring, 250, tracksfile);
186
187 if (strncasecmp (tempstring, NUM_OF_TRACKS_TEXT,
188 strlen (NUM_OF_TRACKS_TEXT)))
189 {
190 #ifdef MORE_VERBOSE
191 error_window ("Number_of_tracks not found.");
192 #endif
193 fclose (tracksfile);
194 return 0;
195 }
196
197 *number_of_tracks = atoi (tempstring + strlen (NUM_OF_TRACKS_TEXT));
198
199 if (*number_of_tracks < 1 || *number_of_tracks > 99)
200 {
201 #ifdef MORE_VERBOSE
202 error_window ("Wrong number or tracks.");
203 #endif
204 fclose (tracksfile);
205 return 0;
206 }
207
208 for (i = 1; i <= *number_of_tracks; i++)
209 {
210 sprintf (tempstring2, "Track%02dstart=", i); /* Start time */
211 fseek (tracksfile, tracks_pos, SEEK_SET);
212
213 tempstring[0] = '\0';
214 while (!feof (tracksfile) && strncasecmp (tempstring,
215 tempstring2, strlen (tempstring2)))
216 fgets (tempstring, 250, tracksfile);
217
218 if (strncasecmp (tempstring, tempstring2, strlen (tempstring2)))
219 {
220 #ifdef MORE_VERBOSE
221 error_window ("TrackXXstart not found.");
222 #endif
223 fclose (tracksfile);
224 return 0;
225 }
226
227 tempstring[strlen (tempstring) - 1] = '\0'; /* Del \n */
228 if (!hmsf2fsec (tempstring + strlen (tempstring2), &seconds))
229 {
230 #ifdef MORE_VERBOSE
231 error_window ("Could not convert start time.");
232 #endif
233 fclose (tracksfile);
234 return 0;
235 }
236
237 tracktimes[i].begin = 44100 * seconds;
238
239 sprintf (tempstring2, "Track%02dend=", i); /* End time */
240 fseek (tracksfile, tracks_pos, SEEK_SET);
241
242 tempstring[0] = '\0';
243 while (!feof (tracksfile) && strncasecmp (tempstring,
244 tempstring2, strlen (tempstring2)))
245 fgets (tempstring, 250, tracksfile);
246
247 if (strncasecmp (tempstring, tempstring2, strlen (tempstring2)))
248 {
249 #ifdef MORE_VERBOSE
250 error_window ("TrackXXend not found.");
251 #endif
252 fclose (tracksfile);
253 return 0;
254 }
255
256 tempstring[strlen (tempstring) - 1] = '\0'; /* Del \n */
257 if (!hmsf2fsec (tempstring + strlen (tempstring2), &seconds))
258 {
259 #ifdef MORE_VERBOSE
260 error_window ("Could not convert end time.");
261 #endif
262 fclose (tracksfile);
263 return 0;
264 }
265
266 tracktimes[i].end = 44100 * seconds;
267 }
268
269 fclose (tracksfile);
270 return 1;
271 }
272
273
274 void
275 #ifndef SWIG
signproc_main(char * startdir)276 signproc_main (char *startdir)
277 #else
278 signproc_main (char *infilename, char *outfilename, int number_of_filters, int *filter_type)
279 #endif
280 {
281 #ifndef SWIG
282 char infilename[250];
283 char outfilename[250];
284 #endif
285 char baseoutfilename[250];
286 char outfileextension[250];
287
288 /* The menu settings are made static to allow the selected
289 filters and settings to be remembered between invocations */
290
291 #ifndef SWIG
292 static int first_entry = 1;
293 static scrollmenu_t filtlist;
294 static char *filtlist_items[MAX_FILTERS + 10];
295 static int filtnumbers[MAX_FILTERS + 10];
296 static char *helptexts[MAX_FILTERS + 10];
297 static scrollmenu_t selectedfilts;
298 static char *selectedfilts_items[MAX_FILTERS];
299 #else
300 int j;
301 #endif
302 static int usebeginendtime = 0, usetracktimes = 1;
303 static double begintime = 0, endtime = 0;
304
305 struct stat buf;
306 int i;
307 char *charptr;
308 #ifndef SWIG
309 int in_ch;
310 #endif
311 beginendsample_t tracktimes[100]; /* max. 99 tracks: 1 (!) - 99 */
312
313 int number_of_tracks;
314 #ifndef SWIG
315 if (first_entry)
316 {
317 filtlist.items = filtlist_items; /* malloc also works :) */
318 make_filterlist (&filtlist, filtnumbers, helptexts);
319
320 selectedfilts.items = selectedfilts_items;
321 number_of_filters = 0;
322 selectedfilts.number = 0;
323
324 /* Default filter: Conditional Median Filter II:
325
326 ******* NOTE: The exact number must be changed when new filters are added!
327 */
328 selectedfilts.items[number_of_filters] = filtlist.items[7];
329 filter_type[number_of_filters] = filtnumbers[7];
330 parampointerarray[number_of_filters] =
331 (parampointer_t) malloc (sizeof (param_t));
332 param_defaults (parampointerarray[number_of_filters], filtnumbers[7]);
333 number_of_filters++;
334 selectedfilts.number = number_of_filters;
335 selectedfilts.selected = number_of_filters - 1;
336 /* ----- End (default filter) */
337
338 first_entry = 0;
339 }
340
341 infilename[0] = '\0';
342 outfilename[0] = '\0';
343
344 if (!signproc_get_options (startdir, infilename, outfilename,
345 &filtlist, filtnumbers, helptexts, &selectedfilts,
346 &usetracktimes, &usebeginendtime, &begintime, &endtime))
347 return;
348 #else
349 for (j=0;j<number_of_filters;j++) {
350 parampointerarray[j] =
351 (parampointer_t) malloc (sizeof (param_t));
352 param_defaults (parampointerarray[j], filter_type[j]);
353 }
354 #endif
355
356 strcpy (baseoutfilename, outfilename);
357 strcpy (outfileextension, ".wav");
358
359 /* IF there is a last '.' AND it's after
360 the last '/' THEN make a new basename
361 and extension */
362 if ((charptr = strrchr (outfilename, '.')) != NULL &&
363 strchr (charptr, '/') == NULL
364 )
365 {
366 baseoutfilename[charptr - outfilename] = '\0';
367 strcpy (outfileextension, charptr);
368 }
369
370 if (usebeginendtime)
371 {
372 number_of_tracks = 1;
373 tracktimes[1].begin = begintime * 44100;
374 tracktimes[1].end = endtime * 44100;
375 }
376 else if (usetracktimes)
377 {
378 if (!load_track_times (infilename, tracktimes, &number_of_tracks))
379 {
380 error_window ("No (correct) track information is available for \
381 the specified source file.");
382 return;
383 }
384 }
385 else
386 /* entire file */
387 {
388 number_of_tracks = 1;
389 stat (infilename, &buf);
390 tracktimes[1].begin = 0;
391 tracktimes[1].end = (buf.st_size - sizeof (wavhead)) / (2 * 2);
392 }
393
394 totalsize_samples = 0; /* calculate sample totals */
395 current_total_sample = 0;
396 for (i = 1; i <= number_of_tracks; i++)
397 totalsize_samples += tracktimes[i].end - tracktimes[i].begin;
398
399 if (!openwavsource (infilename))
400 return; /* open source */
401
402 #ifndef SWIG
403 def_prog_mode (); /* save terminal state */
404 #endif
405 for (i = 1; i <= number_of_tracks; i++)
406 {
407 #ifndef SWIG
408 clearscreen (SIGNPR_PROCESSING_HEADERTEXT);
409 error_window_display ("", " Cancel ");
410 mvprintw (ERROR_WINDOW_Y, ERROR_WINDOW_X + 1,
411 "Track: %2d of %d.", i, number_of_tracks);
412 nodelay (stdscr, TRUE); /* don't wait for a key */
413 #else
414 printf ("Track: %2d of %d.\n", i, number_of_tracks);
415 #endif
416
417 /* calculate #samples for this track */
418 tracksize_samples = tracktimes[i].end - tracktimes[i].begin + 1;
419
420 /* seek to beginsample */
421 if (!seeksamplesource (tracktimes[i].begin))
422 {
423 #ifndef SWIG
424 reset_prog_mode ();
425 nodelay (stdscr, FALSE);
426 #endif
427 error_window ("The start position of the track could not be \
428 found. This track will be skipped.");
429 break;
430 }
431
432 if (number_of_tracks > 1) /* make outfile name */
433 sprintf (outfilename, "%s%02d%s", baseoutfilename,
434 i, outfileextension);
435
436 /* open destination file */
437 if (!openwavdest (outfilename, tracksize_samples * 4))
438 {
439 #ifndef SWIG
440 reset_prog_mode ();
441 nodelay (stdscr, FALSE);
442 #endif
443 error_window ("The destination file could not be opened. This \
444 track will be skipped.");
445 break;
446 }
447
448 #ifndef SWIG
449 init_filters ();
450 #else
451 init_filters (number_of_filters, filter_type);
452 #endif
453
454 /* process the signal */
455 for (current_sample = 0; current_sample < tracksize_samples;
456 current_sample++)
457 {
458
459 #ifndef SWIG
460 if (!(current_sample % 4000))
461 /* progress indicator */
462 {
463 mvprintw (ERROR_WINDOW_Y + 1, ERROR_WINDOW_X + 1,
464 "Done: %3ld%% track", (long)
465 ((100. * current_sample) / tracksize_samples));
466 mvprintw (ERROR_WINDOW_Y + 2, ERROR_WINDOW_X + 1,
467 " %3ld%% total", (long)
468 ((100. * current_total_sample) / totalsize_samples));
469 move (0, 79);
470 refresh ();
471
472 in_ch = getch ();
473 if (in_ch == 27 || in_ch == 13 || in_ch == KEY_ENTER)
474 {
475 reset_prog_mode ();
476 #ifndef SWIG
477 nodelay (stdscr, FALSE);
478 closewavdest ();
479 #endif
480 closewavsource ();
481 delete_filters ();
482 return;
483 }
484 }
485 #endif
486 /* process one sample */
487 #ifndef SWIG
488 writesampledest (get_sample_from_filter (number_of_filters - 1));
489 #else
490 writesampledest (get_sample_from_filter (number_of_filters - 1, filter_type));
491 #endif
492
493 current_total_sample++; /* update total count */
494 }
495
496 closewavdest (); /* close destination */
497 #ifndef SWIG
498 delete_filters (); /* delete filters */
499 #else
500 delete_filters (filter_type);
501 #endif
502 }
503
504 closewavsource (); /* close source */
505
506 #ifndef SWIG
507 reset_prog_mode (); /* reset terminal state */
508 nodelay (stdscr, FALSE);
509 #endif
510 }
511