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