home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / player.c < prev    next >
Text File  |  1994-11-24  |  9KB  |  382 lines

  1. /* player.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: player.c,v 4.3 1994/11/15 16:11:01 espie Exp espie $
  6.  * $Log: player.c,v $
  7.  * Revision 4.3  1994/11/15  16:11:01  espie
  8.  * *** empty log message ***
  9.  *
  10.  *
  11.  * Revision 4.0  1994/01/11  17:51:40  espie
  12.  * Use the new UI calls.
  13.  * Use the new pref settings.
  14.  *
  15.  * Revision 1.14  1994/01/09  23:24:37  Espie
  16.  * Last bug fix.
  17.  * Suppressed really outdated code.
  18.  * New names: new_channel_tag_list, release_audio_channel.
  19.  * Some notice to status.
  20.  * Use new pref scheme.
  21.  * Use get_ui
  22.  * Use autoinit feature of display.c
  23.  * discard_buffer forgotten...
  24.  * Handle errors better.
  25.  *
  26.  * Revision 3.18  1993/12/04  16:12:50  espie
  27.  * Lots of changes.
  28.  * New high-level functions.
  29.  * Amiga support.
  30.  * Bug with delay_pattern: can't factorize the check for effect thingy.
  31.  * Reniced verbose output display.
  32.  * Bug fix: now use correct finetune when loading samples/starting notes.
  33.  * Added bg/fg test.
  34.  * General cleanup
  35.  * Added <> operators.
  36.  * Added update frequency on the fly.
  37.  * Added finetune.
  38.  * Protracker commands.
  39.  *
  40.  * Revision 2.19  1992/11/17  17:15:37  espie
  41.  * Added interface using may_getchar(). Still primitive, though.
  42.  * imask, start.
  43.  * Added transpose feature.
  44.  * Added possibility to get back to MONO for the sgi.
  45.  * Added stereo capabilities to the indigo version.
  46.  * Added two level of fault tolerancy.
  47.  * Added some control on the number of replays,
  48.  * and better error recovery.
  49.  */
  50.      
  51. #include <stdio.h>
  52.      
  53. #include "defs.h"
  54. #include "song.h"
  55. #include "channel.h"
  56. #include "extern.h"
  57. #include "tags.h"
  58. #include "prefs.h"
  59.      
  60.  
  61. ID("$Id: player.c,v 4.3 1994/11/15 16:11:01 espie Exp espie $")
  62.      
  63.  
  64. /* setting up a given note */
  65.  
  66. void reset_note(ch, note, pitch)
  67. struct channel *ch;
  68. int note;
  69. int pitch;
  70.    {
  71.    ch->pitch = pitch;
  72.    ch->note = note;
  73.    ch->viboffset = 0;
  74.    play_note(ch->audio, ch->samp, pitch);
  75.    }
  76.  
  77. /* changing the current pitch (value
  78.  * may be temporary, and not stored
  79.  * in channel pitch, for instance vibratos.
  80.  */
  81. void set_current_pitch(ch, pitch)
  82. struct channel *ch;
  83. int pitch;
  84.    {
  85.       /* save current pitch in case we want to change
  86.        * the step table on the run
  87.    ch->cpitch = pitch;
  88.    ch->step = step_table[pitch];
  89.       */
  90.    set_play_pitch(ch->audio, pitch);
  91.    }
  92.  
  93. /* changing the current volume. You HAVE to get through
  94.  * there so that it will work on EVERY machine.
  95.  */
  96. void set_current_volume(ch, volume)
  97. struct channel *ch;
  98. int volume;
  99.    {
  100.    ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  101.    set_play_volume(ch->audio, ch->volume);
  102.    }
  103.  
  104. void set_position(ch, pos)
  105. struct channel *ch;
  106. int pos;
  107.    {
  108.    set_play_position(ch->audio, pos);
  109.    }
  110.  
  111. /* init_channel(ch, dummy):
  112.  * setup channel, with initially
  113.  * a dummy sample ready to play,
  114.  * and no note.
  115.  */
  116. LOCAL void init_channel(ch)
  117. struct channel *ch;
  118.    {
  119.    ch->samp = NULL;
  120.    ch->finetune = 0;
  121.    ch->audio = new_channel_tag_list(TAG_END);
  122.    ch->volume = 0; 
  123.    ch->pitch = 0; 
  124.    ch->note = NO_NOTE;
  125.  
  126.       /* we don't setup arpeggio values. */
  127.    ch->viboffset = 0; 
  128.    ch->vibdepth = 0;
  129.  
  130.    ch->slide = 0; 
  131.  
  132.    ch->pitchgoal = 0; 
  133.    ch->pitchrate = 0;
  134.  
  135.    ch->volumerate = 0;
  136.  
  137.    ch->vibrate = 0;
  138.    ch->adjust = do_nothing;
  139.    }
  140.  
  141.  
  142.  
  143. LOCAL int VSYNC;          /* base number of sample to output */
  144. LOCAL void (*eval[NUMBER_EFFECTS]) P((struct automaton *a, struct channel *ch));
  145.                     /* the effect table */
  146. LOCAL int oversample;     /* oversample value */
  147. LOCAL int frequency;      /* output frequency */
  148. LOCAL int channel;        /* channel loop counter */
  149.  
  150. LOCAL struct channel chan[NUMBER_TRACKS];
  151.                     /* every channel */
  152.  
  153. LOCAL struct sample_info *voices;
  154.  
  155. LOCAL struct automaton a;
  156.  
  157.  
  158. void init_player(o, f)
  159. int o, f;
  160.    {
  161.    oversample = o;
  162.    frequency = f;
  163.    init_tables(o, f);
  164.    init_effects(eval);
  165.    }
  166.  
  167. LOCAL void setup_effect(ch, a, e)
  168. struct channel *ch;
  169. struct automaton *a;
  170. struct event *e;
  171.    {
  172.    int samp, cmd;
  173.  
  174.       /* retrieves all the parameters */
  175.    samp = e->sample_number;
  176.  
  177.       /* load new instrument */
  178.    if (samp)  
  179.       {
  180.          /* note that we can change sample in the middle
  181.           * of a note. This is a *feature*, not a bug (see
  182.           * made). Precisely: the sample change will be taken
  183.           * into account for the next note, BUT the volume change
  184.           * takes effect immediately.
  185.           */
  186.       ch->samp = voices + samp;
  187.       ch->finetune = voices[samp].finetune;
  188.       if ((1L<<samp) & get_pref_scalar(PREF_IMASK))
  189.          ch->samp = voices;
  190.       set_current_volume(ch, voices[samp].volume);
  191.       }
  192.  
  193.    a->note = e->note;
  194.    if (a->note != NO_NOTE)
  195.       a->pitch = pitch_table[a->note][ch->finetune];
  196.    else
  197.       a->pitch = e->pitch;
  198.    cmd = e->effect;
  199.    a->para = e->parameters;
  200.  
  201.    if (a->pitch >= REAL_MAX_PITCH)
  202.       {
  203.       char buffer[60];
  204.       sprintf(buffer,"Pitch out of bounds %d", a->pitch);
  205.       status(buffer);
  206.       a->pitch = 0;
  207.       error = FAULT;
  208.       }
  209.  
  210.    dump_event(ch, e);
  211.  
  212.       /* check for a new note: portamento
  213.        * is the special case where we do not restart
  214.        * the note.
  215.        */
  216.    if (a->pitch && cmd != EFF_PORTA && cmd != EFF_PORTASLIDE)
  217.       reset_note(ch, a->note, a->pitch);
  218.    ch->adjust = do_nothing;
  219.       /* do effects */
  220.    (eval[cmd])(a, ch);
  221.    }
  222.  
  223.  
  224. LOCAL void adjust_sync(ofreq, tempo)
  225. int ofreq, tempo;
  226.    {
  227.    VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  228.    }
  229.  
  230. LOCAL void play_once(a)
  231. struct automaton *a;
  232.    {
  233.    int channel;
  234.  
  235.    if (a->do_stuff & DELAY_PATTERN)
  236.       for (channel = 0; channel < NUMBER_TRACKS; channel++)
  237.          /* do the effects */
  238.          (chan[channel].adjust)(chan + channel);
  239.    else
  240.       {  
  241.       if (a->counter == 0)
  242.          {
  243.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  244.             /* setup effects */
  245.             setup_effect(chan + channel, a, 
  246.                &(a->pattern->e[channel][a->note_num]));
  247.          dump_event(0, 0);
  248.          }
  249.       else
  250.          for (channel = 0; channel < NUMBER_TRACKS; channel++)
  251.             /* do the effects */
  252.             (chan[channel].adjust)(chan + channel);
  253.       }
  254.  
  255.       /* advance player for the next tick */
  256.    next_tick(a);
  257.       /* actually output samples */
  258.    resample(oversample, VSYNC / a->finespeed);
  259.    }
  260.  
  261. LOCAL struct tag pres[2];
  262.  
  263.  
  264. struct tag *play_song(song, start)
  265. struct song *song;
  266. int start;
  267.    {
  268.    int tempo;
  269.    int countdown;      /* keep playing the tune or not */
  270.  
  271.    song_title(song->title);
  272.    pres[1].type = TAG_END;
  273.    
  274.    tempo = get_pref_scalar(PREF_SPEED);
  275.  
  276.    adjust_sync(frequency, tempo);
  277.     /* a repeats of 0 is infinite replays */
  278.    
  279.    countdown = get_pref_scalar(PREF_REPEATS);
  280.    if (countdown == 0)
  281.       countdown = 50000;   /* ridiculously huge number */
  282.  
  283.    voices = song->samples; 
  284.  
  285.    init_automaton(&a, song, start);
  286.  
  287.    release_audio_channels();
  288.  
  289.    for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  290.       init_channel(chan + channel);
  291.  
  292.    while(countdown)
  293.       {
  294.       struct tag *result;
  295.       
  296.       play_once(&a);
  297.       result = get_ui();
  298.       while(result = get_tag(result))
  299.          {
  300.          switch(result->type)
  301.             {  
  302.          case UI_LOAD_SONG:
  303.             if (!result->data.pointer)
  304.                break;
  305.          case UI_NEXT_SONG:
  306.          case UI_PREVIOUS_SONG:
  307.             discard_buffer();
  308.             pres[0].type = result->type;
  309.             pres[0].data = result->data;
  310.             return pres;
  311.          case UI_QUIT:
  312.             discard_buffer();
  313.             end_all(0);
  314.             /* NOTREACHED */
  315.          case UI_SET_BPM:
  316.             tempo = result->data.scalar;
  317.             adjust_sync(frequency, tempo);
  318.             break;
  319.          case UI_RESTART:
  320.             discard_buffer();
  321.             init_automaton(&a, song, start);
  322.             release_audio_channels();
  323.             for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  324.                init_channel(chan + channel);
  325.             break;
  326.          case UI_JUMP_TO_PATTERN:
  327.             if (result->data.scalar >= 0 && result->data.scalar < a.info->length)
  328.                {
  329.                discard_buffer();
  330.                init_automaton(&a, song, result->data.scalar);
  331.                }
  332.             break;
  333.             /*
  334.          case ' ':
  335.             while (may_getchar() == EOF)
  336.                ;
  337.             break;
  338.              */
  339.          default:
  340.             break;
  341.             }
  342.          result++;
  343.          }
  344.  
  345.       {
  346.       int new_freq;
  347.       if (new_freq = update_frequency())
  348.          {
  349.          frequency = new_freq;
  350.          adjust_sync(frequency, tempo);
  351.          init_tables(oversample, frequency);
  352.          }
  353.       }
  354.  
  355.       switch(error)
  356.          {
  357.       case NONE:
  358.          break;
  359.       case ENDED:
  360.          countdown--;
  361.          break;
  362.       case SAMPLE_FAULT:
  363.       case FAULT:
  364.       case PREVIOUS_SONG:
  365.       case NEXT_SONG:
  366.       case UNRECOVERABLE:
  367.          if ( (error == SAMPLE_FAULT && get_pref_scalar(PREF_TOLERATE))
  368.             ||(error == FAULT && get_pref_scalar(PREF_TOLERATE) > 1) )
  369.             break;
  370.          pres[0].type = PLAY_ERROR;
  371.          pres[0].data.scalar = error;
  372.          return pres;
  373.       default:
  374.          break;
  375.          }
  376.          error = NONE;
  377.       }
  378.    pres[0].type = TAG_IGNORE;      
  379.    return pres;
  380.    }
  381.  
  382.