//////////////////////////////////////////////////////////////////////
//
// File:        Player.h
// Author:      Brian Postma
// Created:     30 December 1999
//
// Purpose:     The actual replayer, this part is OS/Hardware
//              independent.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PLAYER_H__B5B25169_B20B_11D3_BEB9_00104B26B3E4__INCLUDED_)
#define AFX_PLAYER_H__B5B25169_B20B_11D3_BEB9_00104B26B3E4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "bstypes.h"
#include "Module.h"
#include "LSoundPlayer.h"

#define DSBPAN_LEFT -1
#define DSBPAN_RIGHT 1

#define CALCVOLUME(x,y) BYTE((WORD(x)*WORD(y))>>8)
#define GETFREQ(x) bpper[char(x)+36-1]

struct BPCURRENT
{
	BYTE		note;
	BYTE		instrument;
	WORD		period;
	BYTE		option;
	BYTE		optiondata;
	BYTE		autoslide;
	BYTE		autoarpeggio;
	BYTE		vibrato;
	BYTE		volume;
	WORD		adsrptr;
	WORD		egptr;
	WORD		modptr;
	WORD		lfoptr;
	BYTE		adsrcount;
	BYTE		egcount;
	BYTE		modcount;
	BYTE		lfocount;
	BYTE		fxcount;
	BYTE		adsrcontrol;
	BYTE		lfocontrol;
	BYTE		egcontrol;
	BYTE		modcontrol;
	BYTE		fxcontrol;
	bool		restart;
	bool		newnote;
};

class Player
{
public:
	Player(Module *modptr, bool stereo=true);
	virtual ~Player();
	BS_ERROR Start();
	BS_ERROR Stop();
	void Run();
	void SetStep(int step);
	void DecStep();
	void IncStep();

	Module *GetModule()
	{
		return modptr;
	}
	inline WORD PerToFreq(WORD per)
	{
		if (per!=0)
			return PERTOFREQCONST/per;
		else
			return 0;
	}
        inline void Mix()
        {
          soundplayer->Mix();
        }
        inline int GetStep()
        {
          return stepptr;
        }

private:
	void BpPlay();
	void BpNext();
	void BpFx();
	void BpProcess();
	void BpArpeggio(short voice, BYTE arpeggio);
	void BpAutoSlide(short voice, BYTE slide);
	void BpVibrato(short voice);
	void BpSynthFx(short voice);
	void BpAveraging(short voice);
	void BpTransform(short voice, BYTE table, BYTE delta, bool invert);
	void BpBackInversion(short voice, BYTE delta);
	void BpTransform(short voice, BYTE table, BYTE delta);

	Module				*modptr;
	LSoundPlayer			*soundplayer;

	int				patptr;
	int				stepptr;
	int				nextstep;
	short				speed;
	short				count;
	short				arpptr;
	short				vibrptr;
	BPCURRENT			bpcurrent[VOICES];
	BYTE				synthbuf[VOICES*SYNTHFXSIZE];
	bool				stereo;

	static short			bpper[256];
	static short			vibtable[8];
};

#endif // !defined(AFX_PLAYER_H__B5B25169_B20B_11D3_BEB9_00104B26B3E4__INCLUDED_)