home *** CD-ROM | disk | FTP | other *** search
- /* str32.c */
-
- /* plays sound/noisetracker files on Sparc, silicon graphics.
- * Authors : Liam Corner - zenith@dcs.warwick.ac.uk
- * Marc Espie - espie@dmi.ens.fr
- *
- * Usage : tracker <filename>
- * this version plays compressed files and simple zoo archives
- * as well.
- */
-
- /* $Author: espie $
- * $Id: str32.c,v 2.9 1991/12/04 08:28:53 espie Exp espie $
- * $Revision: 2.9 $
- * $Log: str32.c,v $
- * Revision 2.9 1991/12/04 08:28:53 espie
- * Separated mix/stereo stuff.
- *
- * Revision 2.8 1991/12/03 23:03:39 espie
- * Added transpose feature.
- *
- * Revision 2.7 1991/12/03 20:43:46 espie
- * Added possibility to get back to MONO for the sgi.
- *
- * Revision 2.6 1991/12/03 18:07:38 espie
- * Added stereo capabilities to the indigo version.
- *
- * Revision 2.5 1991/12/03 17:10:11 espie
- * Added recovery and reread for automatic recognition
- * of old/new tracker files.
- *
- * Revision 2.4 1991/11/20 20:46:35 espie
- * Minor correction.
- *
- * Revision 2.3 1991/11/18 01:23:30 espie
- * Added two level of fault tolerancy.
- *
- * Revision 2.2 1991/11/18 01:10:45 espie
- * Added more rational options.
- *
- * Revision 2.1 1991/11/17 23:07:58 espie
- * Moved almost everything to audio and automaton.
- *
- * Revision 2.0 1991/11/17 21:42:08 espie
- * Structured part of the code, especially replay ``automaton''
- * and setting up of effects.
- *
- * Revision 1.26 1991/11/17 17:09:53 espie
- * Added missing prototypes.
- *
- * Revision 1.25 1991/11/17 16:30:48 espie
- * Corrected cosmetic details, mostly.
- *
- * Revision 1.24 1991/11/16 16:57:01 espie
- * Forgot that read_song only returned NULL on read problem.
- * Should test that before printing Ok.
- *
- * Revision 1.23 1991/11/16 16:54:19 espie
- * Some more info while loading files.
- * Added FAULT env variable, FAULT resistant playing,
- * for playing modules which are not quite correct.
- *
- * Revision 1.22 1991/11/16 15:42:43 espie
- * tabs.
- *
- * Revision 1.21 1991/11/15 20:57:34 espie
- * Minor cleanup, mostly comments.
- *
- * Revision 1.20 1991/11/15 18:22:10 espie
- * Serious bug: dochangespeed was not reset all the time.
- * Check all these parameters, they MUST be reset for
- * each new song.
- *
- * Revision 1.19 1991/11/09 20:01:56 espie
- * Fixed a stupid bug: when env variable LOOPING was
- * undefined, we got a segv on strcmp.
- * Now we just test for its existence, since this is
- * about all we want...
- *
- * Revision 1.18 1991/11/09 17:47:33 espie
- * Bug correction: when doing arpeggio, there might not
- * be a new note, so we have to save the old note value
- * and do the arppeggio on that note.
- *
- * Revision 1.17 1991/11/08 14:47:52 espie
- * Completely added control with OVERSAMPLE and FREQUENCY.
- *
- * Revision 1.15 1991/11/08 13:35:57 espie
- * Added control flow.
- *
- * Revision 1.14 1991/11/08 12:37:37 espie
- * Added pipe decompression, so that now you can do
- * str32 file.Z directly.
- * stdin may go away.
- *
- * Looping is now controlled by an environment variable.
- *
- * Revision 1.13 1991/11/07 21:40:16 espie
- * Added arpeggio.
- *
- * Revision 1.12 1991/11/07 20:12:34 espie
- * Minor problem with version id.
- *
- * Revision 1.11 1991/11/07 20:09:06 espie
- * Added embedded version id.
- *
- * Revision 1.10 1991/11/07 20:05:53 espie
- * Added vibslide and portaslide.
- *
- * Revision 1.9 1991/11/07 15:27:02 espie
- * Added speed command.
- * Added signal control.
- * Error checking: there shouldn't be that many
- * segv signals any more.
- *
- * Revision 1.8 1991/11/06 09:46:06 espie
- * Moved every command to commands.c.
- *
- * Revision 1.7 1991/11/06 00:03:11 espie
- * Added effect #9, change offset in sample.
- * It seems to work quite correctly (example: sampled annie).
- *
- * Revision 1.6 1991/11/05 22:49:03 espie
- * Added some debug code for showing the full
- * sequence for a file.
- * Corrected the bug in volume slide: there is
- * no default value, i.e., if it is 0, it is 0,
- * as stupid as it may seem.
- * Added vibrato.
- * Added fastskip/corrected skip.
- *
- * Revision 1.5 1991/11/05 11:14:59 espie
- * Modified control flow of the player till
- * it looks like something reasonable (i.e.,
- * the structure is more natural and reflects
- * the way stuff is played actually...)
- *
- * Added some #define for a slightly higher level
- * of abstraction ( :-) ).
- *
- * Revision 1.4 1991/11/04 20:27:05 espie
- * Do not restart the sound when we change instruments
- * on the fly. A bit strange, but it works that way.
- *
- * Revision 1.3 1991/11/04 13:23:59 espie
- * Modified main to use new data structures.
- * The sound player is MUCH cleaner, it uses now
- * a 3-state automaton for each voice.
- *
- * Revision 1.2 1991/11/04 08:01:20 espie
- * Corrected ruckus with data type of sample.
- *
- * Revision 1.1 1991/11/03 22:47:05 espie
- * Initial revision
- *
- *
- */
-
- static char *id = "$Id: str32.c,v 2.9 1991/12/04 08:28:53 espie Exp espie $";
-
- #include <stdio.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <string.h>
-
- /* this should be in getopt.h, but sparc doesn't know it... */
-
- extern int getopt();
- extern char *optarg;
- extern int optind, opterr;
-
- #include "extern.h"
- #include "machine.h"
- #include "song.h"
- #include "pref.h"
-
-
- /* global variable to catch various types of errors
- * and achieve the desired flow of control
- */
- int error;
-
- /* signal handlers */
-
- void goodbye(sig)
- int sig;
- {
- printf("\nSignal %d\n", sig);
- exit(10);
- }
-
- void nextsong(sig)
- int sig;
- {
- printf("\nSignal %d\n", sig);
- signal(sig, nextsong);
- error = NEXT_SONG;
- }
-
- /* v = read_env(name, default): reads the value v
- * in the environment, supplies a defaults.
- */
- int read_env(name, def)
- char *name;
- int def;
- {
- char *var;
- int value;
-
- var = getenv(name);
- if (!var)
- return def;
- if (sscanf(var, "%d", &value) == 1)
- return value;
- else
- return def;
- }
-
- /***
- *
- * Handling compressed modules.
- *
- ***/
-
- int check_Z(s)
- char *s;
- {
- int i;
-
- i = strlen(s);
- if (i < 2)
- return 0;
- return s[i-1] == 'Z' && s[i-2] == '.';
- }
-
- int check_zoo(s)
- char *s;
- {
- int i;
-
- i = strlen(s);
- if (i < 4)
- return 0;
- return s[i-1] == 'o' && s[i-2] == 'o' && s[i-3] == 'z' && s[i-4] == '.';
- }
-
- /* small hack for transposing songs on the fly */
- static int transpose;
-
- struct song *do_read_song(s, type)
- char *s;
- int type;
- {
- struct song *song;
- FILE *fp;
-
- printf("(%s)...", s);
- fflush(stdout);
-
- if (check_Z(s))
- {
- char pipe[200];
-
- sprintf(pipe, "zcat %s", s);
- fp = popen(pipe, "r");
- if (fp == NULL)
- {
- fprintf(stderr, "Unable to open tune file %s\n", s);
- return NULL;
- }
- song = read_song(fp, type, transpose);
- pclose(fp);
- }
- else if (check_zoo(s))
- {
- char pipe[200];
-
- sprintf(pipe, "zoo xpq %s", s);
- fp = popen(pipe, "r");
- if (fp == NULL)
- {
- fprintf(stderr, "Unable to open tune file %s\n", s);
- return NULL;
- }
- song = read_song(fp, type, transpose);
- pclose(fp);
- }
- else
- {
- fp = fopen(s, "r");
- if (fp == NULL)
- {
- fprintf(stderr, "Unable to open tune file %s\n", s);
- return NULL;
- }
- song = read_song(fp, type, transpose);
- fclose(fp);
- }
- if (song)
- printf("Ok!\n");
- return song;
- }
-
- int optvalue(def)
- int def;
- {
- int d;
- if (sscanf(optarg, "%d", &d) == 1)
- return d;
- else
- {
- optind--;
- return def;
- }
- }
-
- int main (argc, argv)
- int argc;
- char **argv;
- {
-
- int frequency;
- int oversample;
-
- struct pref pref;
- struct song *song;
-
- int index;
- int c;
- int default_type;
-
- signal(2, nextsong);
- signal(3, goodbye);
-
- frequency = read_env("FREQUENCY", 0);
- oversample = read_env("OVERSAMPLE", 1);
- transpose = read_env("TRANSPOSE", 0);
-
- frequency = open_audio(frequency);
-
- init_player(oversample, frequency);
-
- /* check the command name for default reading type */
- if (strcmp(argv[0], "otracker") == 0)
- default_type = OLD;
- else if (strcmp(argv[0], "ntracker") == 0)
- default_type = NEW;
- else
- default_type = BOTH;
-
- pref.type = default_type;
- pref.repeats = 1;
- pref.speed = 50;
- pref.tolerate = 1;
-
- for (optind = 1; optind < argc; optind++)
- {
- while ((c = getopt(argc, argv, "onhbr:s:f:m:" )) != -1)
- switch(c)
- {
- case 'o': /* old tracker type */
- pref.type = OLD;
- break;
- case 'n': /* new tracker type */
- pref.type = NEW;
- break;
- case 'b': /* both tracker types */
- pref.type = BOTH;
- break;
- case 'r': /* number of repeats */
- pref.repeats = optvalue(0);
- break;
- case 's': /* speed */
- pref.speed = optvalue(50);
- break;
- case 'f': /* level of fault */
- pref.tolerate = optvalue(2);
- break;
- case 'm': /* % of channel mix.
- * 0->full stereo, 100->mono */
- set_mix(optvalue(30));
- break;
- case 'h': /* template */
- fprintf(stderr, "%s options:\n", argv[0]);
- fprintf(stderr, "\to : old tracker format");
- if (default_type == OLD)
- fprintf(stderr, " (default)");
- fprintf(stderr, "\n\tn : new tracker format");
- if (default_type == NEW)
- fprintf(stderr, " (default)");
- fprintf(stderr, "\n\tb : try both formats");
- if (default_type == BOTH)
- fprintf(stderr, " (default)");
- fprintf(stderr, "\n\tr n: number of repeats (0 is forever, ");
- fprintf(stderr, "1 is the default)\n");
- fprintf(stderr, "\ts n: speed (default 50, ");
- fprintf(stderr, "some songs want 60)\n");
- fprintf(stderr, "\tf : tolerate faults\n");
- fprintf(stderr, "\tf 0: abort song if problem (default)\n");
- fprintf(stderr, "\tm p: percent of mix (0 is spatial");
- fprintf(stderr, "100 is mono)\n");
- exit(2);
- }
- if (optind < argc)
- {
- switch(pref.type)
- {
- case BOTH:
- song = do_read_song(argv[optind], NEW);
- if (!song)
- song = do_read_song(argv[optind], OLD);
- break;
- case OLD:
- song = do_read_song(argv[optind], pref.type);
- break;
- /* this is explicitly flagged as a new module,
- * so we don't need to look for a signature.
- */
- case NEW:
- song = do_read_song(argv[optind], NEW_NO_CHECK);
- break;
- }
- if (song == NULL)
- continue;
-
- dump_song(song);
- play_song(song, &pref);
- release_song(song);
- }
- }
-
- close_audio();
- return 0;
- }
-
-