/* analyzer.c 
	vi:ts=3 sw=3:
*/


/* read module files and output statistics on them */

/* $Id: analyzer.c,v 4.23 1995/08/27 18:43:08 espie Exp espie $
 * $Log: analyzer.c,v $
 * Revision 4.23  1995/08/27 18:43:08  espie
 * *** empty log message ***
 *
 * Revision 4.22  1995/06/23 09:34:33  espie
 * *** empty log message ***
 *
 * Revision 4.21  1995/05/30  13:08:01  espie
 * ?
 *
 * Revision 4.20  1995/05/15  12:19:43  espie
 * *** empty log message ***
 *
 * Revision 4.19  1995/05/12  13:53:04  espie
 * New synchronization.
 *
 * Revision 4.18  1995/02/21  17:54:32  espie
 * Internal problem: buggy RCS. Fixed logs.
 *
 * Revision 4.13  1995/02/20  22:28:50  espie
 * Spurious bug with # of samples.
 *
 * Revision 4.12  1995/02/20  16:49:58  espie
 * Working.
 *
 * Revision 4.9  1995/02/06  14:50:47  espie
 * Changed sample_info.
 *
 * Revision 4.7  1995/02/01  16:39:04  espie
 * Includes moved to defs.h
 *
 * Revision 4.6  1995/01/28  09:23:59  espie
 * Need (?) a return 0 at the end.
 *
 * Revision 4.1  1994/01/12  16:10:20  espie
 * Fixed up last minute problems.
 * Lots of changes.
 * removed create_note_tables(), run_in_fg().
 * Use new pref scheme.
 * New open_file semantics.
 * Added speed check.
 * Added patch for non termio.
 */

#include "defs.h"

#include "extern.h"
#include "song.h"
#include "tags.h"
#include "prefs.h"

#include <sys/types.h>
#include <sys/stat.h>
#ifdef __NeXT__
#include <sys/dir.h>
#include <sys/dirent.h>
#else
#include <dirent.h>
#endif

ID("$Id: analyzer.c,v 4.23 1995/08/27 18:43:08 espie Exp espie $")

int error;


int use_command[16];
int use_extended[16];

void analyze_block(b, n)
struct block *b;
int n;
   {
   int i, j;
   struct event *e;

   for (i = 0; i < BLOCK_LENGTH; i++)
      {
      int special;

      special = 0;
      for (j = 0; j < NUMBER_TRACKS; j++)
         {
         e = &b->e[j][i];
         switch(e->effect)
            {
#if 0
         case 13: /* skip */
            return;
         case 11: /* fastskip */
            return;
#endif
			case 9:
				if (e->note == 255)
					printf("%d %d %d\n", n, i, j);
				break;
         case 14:
				if (!use_extended[HI(e->parameters)])
					use_extended[HI(e->parameters)] = i+1;
            break;
         case 15:
            if (special != 0 && e->parameters != special)
               putchar('!');
            else
               special = e->parameters;
         default:
				if (!use_command[e->effect])
            use_command[e->effect] = i+1;
            }
         }
      }
   }


void analyze_song(song)
struct song *song;
   {
   int i;

   for (i = 1; i <= song->ninstr ; i++)
      {
      if (song->samples[i])
         {
         if (song->samples[i]->finetune)
            printf("Sample %d: finetune is %d\n", 
               i, song->samples[i]->finetune);
         }
      }
   for (i = 0; i < 16; i++)
      {
      use_command[i] = FALSE;
      use_extended[i] = FALSE;
      }
   for (i = 0; i < song->info.maxpat; i++)
      analyze_block(song->info.pblocks+i, i);
   for (i = 0; i < 16; i++)
      if (use_command[i])
         printf("%3d", i);
   for (i = 0; i < 16; i++)
      if (use_extended[i])
         printf("%3dE", i);
   printf("\n");
   }

void do_load_song(s)
char *s;
	{
	struct stat buf;

	if (stat(s, &buf))
		return;
	if (S_ISDIR(buf.st_mode))
		{
		struct dirent *de;
		DIR *dir;

		dir = opendir(s);
		printf("%s\n", s);
		chdir(s);
		while (de = readdir(dir))
			{
			if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
				continue;
			do_load_song(de->d_name);
			}
		chdir("..");
		printf("..\n");
		closedir(dir);
		}
	else
		{
		struct exfile *file;
		struct song *song;

		file = open_file(s, "r", getenv("MODPATH"));
		if (file)
			{
			song = read_song(file, NEW);
			if (!song)
				{
				rewind_file(file);
				song = read_song(file, OLD);
				}
			close_file(file);
			if (song)
				{
				puts(s);
				analyze_song(song);
				release_song(song);
				}
			}
      }
	}

int main(argc, argv)
int argc;
char **argv;
   {
   int i;

	struct exfile *file;
   struct song *song;
   int default_type;

   default_type = BOTH;
   set_pref_scalar(PREF_TOLERATE, 2);

   for (i = 1; i < argc; i++)
		do_load_song(argv[i]);
   }


void sync_audio(f, p)
void (*f) P((GENERIC));
GENERIC p;
	{
	}

void audio_ui(c)
int c;
	{
	}

