home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / misc / sci / gfft / source / ok.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-05  |  8.9 KB  |  375 lines

  1. /***************************************************************************
  2.  *          Copyright (C) 1994  Charles P. Peterson                  *
  3.  *         4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
  4.  *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
  5.  *                                                                         *
  6.  *          This is free software with NO WARRANTY.                  *
  7.  *          See gfft.c, or run program itself, for details.              *
  8.  *              Support is available for a fee.                      *
  9.  ***************************************************************************
  10.  *
  11.  * Program:     gfft--General FFT analysis
  12.  * File:        ok.c
  13.  * Purpose:     OK! Do it!  (Whatever it is to be done)
  14.  * Author:      Charles Peterson (CPP)
  15.  * History:     23-August-1993 CPP; Created.
  16.  *              5-Aug-94 CPP (1.05); Fix nameless append mode
  17.  * Comment:
  18.  */
  19.  
  20. #include <string.h>
  21. #include "gfft.h"
  22. #include "settings.h" /* Power, Amplitude, ReadPtr */
  23. #include "format.h"   /* ID_8SVX */
  24.  
  25.  
  26. static void check_output_parameters (BOOLEAN do_it_for_real);
  27. static void check_plot_parameters (void);
  28.  
  29. static BOOLEAN temporary_name_used = FALSE;
  30.  
  31. /*
  32.  * First, the interface(s)
  33.  */
  34.  
  35. char *ok (char *arguments)
  36. {
  37.     if (InputFormat.zero != 0)
  38.     {
  39.     int sample_width = (InputFormat.bits > 8) ? 16 : 8;
  40.     InputFormat.zero = ((unsigned long) 0xffffffff >> 
  41.                 (33 - sample_width)) + (unsigned long) 1;
  42.     }
  43.     do_ok (TRUE);
  44.     return arguments;
  45. }
  46.  
  47. char *re_plot (char *arguments)
  48. {
  49.     check_plot_parameters ();
  50.     if (WriteName && strlen(WriteName))
  51.     {
  52.     OkWriteName = WriteName;  /* Probably used Append to load pre-ex */
  53.     }
  54.     if (!OkWriteName || !strlen(OkWriteName))
  55.     {
  56.     error_message (NO_WRITE_FILE);
  57.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  58.     }
  59.     do_re_plot ();
  60.     return arguments;
  61. }
  62.  
  63. char *re_output (char *arguments)
  64. {
  65.     check_output_parameters (TRUE);
  66.     do_re_output ();
  67.     if (WritePtr != stdout) 
  68.     {
  69.     fclose (WritePtr);
  70.     WritePtr = NULL;
  71.     }
  72.     if (Plot)
  73.     {
  74.     ok_plot ();
  75.     }
  76.     if (temporary_name_used) WriteName = NULL;
  77.     return arguments;
  78. }
  79.  
  80. /*
  81.  * Now, the 'main routine' used by OK
  82.  */
  83.  
  84. ULONG do_ok (BOOLEAN do_it_for_real)
  85. {
  86.     ULONG bins_used = 0;
  87.  
  88.     if (!ReadPtr)
  89.     {
  90.     error_message (NO_READ_FILE);
  91.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  92.     }
  93.     if (NumberBins == INVALID_BINS)
  94.     {
  95.     error_message (INVALID_BINS_SPEC);
  96.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  97.     }
  98.     if (Interleave == INVALID_INTERLEAVE)
  99.     {
  100.     error_message (INVALID_INTERLEAVE_SPEC);
  101.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  102.     }
  103.     check_output_parameters (do_it_for_real);
  104.  
  105.     if (FileFormat)
  106.     {
  107.     if (!FileFormatOK)
  108.     {
  109.         error_message (FORMAT_NOT_OK);
  110.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  111.     }
  112.     if ((OneShotOnly || RepeatOnly) && FileFormat != ID_8SVX)
  113.     {
  114.         error_message (ONESHOT_BUT_NOT_8SVX);
  115.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  116.     }
  117.     OkRate = (Rate == AUTO_RATE) ? FileRate : Rate;/* user may ovride */
  118.     OkOffset = FileDataOffset;
  119.     OkChannels = FileChannels;
  120.  
  121.     OkOctaveOffset = ok_octave_offset (TRUE);
  122.  
  123.     if (OkOctaveOffset == 0)
  124.     {
  125.         ULONG available_frames = FileFrames;
  126.  
  127.         OkStartFrame = StartFrame;
  128.         OkStartFrame += (RepeatOnly) ? FileOneShotHiFrames : 0;
  129.         available_frames -= (RepeatOnly) ? FileOneShotHiFrames : 0;
  130.         available_frames -= (OneShotOnly) ? FileRepeatHiFrames : 0;
  131.         OkFrames = available_frames - StartFrame;
  132.         if (OkFrames < 1)
  133.         {
  134.         error_message (NOT_ENOUGH_FRAMES);
  135.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  136.         }
  137.     }
  138.     else
  139.     {
  140.     /*
  141.      * Deal with multi-octave stuff (and, OneShot/Repeat stuff here too)
  142.      * since user asked for higher octave
  143.      * We use indirection inherent in OkFrames and OkStartFrame.
  144.      * (Otherwise, format reader defaults FileFrames to first octave.)
  145.      *
  146.      * NOTE!  Currently multi-octaves are only supported for 8SVX.
  147.      * Also, I ought to move this stuff back into the format module for
  148.      * better modularity.  Someday.
  149.      */
  150.         ULONG octave_and_oneshot_offset = 0;
  151.         int power2 = 1;
  152.         int i;
  153.  
  154.         for (i = 0; i < OkOctaveOffset; i++)
  155.         {
  156.         octave_and_oneshot_offset += power2 * FileFrames;
  157.         power2 *= 2;
  158.         }
  159.         OkFrames = power2 * FileFrames;
  160.         if (RepeatOnly)
  161.         {
  162.         OkFrames -= power2 * FileOneShotHiFrames;
  163.         octave_and_oneshot_offset += power2 * FileOneShotHiFrames;
  164.         }
  165.         if (OneShotOnly)
  166.         {
  167.         OkFrames -= power2 * FileRepeatHiFrames;
  168.         }
  169.         OkStartFrame = StartFrame + octave_and_oneshot_offset;
  170.         OkFrames -= StartFrame;
  171.         if (OkFrames < 1)
  172.         {
  173.         error_message (NOT_ENOUGH_FRAMES);
  174.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  175.         }
  176.     }
  177.     /*
  178.      * Now, see if we have enough frames for user's specification
  179.      */
  180.     if (Frames < OkFrames)
  181.     {
  182.         OkFrames = Frames;
  183.     }
  184.     else
  185.     {
  186.         if (Frames != ULONG_MAX)
  187.         {
  188.         error_message (NOT_ENOUGH_FRAMES);
  189.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  190.         }
  191.     }
  192.     }
  193.     else /* Unformatted file */
  194.     {
  195.     if (Rate == AUTO_RATE)
  196.     {
  197.         error_message (NO_RATE_SPECIFIED);
  198.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  199.     }
  200.     OkRate = Rate;
  201.     OkOffset = StartByte;
  202.     if (FileFrames == 0)  /* If file length unknown */
  203.     {
  204.         OkFrames = ULONG_MAX;
  205.         OkStartFrame = StartFrame;
  206.     }
  207.     else
  208.     {
  209.         if (FileFrames <= StartFrame) /* StartFrame is 0 based */
  210.         {
  211.         error_message (NOT_ENOUGH_FRAMES);
  212.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  213.         }
  214.         OkFrames = FileFrames - StartFrame;
  215.         OkStartFrame = StartFrame;
  216.     }
  217.     OkChannels = 1;     /* unformatted files must have 1 channel now */
  218.     }
  219.     if (Channel > OkChannels || Channel < 1)
  220.     {
  221.     error_message (SPEC_CHANNEL_UNAVAIL);
  222.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  223.     }
  224.     /*
  225.      * To permit multiple analyses without redundantly entering filename
  226.      * it is reset to beginning here
  227.      */
  228.     ok_rewind ();
  229.  
  230.     if (Power || Amplitude)
  231.     {
  232.     if (Time3D)
  233.     {
  234.         bins_used = ok_time3d_spectrum (do_it_for_real);
  235.     }
  236.     else
  237.     {
  238.         bins_used = ok_spectrum (do_it_for_real);
  239.     }
  240.     }
  241.     else
  242.     {
  243.     bins_used = ok_fft (do_it_for_real);
  244.     }
  245.     if (do_it_for_real)
  246.     {
  247.     if (WritePtr != stdout)
  248.     {
  249.         fclose (WritePtr);
  250.         WritePtr = NULL;
  251.     }
  252.     if (Plot)
  253.     {
  254.         ok_plot ();
  255.     }
  256.     if (temporary_name_used) WriteName = NULL;
  257.     }
  258.     return bins_used;
  259. }
  260.  
  261.     
  262. /*
  263.  * Now, the checking and utilty routines
  264.  */
  265.  
  266. /*
  267.  *  User selects 1 for lowest octave, 2 for second, etc.
  268.  *   (Special case...0 for highest)
  269.  * however, 8SVX octaves are stored in order highest first
  270.  * so, we compute OkOctaveOffset to match storage order
  271.  */
  272.  
  273. int ok_octave_offset (BOOLEAN report_error)
  274. {
  275.     int octave_offset = 0;
  276.     if (Octave != 0)
  277.     {
  278.     octave_offset = FileOctaves - Octave;
  279.     if (octave_offset < 0)
  280.     {
  281.         if (report_error) error_message (OCTAVE_NOT_PRESENT);
  282.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  283.     }
  284.     }
  285.     return octave_offset;
  286. }
  287.  
  288.  
  289. static void check_output_parameters (BOOLEAN do_it_for_real)
  290. {
  291.  
  292.     temporary_name_used = FALSE;
  293.  
  294.     if (Rate == INVALID_RATE)   /* Last rate command was invalid */
  295.     {
  296.     error_message (NO_RATE_SPECIFIED);
  297.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  298.     }
  299.     if (SmoothingSegments == INVALID_SMOOTHING)
  300.     {
  301.     error_message (INVALID_SMOOTHING_SPEC);
  302.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  303.     }
  304.     check_plot_parameters ();
  305.     if (do_it_for_real)
  306.     {
  307.     if (WriteName && strlen (WriteName) && !WritePtr)
  308.     {
  309.         char temp_filename[MAX_PATH+1];
  310.  
  311.         strcpy (temp_filename, WriteName);
  312.         if (Appending)
  313.         {
  314.         set_append (temp_filename);
  315.         }
  316.         else
  317.         {
  318.         set_write (temp_filename);
  319.         }
  320.     }
  321.     if (Plot && !WritePtr)
  322.     {
  323.         extern int Old_File_Count;
  324.         int file_number = (CombinePlots) ? Old_File_Count+1 : 1;
  325.         char *read_name = (ReadName) ? ReadName : NullString;
  326.         char temp_filename[MAX_PATH+1];
  327.         char temp_name[MAX_PATH+1];
  328.  
  329.         temporary_name_used = TRUE;
  330.  
  331.         stcgfn (temp_filename, read_name);  /* SAS/C SYSTEM DEPENDENT */
  332.         sprintf (temp_name, TEMP_DATAFILE_NAME, temp_filename,
  333.              file_number);
  334.         /*
  335.          * (1.05)
  336.          */
  337.         if (Appending)
  338.         {
  339.         set_append (temp_name);
  340.         }
  341.         else
  342.         {
  343.         set_write (temp_name);
  344.         }
  345.     }
  346.     if (!WritePtr)
  347.     {
  348.         error_message (NO_WRITE_FILE);
  349.         RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  350.     }
  351.     OkWriteName = WriteName;
  352.  
  353.     } /* end if (do_it_for_real) */
  354. }
  355.  
  356.  
  357. static void check_plot_parameters (void)
  358. {
  359.     if (WritePtr == stdout && Plot)
  360.     {
  361.     error_message (CANT_PLOT_FROM_STDOUT);
  362.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  363.     }
  364.     if (RotX == INVALID_ROTATION)
  365.     {
  366.     error_message (INVALID_ROTATION_SPEC);
  367.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  368.     }
  369.     if (RotZ == INVALID_ROTATION)
  370.     {
  371.     error_message (INVALID_ROTATION_SPEC);
  372.     RAISE_ERROR (NOTHING_SPECIAL);  /* longjmp outa here! */
  373.     }
  374. }
  375.