// -*-C++-*-
// This file is part of the gmod package
// Copyright (C) 1997 by Andrew J. Robinson

#include <stdlib.h>
#include <sys/ultrasound.h>

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

#include "defines.h"
#include "Sample.h"
#include "VoiceGUS.h"

void syncTime();

void
VoiceGUS::doUpdates(int dev)
{
  SEQ_DECLAREBUF();

  if (!delayCount_)
    {
      if (whatChanged_ & (SAMPLE_CHANGED | PAN_CHANGED | OFFSET_CHANGED |
			  KEY_CHANGED))
	syncTime();

      if (whatChanged_ & SAMPLE_CHANGED)
	SEQ_SET_PATCH(dev, channel_, sample_->number());

      if (whatChanged_ & PAN_CHANGED)
	{
	  int panVal;
	  
	  panVal = pan_ + (envelopePan_ - 32) * (128 - abs(128 - pan_)) / 32;
	  
	  if (panVal > 255)
	    panVal = 255;
	  else if (panVal < 0)
	    panVal = 0;
	  
	  if (panFactor_ != 100)
	    {
	      panVal -= 128;
	      panVal = (panVal * panFactor_) / 100;
	      panVal += 128;
	    }

	  SEQ_CONTROL(dev, channel_, CTL_PAN, panVal); 

	  if (!(whatChanged_ & NOTE_CHANGED))
	    {
	      panVal = ((panVal * 2) - 240) / 32 + 7;
	      GUS_VOICEBALA(dev, channel_, panVal);
	    }
	}

      if (whatChanged_ & NOTE_CHANGED)
	startNote(dev, note_);
      else if (whatChanged_ & VOL_CHANGED)
	startNote(dev, 255);

      if (whatChanged_ & BEND_CHANGED)
	{
	  int bend = pitchbender_ + vibraBend_ + arpegBend_ + finetune_;

	  if (bend != lastBend_)
	    {
	      lastBend_ = bend;
	      syncTime();
	      SEQ_BENDER(dev, channel_, bend + 8192);
	    }
	}

      if (whatChanged_ & OFFSET_CHANGED)
	{
	  // restart note to prevent click
	  if (!(whatChanged_ & NOTE_CHANGED))
	      startNote(dev, note_);

	  GUS_VOICE_POS(dev, channel_, offset_);
	}

      if (whatChanged_ & KEY_CHANGED)
	  GUS_VOICEOFF(dev, channel_);
      
      whatChanged_ = 0;
    }
}
