home *** CD-ROM | disk | FTP | other *** search
/ Mods Anthology 4 / Music-AmigaModsAnthology-4of4-Psychodk.mcsteam.iso / Tools / BeBox / Ralf_Tracker_0.3_Src / player.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-23  |  9.3 KB  |  450 lines

  1. /* player.c */
  2.  
  3. /* $Id: player.c,v 3.17 1993/11/19 14:27:06 espie Exp espie $
  4.  * $Log: player.c,v $
  5.  * Revision 3.17  1993/11/19  14:27:06  espie
  6.  * Stupid bug.
  7.  *
  8.  * Revision 3.16  1993/11/17  15:31:16  espie
  9.  * New high-level functions.
  10.  *
  11.  * Revision 3.15  1993/11/11  20:00:03  espie
  12.  * Amiga support.
  13.  *
  14.  * Revision 3.14  1993/08/04  11:34:33  espie
  15.  * *** empty log message ***
  16.  *
  17.  * Revision 3.13  1993/07/18  11:49:29  espie
  18.  * Bug with delay_pattern: can't factorize the check for effect thingy.
  19.  *
  20.  * Revision 3.12  1993/07/18  10:39:44  espie
  21.  * Added forking under unix.
  22.  *
  23.  *
  24.  * Revision 3.10  1993/05/09  14:06:03  espie
  25.  * Reniced verbose output display.
  26.  *
  27.  * Revision 3.9  1993/04/25  14:08:15  espie
  28.  * Bug fix: now use correct finetune when loading samples/starting notes.
  29.  *
  30.  * Revision 3.8  1993/01/15  14:00:28  espie
  31.  * Added bg/fg test.
  32.  *
  33.  * Revision 3.6  1992/11/27  10:29:00  espie
  34.  * General cleanup
  35.  *
  36.  * Revision 3.5  1992/11/24  10:51:19  espie
  37.  * un#ifdef'ed showseq code.
  38.  *
  39.  * Revision 3.3  1992/11/22  17:20:01  espie
  40.  * Added <> operators.
  41.  * Added update frequency on the fly.
  42.  *
  43.  * Revision 3.2  1992/11/20  14:53:32  espie
  44.  * Added finetune.
  45.  *
  46.  * Revision 3.1  1992/11/19  20:44:47  espie
  47.  * Protracker commands.
  48.  *
  49.  * Revision 3.0  1992/11/18  16:08:05  espie
  50.  * New release.
  51.  *
  52.  * Revision 2.19  1992/11/17  17:15:37  espie
  53.  * Added interface using may_getchar(). Still primitive, though.
  54.  * imask, start.
  55.  * Added transpose feature.
  56.  * Added possibility to get back to MONO for the sgi.
  57.  * Added stereo capabilities to the indigo version.
  58.  * Added two level of fault tolerancy.
  59.  * Added some control on the number of replays,
  60.  * and better error recovery.
  61.  */
  62.      
  63. #include <stdio.h>
  64.      
  65. #include "defs.h"
  66. #include "extern.h"
  67. #include "song.h"
  68. #include "channel.h"
  69. #include "pref.h"
  70.      
  71.  
  72. LOCAL char *id = "$Id: player.c,v 3.17 1993/11/19 14:27:06 espie Exp espie $";
  73.      
  74.  
  75. // a flag set by the app to go next module or to quit
  76. extern int gBeAudioNextModule;
  77.  
  78. void make_effects(int cmd, struct automaton *a, struct channel *ch);
  79.  
  80. /* setting up a given note */
  81.  
  82. void reset_note(ch, note, pitch)
  83. struct channel *ch;
  84. int note;
  85. int pitch;
  86.     {
  87.         /*
  88.     ch->pointer = 0;
  89.     ch->mode = PLAY;
  90.     set_current_pitch(ch, pitch);
  91.         */
  92.     ch->pitch = pitch;
  93.     ch->note = note;
  94.     ch->viboffset = 0;
  95.     play_note(ch->audio, ch->samp, pitch);
  96.     }
  97.  
  98. /* changing the current pitch (value
  99.  * may be temporary, and not stored
  100.  * in channel pitch, for instance vibratos.
  101.  */
  102. void set_current_pitch(ch, pitch)
  103. struct channel *ch;
  104. int pitch;
  105.     {
  106.         /* save current pitch in case we want to change
  107.          * the step table on the run
  108.     ch->cpitch = pitch;
  109.     ch->step = step_table[pitch];
  110.         */
  111.     set_play_pitch(ch->audio, pitch);
  112.     }
  113.  
  114. /* changing the current volume. You HAVE to get through
  115.  * there so that it will work on EVERY machine.
  116.  */
  117. void set_current_volume(ch, volume)
  118. struct channel *ch;
  119. int volume;
  120.     {
  121.     ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  122.     set_play_volume(ch->audio, volume);
  123.     }
  124.  
  125. void set_position(ch, pos)
  126. struct channel *ch;
  127. int pos;
  128.     {
  129.     set_play_position(ch->audio, pos);
  130.     /*
  131.     ch->pointer = int_to_fix(pos);
  132.     */
  133.     }
  134.  
  135. /* init_channel(ch, dummy):
  136.  * setup channel, with initially
  137.  * a dummy sample ready to play,
  138.  * and no note.
  139.  */
  140. LOCAL void init_channel(ch)
  141. struct channel *ch;
  142.     {
  143.     ch->samp = NULL;
  144.     ch->finetune = 0;
  145.     ch->audio = new_channel();
  146.     ch->volume = 0; 
  147.     ch->pitch = 0; 
  148.     ch->note = NO_NOTE;
  149.  
  150.         /* we don't setup arpeggio values. */
  151.     ch->viboffset = 0; 
  152.     ch->vibdepth = 0;
  153.  
  154.     ch->slide = 0; 
  155.  
  156.     ch->pitchgoal = 0; 
  157.     ch->pitchrate = 0;
  158.  
  159.     ch->volumerate = 0;
  160.  
  161.     ch->vibrate = 0;
  162.     ch->adjust = do_nothing;
  163.     }
  164.  
  165.  
  166.  
  167. LOCAL int VSYNC;          /* base number of sample to output */
  168. void (*eval[NUMBER_EFFECTS])();
  169.                     /* the effect table */
  170. LOCAL int oversample;     /* oversample value */
  171. LOCAL int frequency;      /* output frequency */
  172. LOCAL int channel;        /* channel loop counter */
  173.  
  174. LOCAL struct channel chan[NUMBER_TRACKS];
  175.                     /* every channel */
  176. LOCAL int countdown;      /* keep playing the tune or not */
  177.  
  178. LOCAL struct song_info *info;
  179. LOCAL struct sample_info *voices;
  180.  
  181. LOCAL struct automaton a;
  182.  
  183.  
  184. void init_player(o, f)
  185. int o, f;
  186.     {
  187.     oversample = o;
  188.     frequency = f;
  189.     init_tables(o, f, NULL);
  190.     init_effects(eval);
  191.     init_display();
  192.     }
  193.  
  194. LOCAL void setup_effect(ch, a, e, imask, bcdvol)
  195. struct channel *ch;
  196. struct automaton *a;
  197. struct event *e;
  198. unsigned long imask;
  199. int bcdvol;
  200.     {
  201.     int samp, cmd;
  202.  
  203.         /* retrieves all the parameters */
  204.     samp = e->sample_number;
  205.  
  206.         /* load new instrument */
  207.     if (samp)  
  208.         {
  209.             /* note that we can change sample in the middle
  210.              * of a note. This is a *feature*, not a bug (see
  211.              * made). Precisely: the sampel change will be taken
  212.              * into account for the next note, BUT the volume change
  213.              * takes effect immediately.
  214.              */
  215.         ch->samp = voices + samp;
  216.         ch->finetune = voices[samp].finetune;
  217.         if ((1L<<samp) & imask)
  218.             ch->samp = voices;
  219.         set_current_volume(ch, voices[samp].volume);
  220.         }
  221.  
  222.     a->note = e->note;
  223.     if (a->note != NO_NOTE)
  224.         a->pitch = pitch_table[a->note][ch->finetune];
  225.     else
  226.         a->pitch = e->pitch;
  227.     cmd = e->effect;
  228.     a->para = e->parameters;
  229.  
  230.     if (a->pitch >= MAX_PITCH)
  231.         {
  232.         fprintf(stderr, "Pitch out of bounds %d\n", a->pitch);
  233.         a->pitch = 0;
  234.         error = FAULT;
  235.         }
  236.  
  237.     if (show && run_in_fg())
  238.         dump_event(ch, e, imask);
  239.         /* check for a new note: portamento
  240.          * is the special case where we do not restart
  241.          * the note.
  242.          */
  243.     if (a->pitch && cmd != EFF_PORTA && cmd != EFF_PORTASLIDE)
  244.         reset_note(ch, a->note, a->pitch);
  245.     ch->adjust = do_nothing;
  246.         /* do effects */
  247.     (eval[cmd])(a, ch);
  248.         //make_effects(cmd, a, ch); // in commands.c
  249.     }
  250.  
  251.  
  252. LOCAL void adjust_sync(ofreq, tempo)
  253. int ofreq, tempo;
  254.     {
  255.     VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  256.     }
  257.  
  258. LOCAL void play_once(a, pref)
  259. struct automaton *a;
  260. struct pref *pref;
  261.     {
  262.     int channel;
  263.  
  264.     if (a->do_stuff & DELAY_PATTERN)
  265.         for (channel = 0; channel < NUMBER_TRACKS; channel++)
  266.             /* do the effects */
  267.             (chan[channel].adjust)(chan + channel);
  268.     else
  269.         {    
  270.         if (a->counter == 0)
  271.             for (channel = 0; channel < NUMBER_TRACKS; channel++)
  272.                 /* setup effects */
  273.                 setup_effect(chan + channel, a, 
  274.                     &(a->pattern->e[channel][a->note_num]), 
  275.                     pref->imask, pref->bcdvol);
  276.         else
  277.             for (channel = 0; channel < NUMBER_TRACKS; channel++)
  278.                 /* do the effects */
  279.                 (chan[channel].adjust)(chan + channel);
  280.         }
  281.  
  282.         /* advance player for the next tick */
  283.     next_tick(a);
  284.         /* actually output samples */
  285.     resample(chan, oversample, VSYNC / a->finespeed);
  286.     }
  287.  
  288.  
  289.  
  290. void play_song(song, pref, start)
  291. struct song *song;
  292. struct pref *pref;
  293. int start;
  294.     {
  295.     int tempo;
  296.  
  297.     tempo = pref->speed;
  298.  
  299.     adjust_sync(frequency, tempo);
  300.     /* a repeats of 0 is infinite replays */
  301.     if (pref->repeats)
  302.         countdown = pref->repeats;
  303.     else
  304.         countdown = 1;
  305.  
  306.     info = &song->info;
  307.     voices = song->samples; 
  308.  
  309.     init_automaton(&a, song, start);
  310.  
  311.     no_audio_channels();
  312.  
  313.     for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  314.         init_channel(chan + channel);
  315.  
  316.  
  317.     while(countdown)
  318.         {
  319.         play_once(&a, pref);
  320.  
  321.         if (gBeAudioNextModule)
  322.         {
  323.             gBeAudioNextModule = FALSE;
  324.             error = NEXT_SONG;
  325.             return;
  326.         }
  327.  
  328.         switch(may_getchar())
  329.             {
  330.         case 'n':
  331. #ifdef FORKING
  332.         if (forked)
  333.             break;
  334.         forked = TRUE;
  335.         if (pid = fork())
  336.             {
  337.             nice(15);
  338.             error = NEXT_SONG;
  339.             return;
  340.             }
  341.         else
  342.             break;
  343. #else
  344.             discard_buffer();
  345.             error = NEXT_SONG;
  346.             return;
  347. #endif
  348.         case 'p':
  349. #ifdef FORKING
  350.         if (forked)
  351.             break;
  352.         forked = TRUE;
  353.         if (pid = fork())
  354.             {
  355.             nice(15);
  356.             error = PREVIOUS_SONG;
  357.             return;
  358.             }
  359.         else 
  360.             break;
  361. #else
  362.             discard_buffer();
  363.             error = PREVIOUS_SONG;
  364.             return;
  365. #endif
  366.         case 'x':
  367.         case 'e':
  368.         case 'q':
  369.             discard_buffer();
  370.             end_all();
  371.         case 's':
  372.             tempo = 50;
  373.             adjust_sync(frequency, tempo);
  374.             break;
  375.         case 'S':
  376.             tempo = 60;
  377.             adjust_sync(frequency, tempo);
  378.             break;
  379.         case 'r':
  380.             discard_buffer();
  381.             init_automaton(&a, song, start);
  382.             no_audio_channels();
  383.             for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  384.                 init_channel(chan + channel);
  385.             break;
  386.         case '>':
  387.             discard_buffer();
  388.             init_automaton(&a, song, a.pattern_num+1);
  389.             break;
  390.         case '<':
  391.             discard_buffer();
  392.             if (a.note_num < 4)
  393.                 init_automaton(&a, song, a.pattern_num -1);
  394.             else
  395.                 init_automaton(&a, song, a.pattern_num);
  396.             break;
  397.         case '?':
  398.             dump_song(song);
  399.             show = TRUE;
  400.             break;
  401.         case '!':
  402.             show = FALSE;
  403.             break;
  404.         case ' ':
  405.             while (may_getchar() == EOF)
  406.                 ;
  407.             break;
  408.         default:
  409.             break;
  410.             }
  411.         {
  412.         int new_freq;
  413.         if (new_freq = update_frequency())
  414.             {
  415.             frequency = new_freq;
  416.             adjust_sync(frequency, tempo);
  417.             init_tables(oversample, frequency, chan);
  418.             }
  419.         }
  420.  
  421.         switch(error)
  422.             {
  423.         case NONE:
  424.             break;
  425.         case ENDED:
  426.             if (pref->repeats)
  427.                 countdown--;
  428.             break;
  429.         case SAMPLE_FAULT:
  430.             if (!pref->tolerate)
  431.                 countdown = 0;
  432.             break;
  433.         case FAULT:
  434.             if (pref->tolerate < 2)
  435.                 countdown = 0;
  436.             break;
  437.         case PREVIOUS_SONG:
  438.         case NEXT_SONG:
  439.         case UNRECOVERABLE:
  440.             countdown = 0;
  441.             break;
  442.         default:
  443.             break;
  444.             }
  445.         error = NONE;
  446.         }
  447.          
  448.     }
  449.  
  450.