
/*
*	gmod.c	- Module player for GUS and Linux.
*		(C) Hannu Savolainen, 1993
*
*	NOTE!	This program doesn't try to be a complete module player.
*		It's just a too I used while developing the driver. In
*		addition it can be used as an example on programming
*		the VoxWare Sound Driver with GUS.
*/

/*
* Many modifications have been done by Andrew J. Robinson.
* Refer to the ChangeLog for details.
*/


#include "defines.h"
#include "structs.h"
#include "globals.h"

void
set_speed (int parm)
{
  if (!parm)
    parm = 1;

  if (parm < 32)
    ticks_per_division = parm;
  else
    tick_duration = (250.0 / parm);
}

void
set_volslide (int channel, struct note_info *pat)
{
  int n;

  voices[channel].volslide = 0;

  if ((n = ((pat->parm1 & 0xf0) >> 4)))
    voices[channel].volslide = VOL_SLIDE_RATE * n;
  else
    voices[channel].volslide = -(VOL_SLIDE_RATE * (pat->parm1 & 0xf));
}

void
set_slideto (int channel, struct note_info *pat)
{
  int size, rate, note, curr_note;

  note = pat->note;

  if (pat->parm1 != 0)
    {
      rate = pat->parm1;
      if (rate == 0)
	rate = 1;
      voices[channel].last_rate = rate;
    }
  else
    rate = voices[channel].last_rate;

  if (note == 0)
    {
      if (voices[channel].slide_rate > 0)
	{
	  voices[channel].slide_pitch = 1;
	  voices[channel].slide_rate = rate;
	}
      else if (voices[channel].slide_rate < 0)
	{
	  voices[channel].slide_pitch = 1;
	  voices[channel].slide_rate = -rate;
	}
      return;
    }

  curr_note = voices[channel].note * 100 + voices[channel].pitchbender;

  size = (note * 100) - curr_note;

  if (!size)
    return;

  if (size < 0)
    rate = -rate;

  voices[channel].slide_goal = voices[channel].pitchbender + size;
  voices[channel].slide_rate = rate;
  voices[channel].slide_period_goal = period_table[note - NOTE_BASE];
}

void
set_arpeg (int channel, int amount)
{
  voices[channel].arpeg_num = 3;
  voices[channel].arpeg_note[0] = 0;
  voices[channel].arpeg_curr = 0;
  voices[channel].arpeg_note[1] = (amount >> 4) * 100;
  voices[channel].arpeg_note[2] = (amount & 0x0f) * 100;
}

void
set_vibrato (int channel, int amount)
{
  int depth;

  voices[channel].vibra_rate = (amount & 0xf0) >> 4;

  if (voices[channel].vibra_rate == 0)
    voices[channel].vibra_rate = voices[channel].vibra_old_rate;
  else
    voices[channel].vibra_old_rate = voices[channel].vibra_rate;

  depth = (amount & 0x0f);

  if (depth != 0)
    voices[channel].vibra_depth = depth;
}

void
set_tremolo (int channel, int amount)
{
  int depth;

  voices[channel].tremolo = (amount & 0xf0) >> 4;

  if (voices[channel].tremolo == 0)
    voices[channel].tremolo = voices[channel].tremolo_old;
  else
    voices[channel].tremolo_old = voices[channel].tremolo;

  depth = (amount & 0x0f);

  if (depth != 0)
    voices[channel].tremolo_depth = depth;
}
