home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / audio / tracker / player.c < prev    next >
Encoding:
C/C++ Source or Header  |  2014-05-19  |  6.1 KB  |  245 lines

  1. /* player.c */
  2.  
  3. /* $Author: espie $
  4.  * $Id: player.c,v 2.10 1991/12/03 23:03:39 espie Exp espie $
  5.  * $Revision: 2.10 $
  6.  * $Log: player.c,v $
  7.  * Revision 2.10  1991/12/03  23:03:39  espie
  8.  * Added transpose feature.
  9.  *
  10.  * Revision 2.9  1991/12/03  21:24:53  espie
  11.  * Reverted to previous behaviour because of intromusic6.b.
  12.  *
  13.  * Revision 2.8  1991/12/03  20:43:46  espie
  14.  * Added possibility to get back to MONO for the sgi.
  15.  *
  16.  * Revision 2.7  1991/12/03  18:07:38  espie
  17.  * Added stereo capabilities to the indigo version.
  18.  *
  19.  * Revision 2.6  1991/12/03  17:12:33  espie
  20.  * Minor changes ??
  21.  *
  22.  * Revision 2.5  1991/11/19  16:07:19  espie
  23.  * Added comments, moved minor stuff around.
  24.  *
  25.  * Revision 2.4  1991/11/18  14:10:30  espie
  26.  * Moved resample part and empty sample test to audio.
  27.  *
  28.  * Revision 2.3  1991/11/18  01:23:30  espie
  29.  * Added two level of fault tolerancy.
  30.  *
  31.  * Revision 2.2  1991/11/18  01:12:31  espie
  32.  * Added some control on the number of replays,
  33.  * and better error recovery.
  34.  *
  35.  * Revision 2.1  1991/11/17  23:07:58  espie
  36.  * Coming from str32.
  37.  *
  38.  */
  39.      
  40. static char *id = "$Id: player.c,v 2.10 1991/12/03 23:03:39 espie Exp espie $";
  41.  
  42. #ifdef SHOW_SEQ
  43. char *num[] = {
  44. " 0", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9",
  45. "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
  46. "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
  47. "30", "31", "32", "33", "34", "35", "36", "37", "38", "39"};
  48. #endif
  49.  
  50. #include <stdio.h>
  51.      
  52. #include "extern.h"
  53. #include "machine.h"
  54. #include "song.h"
  55. #include "channel.h"
  56. #include "pref.h"
  57.      
  58.      
  59.  
  60. /* init_channel(ch, dummy):
  61.  * setup channel, with initially
  62.  * a dummy sample ready to play,
  63.  * and no note.
  64.  */
  65. void init_channel(ch, dummy)
  66. struct channel *ch;
  67. struct sample_info *dummy;
  68.     {
  69.     ch->samp = dummy;
  70.     ch->mode = DO_NOTHING; 
  71.     ch->pointer = 0; 
  72.     ch->step = 0; 
  73.     ch->volume = 0; 
  74.     ch->pitch = 0; 
  75.     ch->note = NO_NOTE;
  76.  
  77.         /* we don't setup arpeggio values. */
  78.     ch->viboffset = 0; 
  79.     ch->vibdepth = 0;
  80.  
  81.     ch->slide = 0; 
  82.  
  83.     ch->pitchgoal = 0; 
  84.     ch->pitchrate = 0;
  85.  
  86.     ch->volumerate = 0;
  87.  
  88.     ch->vibrate = 0;
  89.     ch->adjust = do_nothing;
  90.     }
  91.  
  92.  
  93.  
  94. int VSYNC;          /* base number of sample to output */
  95. void (*eval[NUMBER_EFFECTS])();
  96.                     /* the effect table */
  97. int oversample;     /* oversample value */
  98. int frequency;      /* output frequency */
  99. int channel;        /* channel loop counter */
  100.  
  101. struct channel chan[NUMBER_TRACKS];
  102.                     /* every channel */
  103. int countdown;      /* keep playing the tune or not */
  104.  
  105. struct song_info *info;
  106. struct sample_info **voices;
  107.  
  108. struct automaton a;
  109.  
  110.  
  111. void init_player(o, f)
  112. int o, f;
  113.     {
  114.     oversample = o;
  115.     frequency = f;
  116.     init_tables(oversample, frequency);
  117.     init_effects(eval);
  118.     }
  119.  
  120.  
  121. void setup_effect(ch, a, e)
  122. struct channel *ch;
  123. struct automaton *a;
  124. struct event *e;
  125.     {
  126.     int samp, cmd;
  127.  
  128.         /* retrieves all the parameters */
  129.     samp = e[a->note_num].sample_number;
  130.     a->note = e[a->note_num].note;
  131.     if (a->note != NO_NOTE)
  132.         a->pitch = pitch_table[a->note];
  133.     else
  134.         a->pitch = e[a->note_num].pitch;
  135.     cmd = e[a->note_num].effect;
  136.     a->para = e[a->note_num].parameters;
  137.  
  138.     if (a->pitch >= MAX_PITCH)
  139.         {
  140.         fprintf(stderr, "Pitch out of bounds %d\n", a->pitch);
  141.         a->pitch = 0;
  142.         error = FAULT;
  143.         }
  144. #ifdef SHOW_SEQ
  145.     if (samp == 0 && a->pitch == 0 && cmd == 0)
  146.         printf("-----------  ");
  147.     else
  148.         {
  149.         printf("%s %s ", num[samp], a->pitch ? "N" : "-");
  150.         if (cmd == 0 && a->para == 0)
  151.             printf("------  ");
  152.         else
  153.             printf("%s %3d  ", num[cmd], a->para);
  154.         }
  155.     fflush(stdout);
  156. #endif
  157.  
  158.         /* load new instrument */
  159.     if (samp)  
  160.         {
  161.             /* note that we can change sample in the middle
  162.              * of a note. This is a *feature*, not a bug (see
  163.              * intromusic6.b)
  164.              */
  165.         ch->samp = voices[samp];
  166.         ch->volume = voices[samp]->volume;
  167.         }
  168.         /* check for a new note: cmd 3 (portamento)
  169.          * is the special case where we do not restart
  170.          * the note.
  171.          */
  172.     if (a->pitch && cmd != 3)
  173.         reset_note(ch, a->note, a->pitch);
  174.     ch->adjust = do_nothing;
  175.         /* do effects */
  176.     (eval[cmd])(a, ch);
  177.     }
  178.  
  179.  
  180.  
  181. void play_song(song, pref)
  182. struct song *song;
  183. struct pref *pref;
  184.     {
  185.     init_automaton(&a, song);
  186.     VSYNC = frequency * 100 / pref->speed;
  187.     /* a repeats of 0 is infinite replays */
  188.     if (pref->repeats)
  189.         countdown = pref->repeats;
  190.     else
  191.         countdown = 1;
  192.  
  193.     info = song->info;
  194.     voices = song->samples; 
  195.  
  196.     for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  197.         init_channel(chan + channel, voices[0]);
  198.  
  199.     printf("(%d):\n", info->length);
  200.  
  201.     while(countdown)
  202.         {
  203.         for (channel = 0; channel < NUMBER_TRACKS; channel++)
  204.             if (a.counter == 0)
  205.                 /* setup effects */
  206.                 setup_effect(chan + channel, &a, a.pattern->e[channel]);
  207.             else
  208.                 /* do the effects */
  209.                 (chan[channel].adjust)(chan + channel);
  210.  
  211.             /* advance player for the next tick */
  212.         next_tick(&a);
  213.             /* actually output samples */
  214.         resample(chan, oversample, VSYNC / a.finespeed);
  215.  
  216.         switch(error)
  217.             {
  218.             case NONE:
  219.                 break;
  220.             case ENDED:
  221.                 if (pref->repeats)
  222.                     countdown--;
  223.                 break;
  224.             case SAMPLE_FAULT:
  225.                 if (!pref->tolerate)
  226.                     countdown = 0;
  227.                 break;
  228.             case FAULT:
  229.                 if (pref->tolerate < 2)
  230.                     countdown = 0;
  231.                 break;
  232.             case NEXT_SONG:
  233.             case UNRECOVERABLE:
  234.                 countdown = 0;
  235.                 break;
  236.             default:
  237.                 break;
  238.             }
  239.         error = NONE;
  240.         }
  241.          
  242.     printf("\n");
  243.     }
  244.  
  245.