home *** CD-ROM | disk | FTP | other *** search
/ Inside Multimedia 1995 August / IMM0895.ISO01.iso / share / os2 / track061 / commands.c < prev    next >
C/C++ Source or Header  |  1992-10-27  |  9KB  |  358 lines

  1. /* commands.c */
  2.  
  3. /* modified by David Nichols for OS/2 PM MOD player */
  4.  
  5. /* $Author: espie $
  6.  * $Id: commands.c,v 2.4 1991/12/03 13:23:10 espie Exp espie $
  7.  * $Revision: 2.4 $
  8.  * $Log: commands.c,v $
  9.  * Revision 2.4  1991/12/03  13:23:10  espie
  10.  * Defensive programming: check the range of each note
  11.  * for arpeggio setup.
  12.  *
  13.  * Revision 2.3  1991/11/19  16:07:19  espie
  14.  * Added comments, moved minor stuff around.
  15.  *
  16.  * Revision 2.2  1991/11/18  01:12:31  espie
  17.  * Minor changes.
  18.  *
  19.  * Revision 2.1  1991/11/17  23:07:58  espie
  20.  * Used some constants.
  21.  *
  22.  * Revision 2.0  1991/11/17  21:42:08  espie
  23.  * Structured part of the code, especially replay ``automaton''
  24.  * and setting up of effects.
  25.  *
  26.  * Revision 1.9  1991/11/17  17:09:53  espie
  27.  * Added missing prototypes.
  28.  *
  29.  * Revision 1.8  1991/11/16  15:42:43  espie
  30.  * tabs.
  31.  *
  32.  * Revision 1.7  1991/11/08  14:25:55  espie
  33.  * Dynamic oversample and frequency.
  34.  *
  35.  * Revision 1.6  1991/11/07  21:40:16  espie
  36.  * Added arpeggio.
  37.  *
  38.  * Revision 1.5  1991/11/07  20:12:34  espie
  39.  * Minor problem with version id.
  40.  *
  41.  * Revision 1.4  1991/11/07  20:11:10  espie
  42.  * Added embedded version id.
  43.  *
  44.  * Revision 1.3  1991/11/07  20:05:53  espie
  45.  * Fixed up vibrato depth.
  46.  * Added vibslide and portaslide.
  47.  *
  48.  * Revision 1.2  1991/11/07  15:27:02  espie
  49.  * Added command 9.
  50.  *
  51.  * Revision 1.1  1991/11/06  09:46:06  espie
  52.  * Initial revision
  53.  *
  54.  *
  55.  */
  56.  
  57. #include <stdio.h>
  58. #include "defs.h"
  59.  
  60. /* sine table for the vibrato effect (could be much more precise) */
  61.  
  62. int vibrato_table[32] =
  63. {0, 25, 49, 71, 90, 106, 117, 125, 127, 125, 117, 106, 90,
  64.  71, 49, 25, 0, -25, -49, -71, -90, -106, -117, -125, -127, -125,
  65.  -117, -106, -90, -71, -49, -25};
  66.  
  67. /***
  68.  *
  69.  *
  70.  *  setting up effects/doing effects.
  71.  *  The set_xxx gets called while parsing the effect,
  72.  *  the do_xxx gets called each tick, and update the
  73.  *  sound parameters while playing it.
  74.  *
  75.  *
  76.  ***/
  77.  
  78. void do_nothing (struct channel *ch)
  79. {
  80. }
  81.  
  82. void set_nothing (struct automaton *a, struct channel *ch)
  83. {
  84. }
  85.  
  86. /* slide pitch (up or down) */
  87.  
  88. void do_slide (struct channel *ch)
  89. {
  90.   ch->pitch += ch->slide;
  91.   ch->pitch = MIN (ch->pitch, MAX_PITCH);
  92.   ch->pitch = MAX (ch->pitch, MIN_PITCH);
  93.   set_current_pitch (ch, ch->pitch);
  94. }
  95.  
  96. void set_upslide (struct automaton *a, struct channel *ch)
  97. {
  98.   ch->adjust = do_slide;
  99.   if (a->para)
  100.     ch->slide = a->para;
  101. }
  102.  
  103. void set_downslide (struct automaton *a, struct channel *ch)
  104. {
  105.   ch->adjust = do_slide;
  106.   if (a->para)
  107.     ch->slide = -a->para;
  108. }
  109.  
  110. /* modulating the pitch with vibrato */
  111.  
  112. void do_vibrato (struct channel *ch)
  113. {
  114.   int offset;
  115.  
  116.   /* this is a literal transcription of the protracker
  117.    * code. I should rescale the vibrato table at some point
  118.    */
  119.   ch->viboffset += ch->vibrate;
  120.   ch->viboffset %= 64;
  121.   offset = (vibrato_table[ch->viboffset >> 1] * ch->vibdepth) / 64;
  122.   /* temporary update of only the step value,
  123.    * note that we do not change the saved pitch.
  124.    */
  125.   set_current_pitch (ch, ch->pitch + offset);
  126. }
  127.  
  128. void set_vibrato (struct automaton *a, struct channel *ch)
  129. {
  130.   ch->adjust = do_vibrato;
  131.   if (a->para)
  132.     {
  133.       ch->vibrate = HI (a->para);
  134.       ch->vibdepth = LOW (a->para);
  135.     }
  136. }
  137.  
  138. /* arpeggio looks a bit like chords: we alternate between two
  139.  * or three notes very fast.
  140.  * Issue: we are able to re-generate real chords. Would that be
  141.  * better ? To try.
  142.  */
  143. void do_arpeggio (struct channel *ch)
  144. {
  145.   if (++ch->arpindex >= MAX_ARP)
  146.     ch->arpindex = 0;
  147.   set_current_pitch (ch, ch->arp[ch->arpindex]);
  148. }
  149.  
  150. void set_arpeggio (struct automaton *a, struct channel *ch)
  151. {
  152.   /* normal play is arpeggio with 0/0 */
  153.   if (!a->para)
  154.     return;
  155.   /* arpeggio can be installed relative to the
  156.    * previous note, so we have to check that there
  157.    * actually is a current(previous) note
  158.    */
  159.   if (ch->note == NO_NOTE)
  160.     {
  161.        trackerror(2, "No note present for arpeggio", NONFATAL_ERROR);
  162.       error = FAULT;
  163.     }
  164.   else
  165.     {
  166.       int note;
  167.  
  168.       ch->arp[0] = pitch_table[ch->note];
  169.       note = ch->note + HI (a->para);
  170.       if (note < NUMBER_NOTES)
  171.     ch->arp[1] = pitch_table[note];
  172.       else
  173.     {
  174.        trackerror(3, "Arpeggio note out of range", NONFATAL_ERROR);
  175.       error = FAULT;
  176.     }
  177.       note = ch->note + LOW (a->para);
  178.       if (note < NUMBER_NOTES)
  179.     ch->arp[2] = pitch_table[note];
  180.       else
  181.     {
  182.        trackerror(4, "Arpeggio note out of range", NONFATAL_ERROR);
  183.       error = FAULT;
  184.     }
  185.       ch->arpindex = 0;
  186.       ch->adjust = do_arpeggio;
  187.     }
  188. }
  189.  
  190. /* volume slide. Mostly used to simulate waveform control.
  191.  * (attack/decay/sustain).
  192.  */
  193. void do_slidevol (struct channel *ch)
  194. {
  195.   ch->volume += ch->volumerate;
  196.   ch->volume = MIN (ch->volume, MAX_VOLUME);
  197.   ch->volume = MAX (ch->volume, MIN_VOLUME);
  198. }
  199.  
  200. /* note that volumeslide does not have a ``take default''
  201.  * behavior. If para is 0, this is truly a 0 volumeslide.
  202.  * Issue: is the test really necessary ? Can't we do
  203.  * a HI(para) - LOW(para).
  204.  */
  205. void parse_slidevol (struct channel *ch, int para)
  206. {
  207.   if (LOW (para))
  208.     ch->volumerate = -LOW (para);
  209.   else
  210.     ch->volumerate = HI (para);
  211. }
  212.  
  213. void set_slidevol (struct automaton *a, struct channel *ch)
  214. {
  215.   ch->adjust = do_slidevol;
  216.   parse_slidevol (ch, a->para);
  217. }
  218.  
  219. /* portamento: gets from a given pitch to another.
  220.  * We can simplify the routine by cutting it in
  221.  * a pitch up and pitch down part while setting up
  222.  * the effect.
  223.  */
  224. void do_portamento (struct channel *ch)
  225. {
  226.   if (ch->pitch < ch->pitchgoal)
  227.     {
  228.       ch->pitch += ch->pitchrate;
  229.       ch->pitch = MIN (ch->pitch, ch->pitchgoal);
  230.     }
  231.   else if (ch->pitch > ch->pitchgoal)
  232.     {
  233.       ch->pitch -= ch->pitchrate;
  234.       ch->pitch = MAX (ch->pitch, ch->pitchgoal);
  235.     }
  236.   set_current_pitch (ch, ch->pitch);
  237. }
  238.  
  239. /* if para and pitch are 0, this is obviously a continuation
  240.  * of the previous portamento.
  241.  */
  242. void set_portamento (struct automaton *a, struct channel *ch)
  243. {
  244.   ch->adjust = do_portamento;
  245.   if (a->para)
  246.     ch->pitchrate = a->para;
  247.   if (a->pitch)
  248.     ch->pitchgoal = a->pitch;
  249. }
  250.  
  251. /*
  252.  * combined commands.
  253.  */
  254.  
  255. void do_portaslide (struct channel *ch)
  256. {
  257.   do_portamento (ch);
  258.   do_slidevol (ch);
  259. }
  260.  
  261. void set_portaslide (struct automaton *a, struct channel *ch)
  262. {
  263.   ch->adjust = do_portaslide;
  264.   parse_slidevol (ch, a->para);
  265. }
  266.  
  267. void do_vibratoslide (struct channel *ch)
  268. {
  269.   do_vibrato (ch);
  270.   do_slidevol (ch);
  271. }
  272.  
  273. void set_vibratoslide (struct automaton *a, struct channel *ch)
  274. {
  275.   ch->adjust = do_vibratoslide;
  276.   parse_slidevol (ch, a->para);
  277. }
  278.  
  279. /***
  280.  *
  281.  *  effects that just need a setup part
  282.  *
  283.  ***/
  284.  
  285. /* IMPORTANT: because of the special nature of
  286.  * the player, we can't process each effect independently,
  287.  * we have to merge effects from the four channel before
  288.  * doing anything about it. For instance, there can be
  289.  * several speed changein the same note,
  290.  * only the last one takes effect.
  291.  */
  292.  
  293. void set_speed (struct automaton *a, struct channel *ch)
  294. {
  295.   a->new_speed = a->para;
  296.   a->do_stuff |= SET_SPEED;
  297. }
  298.  
  299. void set_skip (struct automaton *a, struct channel *ch)
  300. {
  301.   /* yep, this is BCD. */
  302.   a->new_note = HI (a->para) * 10 + LOW (a->para);
  303.   a->do_stuff |= SET_SKIP;
  304. }
  305.  
  306. void set_fastskip (struct automaton *a, struct channel *ch)
  307. {
  308.   a->new_pattern = a->para;
  309.   a->do_stuff |= SET_FASTSKIP;
  310. }
  311.  
  312. /* immediate effect: starts the sample somewhere
  313.  * off the start.
  314.  */
  315. void set_offset (struct automaton *a, struct channel *ch)
  316. {
  317.   ch->pointer = int_to_fix (a->para * 256);
  318. }
  319.  
  320. /* change the volume of the current channel.
  321.  * Is effective until there is a new set_volume,
  322.  * slide_volume, or an instrument is reloaded
  323.  * explicitly by giving its number. Obviously, if
  324.  * you load an instrument and do a set_volume in the
  325.  * same note, the set_volume will take precedence.
  326.  */
  327. void set_volume (struct automaton *a, struct channel *ch)
  328. {
  329.   ch->volume = a->para;
  330. }
  331.  
  332. /* Initialize the whole effect table */
  333.  
  334. void init_effects (void (**table) (/* ??? */))
  335. {
  336.   table[0] = set_arpeggio;
  337.   table[15] = set_speed;
  338.   table[13] = set_skip;
  339.   table[11] = set_fastskip;
  340.   table[12] = set_volume;
  341.   table[10] = set_slidevol;
  342.   table[9] = set_offset;
  343.   table[3] = set_portamento;
  344.   table[5] = set_portaslide;
  345.   table[2] = set_upslide;
  346.   table[1] = set_downslide;
  347.   table[4] = set_vibrato;
  348.   table[6] = set_vibratoslide;
  349.   table[14] = set_nothing;
  350.   table[7] = set_nothing;
  351.   table[8] = set_nothing;
  352. }
  353.  
  354.  
  355.  
  356.  
  357.  
  358.